Vue 不支持 IE8 以及更低版本浏览器
是因为当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data
选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty
把这些属性全部转为 getter/setter。Object.defineProperty
是 ES5 中一个无法 shim 的特性。
建议安装 vue-devtools
来获取对检查数据更加友好的用户界面
是因为不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同。
在属性被访问和修改时通知变更 getter/setter。
watcher
使它关联的组件重新渲染
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
属性必须在 data
对象上存在
才能让 Vue 将它转换为响应式的
受现代 JavaScript 的限制 (而且 Object.observe
也已经被废弃),Vue 无法检测到对象属性的添加或删除。你必须在初始化实例前声明所有根级响应式属性,哪怕只是一个空值。
Vue.set(object, propertyName, value)
向嵌套对象添加响应式属性
Vue.set(vm.someObject, 'b', 2)
//vm.$set 实例方法
this.$set(this.someObject,'b',2)
//Object.assign 创建一个新的对象
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
//数组修改
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.items.splice(newLength)
Vue 在更新 DOM 时是异步执行的
在缓冲时去除重复数据避免不必要的计算和 DOM 操作
要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。
Vue 在内部对异步队列尝试使用原生的 Promise.then
、MutationObserver
和 setImmediate
,如果执行环境不支持,则会采用 setTimeout(fn, 0)
代替。
Vue.nextTick(callback)
回调函数将在 DOM 更新完成后被调用
updateMessage: function () {
this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '已更新'
})
}
$nextTick()
返回一个 Promise
对象,可以使用 ES2017 async/await 语法
updateMessage: async function () {
this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
await this.$nextTick()
console.log(this.$el.textContent) // => '已更新'
}
key
预期:number | string
key
的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。
而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
它也可以用于强制替换元素/组件而不是重复使用它。如下场景时很有用:
- 完整地触发组件的生命周期钩子
- 触发过渡
例如:
<transition>
<span :key="text">{{ text }}</span>
</transition>
当 text
发生改变时,<span>
总是会被替换而不是被修改,因此会触发过渡。
虚拟 DOM
Vue 通过建立一个虚拟 DOM 来追踪自己要如何改变真实 DOM。请仔细看这行代码:
return createElement('h1', this.blogTitle)
createElement
到底会返回什么呢?其实不是一个实际的 DOM 元素。它更准确的名字可能是 createNodeDescription
,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为“VNode”。
“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。
组件树中的所有 VNode 必须是唯一的。
渲染函数
Vue 的模板实际上被编译成了渲染函数。
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)
},
props: {
level: {
type: Number,
required: true
}
}
})
向组件中传递不带 v-slot
指令的子节点时,比如 anchored-heading
中的 Hello world!
,这些子节点被存储在组件实例中的 $slots.default
中。