vue3升级概览

it2023-09-01  64

都来自于官网的的升级文档,官网文档点击我

异步组件

1, overview

2.x(before) // simple const asyncPage = () => import('./NextPage.vue') //advanced const asyncPage = { component: () => import('./NextPage.vue'), delay: 200, timeout: 3000, error: ErrorComponent, loading: LoadingComponent } 3.x(after) import { defineAsyncComponent } from 'vue' import ErrorComponent from './components/ErrorComponent.vue' import LoadingComponent from './components/LoadingComponent.vue' // // simple ---- Async component without options const asyncPage = defineAsyncComponent(() => import('./NextPage.vue')) // //advanced ---- Async component with options const asyncPageWithOptions = defineAsyncComponent({ loader: () => import('./NextPage.vue'), // 注意这里是loader,不是component关键字 delay: 200, timeout: 3000, errorComponent: ErrorComponent, loadingComponent: LoadingComponent })

2 loader function change

2.x(before) const oldAsyncComponent = (resolve, reject) => { /* ... */ } 3.x(after) const asyncComponent = defineAsyncComponent( () => new Promise((resolve, reject) => { /* ... */ }) )

指令的变化

指令的变化主要是API名字的变动,新的API指令名字类似于组件的生命周期

- 表示没有该API 2.x(before)3.x(after)bindbeforeMountinsertedmounted-beforeUpdateupdate-componentUpdatedupdatedunbindunmounted

最终的API长这样:

const MyDirective = { beforeMount(el, binding, vnode, prevVnode) {}, mounted() {}, beforeUpdate() {}, updated() {}, beforeUnmount() {}, // new unmounted() {} } 2.x(before) <p v-highlight="yellow">Highlight this text bright yellow</p> Vue.directive('highlight', { bind(el, binding, vnode) { el.style.background = binding.value } }) 3.x(after) <p v-highlight="yellow">Highlight this text bright yellow</p> const app = Vue.createApp({}) app.directive('highlight', { beforeMount(el, binding, vnode) { el.style.background = binding.value } })

EVENT变化

在3.x版本中:移除了 $on, $off, $once这3个方法。保留了$emit,保留这个方法是为了触发父组件里面的event handler。

所以2.x中的非父子组件的数据交换以及事件触发,就不能通过$onor$off来实现了。实际上我们可以自己实现一个EventHub 【通过发布订阅模式】

不过已经有第三方库实现了mitt 和 tiny-emitter

Filter

3.x 不再支持filter,可以用method 或者 computed来代替。

Fragments

2.x 模板不支持多root节点,3.x支持多root节点

2.x(before) <!-- Layout.vue --> <template> <div> <!--有且只有一个root节点--> <header>...</header> <main>...</main> <footer>...</footer> </div> </template> 3.x(after) <!-- Layout.vue --> <template> <!--template里面可以有多个root节点--> <header>...</header> <main v-bind="$attrs">...</main> <footer>...</footer> </template>

Global API tree-shaking

前景: 2.x里面我们操作dom的时候,是这样操作的。

import Vue from 'vue' Vue.nextTick(()=>{ //Something Dom-related })

由于2.x代码中nextTick的实现方式的原因,造成了诸如webpack等打包工具打包的时候,tree-shaking是不能移除这一块无用的代码的,比如我们是这样写的Vue.nextTick(),最后仍然会在build文件里面。

3.x 部分全局API被重写,已经能够支持tree-shaking。而且这些全局API只能通过ES module的具名引用形式获取到。 像这样:

import { nextTick } from 'vue' nextTick(() => { // something DOM-related })

2.x中被影响的全局API

- Vue.nextTick - Vue.observable (replaced by Vue.reactive) - Vue.version - Vue.compile (only in full builds) - Vue.set (only in compat builds) - Vue.delete (only in compat builds)

除了一些全局的Global API,一些内部组件/帮助方法也能够以具名形式导出。 好处就是,只有被使用了,最后编译的时候才能够打包输出。有使用到才被打包。

v-model 的改变 [非常重要,在自定义组件的时候的逻辑修改]

1,自定义组件的时候,v-model的属性和时间的名字修改。

prop: value -> modelValue event: input -> update:modelValue

2,v-binding的.sync修饰器和组件的model选项被移除,现在作为v-model的参数。

3,可以给一个组件绑定多个v-model

4,除了默认的v-model,可以添加用户自定v-model修饰器

2.x(before)

在2.x下,v-model是一个语法糖,等同于value属性和一个input事件。

<ChildComponent v-model="pageTitle" /> <!-- 等同于 --> <ChildComponent :value="pageTitle" @input="pageTitle = $event" />

如果我们想改变属性和事件的名字,不使用默认的 value 和 input,那我们需要在ChildComponent里面添加model选项。

<!-- ParentComponent.vue --> <ChildComponent v-model="pageTitle" /> // ChildComponent.vue export default { model: { prop: 'title', event: 'change' }, props: { // 让value属性发挥其他作用 // this allows using the `value` prop for a different purpose value: String, // 用属性名title代替名字value // use `title` as the prop which take the place of `value` title: { type: String, default: 'Default title' } } }

这样我们不仅能用v-model的形式,也能用语法糖来表示,但是可以用我们的命名来。

<ChildComponent v-model="pageTitle" /> <!-- 等同于 --> <ChildComponent :title="pageTitle" @change="pageTitle = $event" />

关于.sync,在2.x中,有一定的情况下,需要属性值也双向绑定,子组件可以修改父组件传递下来的属性值。

父组件引用子组件的代码:

<ChildComponent :title.sync="pageTitle" /> <!--等同于--> <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

子组件修改属性值的代码:

this.$emit('update:title', newValue) 3.x(after)

在3.x下,在自定义组件上的v-model 等同于 modalValue属性和update:modalValue事件

prop:value -> modelValue

event: input -> update:modelValue

<ChildComponent v-model="pageTitle" /> <!-- would be shorthand for: --> <ChildComponent :modelValue="pageTitle" @update:modelValue="pageTitle = $event" />

v-model参数(.sync的改进)

现在移除了组件里面的model option, 代替它的是在v-model上传递一个参数

<ChildComponent v-model:title="pageTitle" /> <!-- 等同于: --> <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

也就是说以前.sync的方式这样修改:

<!--2.x--> <ChildComponent :title.sync="pageTitle" /> <!--3.x--> <ChildComponent v-model:title="pageTitle" />

v-model可以自定义修饰器

2.x只有一些默认的修饰器,比如.trim, 3.x支持自定义修饰器了

最新回复(0)