都来自于官网的的升级文档,官网文档点击我
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 } })在3.x版本中:移除了 $on, $off, $once这3个方法。保留了$emit,保留这个方法是为了触发父组件里面的event handler。
所以2.x中的非父子组件的数据交换以及事件触发,就不能通过$onor$off来实现了。实际上我们可以自己实现一个EventHub 【通过发布订阅模式】
不过已经有第三方库实现了mitt 和 tiny-emitter
3.x 不再支持filter,可以用method 或者 computed来代替。
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>前景: 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,一些内部组件/帮助方法也能够以具名形式导出。 好处就是,只有被使用了,最后编译的时候才能够打包输出。有使用到才被打包。
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" />2.x只有一些默认的修饰器,比如.trim, 3.x支持自定义修饰器了