初始化
- 创建实例
- 使用 router、vuex 等
1 | // vue2.x |
1 | // vue3.x |
选项式 API && 组合式 API
1 | // vue2.x |
1 | // vue3.x |
props
props 是响应式的1
2
3
4
5
6
7
8
9
10export default {
props: {
title: String
},
setup(props) {
console.log(props.title)
// ES6 的解构会消除 响应式,需要通过 toRefs 解构
const { name } = toRefs(props)
}
}context
普通的 js 对象,非响应式1
2
3
4
5
6// 可以直接 ES6 解构
// setup (props, { attrs, slots, emit, expose }) {
setup (context) {
// $attrs | $slots | $emit 方法 | expose 暴露一个属性,可以被外部访问 如 $refs
const { attrs, slots, emit, expose } = context
}生命周期钩子
1
2
3
4
5
6
7
8
9
10
11
12Vue2---------------vue3
beforeCreate -> setup()
created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
activated -> onActivated
deactivated -> onDeactivated
errorCaptured -> onErrorCaptured
setup: 组件创建之前,在 beforeCreate 和 created 之前执行,创建 data 和 methods
onBeforeMount: 组件挂载到节点上之前执行的函数
onMounted: …
若组件被
包含,则多出下面两个钩子函数 onActivated: 被激活时
onDeactivated: 失活时执行
注意
- 执行 setup 时,只能访问 props/attrs/slots/emit
- 无法访问 data/computed/methods/refs
- setup 中不能使用 this,因为组件实例尚未被创建,this 不指向实例的引用,Vue 将其设置为 undefined
响应式 API
ref && reactive
- vue2.x 的响应式数据 直接在 data 函数中
1
2
3
4
5
6
7export default {
data () {
return {
obj: {}
}
}
} - vue3.x 的响应式数据 在 setup 函数返回
1
2
3
4
5
6
7
8
9
10
11
12import { ref, reactive } from 'vue'
export default {
setup () {
/**
* 封装成 proxy({ value: 'tang' }) 的形式
*/
let name1 = ref('tang')
const nameObj = reactive({ name: 'tang' })
const { name } = toRefs(nameObj)
return { name1, name }
}
}
computed && watch && watchEffect
1 | import { computed, watch, watchEffect } from 'vue' |
toRef
为源响应式对象上的一个 属性 创建一个 ref,它可以被传递,并且会保持对其源响应式对象的属性的 响应式链接
1 | const state = reactive({ name: '111', age: 0 }) |
当你要将 prop 的 ref 传递给复合函数时,toRef 很有用
1 | setup(props) { |
toRefs
将响应式对象转换为普通对象,但其内部的所有属性,指向的是其原始对象的属性的 ref (其内部属性还是响应式的)
将 proxy 对象proxy({ name: 'tang', age: 12 })
转换成{ name: proxy({ value: 'tang' }), age: proxy({ value: 12 }) }
1 | const state = reactive({ name: '111', age: 0 }) |
其他
响应式原理
Object.defineProperty
=> defineProxy
模板根节点
vue 2.x 的 template 根节点只能一个
1
2
3<template>
<div id="home"></div>
</template>vue 3.x 根节点可以有多个
1
2
3
4<template>
<div id="home"></div>
<div id="docker"></div>
</template>
vue2.x 使用 flow, vue3.x 使用 typescript
对虚拟 DOM 的改进
treeshaking
options API 无法 摇树block
vue2.x 对所有响应式数据 patch 和 diff,vue3.x 将 模板切分为 block(if | slot | for),对于静态节点优化,更新时只遍历动态节点