vuejs3 第10页
#概览 不兼容:v-bind 的绑定顺序会影响渲染结果。 #介绍 在元素上动态绑定 attribute 时,常见的场景是在一个元素中同时使用 v-bind="object" 语法和单独的 property。然而,这就引出了关于合并的优先级的问题。 #2.x 语法 在 2.x,如果一个元素同时定义了 v-bind="object" 和一个相同的单独的 property,那么这个单独的 property 总是会覆盖 object 中的绑定。 <!-- template --> <div id="red" v-bind="{ id: 'blue' }"></div> <!-- result --> <div id="red"></div> #3.x 语法 在 3.x,如果一个元素同时定义了 v-bind="object" 和一个相同的单独的 property,那么声明绑定的顺序决定了它们如何合并。换句话说,相对于假设开发者总是希望单独的 property 覆盖 object 中定义的内容,现在开发者对自己所希望的合并行为有了更好的控制。 <!-- template --> <div id="red" v-bind="{ id: 'blue' }"></div> <!-- result --> <div id="blue"></div> <!-- template --> <div v-bind="{ id: 'blue' }" id="red"></div> <!-- result --> <div id="red"></div> #迁移策略 如果你依赖 v-bind 的覆盖功能,目前的建议是确保在单独的 property 之前定义 v-bind attribute。
#概览 非兼容:两者作用于同一个元素上时,v-if 会拥有比 v-for 更高的优先级。 #介绍 Vue.js 中使用最多的两个指令就是 v-if 和 v-for,因此开发者们可能会想要同时使用它们。虽然不建议这样做,但有时确实是必须的,于是我们想提供有关其工作方式的指南。 #2.x 语法 2.x 版本中在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用。 #3.x 语法 3.x 版本中 v-if 总是优先于 v-for 生效。 #迁移策略 由于语法上存在歧义,建议避免在同一元素上同时使用两者。 比起在模板层面管理相关逻辑,更好的办法是通过创建计算属性筛选出列表,并以此创建可见元素。
#概览 过渡类名 v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from。 #2.x 语法 在v2.1.8版本之前, 为过渡指令提供了两个过渡类名对应初始和激活状态。 在 v2.1.8 版本中, 引入 v-enter-to 来定义 enter 或 leave 变换之间的过渡动画插帧, 为了向下兼容, 并没有变动 v-enter 类名: .v-enter, .v-leave-to { opacity: 0; } .v-leave, .v-enter-to { opacity: 1; } 这样做会带来很多困惑, 类似 enter 和 leave 含义过于宽泛并且没有遵循类名钩子的命名约定。 #3.x 语法 为了更加明确易读,我们现在将这些初始状态重命名为: .v-enter-from, .v-leave-to { opacity: 0; } .v-leave-from, .v-enter-to { opacity: 1; } 现在,这些状态之间的区别就清晰多了。 <transition> 组件相关属性名也发生了变化: leave-class 已经被重命名为 leave-from-class (在渲染函数或 JSX 中可以写为:leaveFromClass) enter-class 已经被重命名为 enter-from-class (在渲染函数或 JSX 中可以写为:enterFromClass) #迁移策略 将 .v-enter 字符串实例替换为 .v-enter-from 将 .v-leave 字符串实例替换为 .v-leave-from 过渡组件相关属性名也需要进行字符串实例替换,规则如上所述。
#概览 此更改统一了 3.x 中的普通 slot 和作用域 slot。 以下是变化的变更总结: this.$slots 现在将 slots 作为函数公开 非兼容:移除 this.$scopedSlots 更多信息,请继续阅读! #2.x 语法 当使用渲染函数时,即 h,2.x 用于在内容节点上定义 slot data property。 // 2.x 语法 h(LayoutComponent, [ h('div', { slot: 'header' }, this.header), h('div', { slot: 'content' }, this.content) ]) 此外,在引用作用域 slot 时,可以使用以下方法引用它们: // 2.x 语法 this.$scopedSlots.header #3.x 语法 在 3.x 中,插槽被定义为当前节点的子对象: // 3.x Syntax h(LayoutComponent, {}, { header: () => h('div', this.header), content: () => h('div', this.content) }) 当你需要以编程方式引用作用域 slot 时,它们现在被统一到 $slots 选项中。 // 2.x 语法 this.$scopedSlots.header // 3.x 语法 this.$slots.header #迁移策略 大部分更改已经在 2.6 中发布。因此,迁移可以一步到位: 在 3.x 中,将所有 this.$scopedSlots 替换为 this.$slots。
#概览 此更改不会影响 <template> 用户。 以下是更改的简要总结: h 现在全局导入,而不是作为参数传递给渲染函数 渲染函数参数更改为在有状态组件和函数组件之间更加一致 vnode 现在有一个扁平的 prop 结构 更多信息,请继续阅读! #Render 函数参数 #2.x 语法 在 2.x 中,e render 函数将自动接收 h 函数 (它是 createElement 的常规别名) 作为参数: // Vue 2 渲染函数示例 export default { render(h) { return h('div') } } #3.x 语法 在 3.x 中,h 现在是全局导入的,而不是作为参数自动传递。 // Vue 3 渲染函数示例 import { h } from 'vue' export default { render() { return h('div') } } #渲染函数签名更改 #2.x 语法 在 2.x 中,render 函数自动接收诸如 h 之类的参数。 // Vue 2 渲染函数示例 export default { render(h) { return h('div') } } #3.x 语法 在 3.x 中,由于 render 函数不再接收任何参数,它将主要用于 setup() 函数内部。这还有一个好处:可以访问作用域中声明的响应式状态和函数,以及传递给 setup() 的参数。 import { h, reactive } from 'vue' export default { setup(props, { slots, attrs, emit }) { const state = reactive({...
生成 prop 默认值的工厂函数不再能访问 this。 替代方案: 把组件接收到的原始 prop 作为参数传递给默认函数; 注入 API 可以在默认函数中使用。 import { inject } from 'vue' export default { props: { theme: { default (props) { // `props` 是传递给组件的原始值。 // 在任何类型/默认强制转换之前 // 也可以使用 `inject` 来访问注入的 property return inject('theme', 'default-theme') } } } }
该页面仅适用于 Vue 2.x 及更低版本,并假定你已经阅读了响应性部分。请先阅读该部分。 由于 JavaScript 的限制,有些 Vue 无法检测的更改类型。但是,有一些方法可以规避它们以维持响应性。 #对于对象 Vue 无法检测到 property 的添加或删除。由于 Vue 在实例初始化期间执行 getter/setter 转换过程,因此必须在 data 对象中存在一个 property,以便 Vue 对其进行转换并使其具有响应式。例如: var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的 对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object,propertyName,value) 方法向嵌套对象添加响应式 property: Vue.set(vm.someObject, 'b', 2) 你还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名: this.$set(this.someObject, 'b', 2) 有时你可能需要为已有对象赋值多个新 property,比如使用 Object.assign() 或 _.extend()。但是,这样添加到对象上的新 property 不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的 property 一起创建一个新的对象。 // 而不是 `Object.assign(this.someObject, { a: 1, b: 2 })` this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) #对于数组 Vue 不能检测以下数组的变动: 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength 例如: var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' // 不是响应式的 vm.items.length = 2 //...