vue3技术简易入门剖析(二)https://developer.aliyun.com/article/1432713
八、vue3的生命周期
8.1 vue2的生命周期
8.2 vue3生命周期
**注意:**vue2的生命周期写法在vue3中同样可以使用。
vue3生命周期图解:
你可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。
下表包含如何在 setup () 内部调用生命周期钩子:
选项式 API | Hook inside setup |
beforeCreate |
setup() |
created |
setup() |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeUnmount |
onBeforeUnmount |
unmounted |
onUnmounted |
errorCaptured |
onErrorCaptured |
renderTracked |
onRenderTracked |
renderTriggered |
onRenderTriggered |
activated |
onActivated |
deactivated |
onDeactivated |
**注意:**因为 setup
是围绕 beforeCreate
和 created
生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup
函数中编写。
vue3中生命周期钩子的使用方法(组合API形式):
这些函数接受一个回调函数,当钩子被组件调用时将会被执行:
<template> <h1>App.vue组件</h1> <h3>{{age}}</h3><button @click="age+=1">点我</button> </template> <script> //首先导入需要使用生命周期钩子函数 import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue' export default { name: 'App', components: {}, setup(){ let age = ref(18) console.log('================beforeCreate======================') console.log('================created======================') onBeforeMount(()=>{ console.log('================onBeforeMount======================') }) onMounted(()=>{ console.log('================onMounted======================') }) onBeforeUpdate(()=>{ console.log('================onBeforeUpdate======================') }) onUpdated(()=>{ console.log('================onUpdated======================') }) //当组件进行切换时 可以调用卸载钩子函数 onBeforeUnmount(()=>{ console.log('================onBeforeUnmount======================') }) onUnmounted(()=>{ console.log('================onUnmounted======================') }) return {age} } } </script>
九、响应式API的使用
9.1 响应性基础API
9.1.1 reactive 与 shallowReactive
- reactive
**概念:**返回对象的响应式副本
const obj = reactive({ count: 0 })
- 响应式转换是“深层”的——它影响所有嵌套 property。在基于 ES2015 Proxy 的实现中,返回的 proxy 是不等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。
- shallowReactive
**概念:**创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (暴露原始值)。
只处理对象最外层属性的响应式,内层嵌套的数据就不再是响应式数据了。
const state = shallowReactive({ foo: 1, nested: { bar: 2 } }) // 改变 state 本身的性质是响应式的 state.foo++ // ...但是不转换嵌套对象 isReactive(state.nested) // false state.nested.bar++ // 非响应式
9.1.2 readonly 与 shallowReadonly
- readonly
**概念:**接受一个对象 (响应式或纯对象) 或 ref 并返回原始对象的只读代理。只读代理是深层的:任何被访问的嵌套 property 也是只读的。
让一个数据变为只读的,深只读,内部嵌套的数据也是只读的
const original = reactive({ count: 0 }) const copy = readonly(original) watchEffect(() => { // 用于响应性追踪 console.log(copy.count) }) // 变更 original 会触发依赖于副本的侦听器 original.count++ // 变更副本将失败并导致警告 copy.count++ // 警告!
- shallowReadonly
**概念:**创建一个 proxy,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换 (暴露原始值)。
const state = shallowReadonly({ foo: 1, nested: { bar: 2 } }) // 改变 state 本身的 property 将失败 state.foo++ // ...但适用于嵌套对象 isReadonly(state.nested) // false state.nested.bar++ // 适用
- 让一个数据变为只读的,浅层只读,内部嵌套的数据不是只读的
<script> import {reactive,ref,toRef,toRefs,shallowReadonly,readonly} from 'vue' export default{ name:"Father", components:{Son}, setup(){ let fname = ref('父亲') let person = reactive({ name:'张三', age:18, job:{ salary:20 } }) //把person对象重新使用shallowReadonly包括 重新赋值给person person = shallowReadonly(person) return { ...toRefs(person) } } } </script>
9.1.3 isProxy 、isReactive 、isReadonly
import { reactive, isReactive } from 'vue' export default { setup() { const state = reactive({ name: 'John' }) console.log(isReactive(state)) // -> true } }
- isReadonly
**概念:**检查对象是否是由readonly
创建的只读代理
9.1.4 toRaw和markRaw
- toRaw
**概念:**返回reactive
或readonly
代理的原始对象。这是一个“逃生舱”,可用于临时读取数据而无需承担代理访问/跟踪的开销,也可用于写入数据而避免触发更改。不建议保留对原始对象的持久引用。请谨慎使用。
把一个响应式对象转变成普通对象。
const foo = {} const reactiveFoo = reactive(foo) console.log(toRaw(reactiveFoo) === foo) // true
- markRaw
**概念:**标记一个对象,使其永远不会转换为 proxy。返回对象本身。
const foo = markRaw({}) console.log(isReactive(reactive(foo))) // false // 嵌套在其他响应式对象中时也可以使用 const bar = reactive({ foo }) console.log(isReactive(bar.foo)) // false
9.2 refs引用型API
9.2.1 ref 和 unref 和 isRef
- ref
**概念:**接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个.value
property,指向该内部值。
示例:
const count = ref(0) console.log(count.value) // 0 count.value++ console.log(count.value) // 1
- 如果将对象分配为 ref 值,则它将被 reactive 函数处理为深层的响应式对象。
- unref
**概念:**如果参数是一个ref
,则返回内部值,否则返回参数本身。这是val = isRef(val) ? val.value : val
的语法糖函数。 - isRef
**概念:**检查值是否为一个 ref 对象
9.2.2 toRef和toRefs
- toRef
**概念:**可以用来为源响应式对象上的某个 property 新创建一个ref
。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') fooRef.value++ console.log(state.foo) // 2 state.foo++ console.log(fooRef.value) // 3
- 我们可以把对象中的常用数据通过toRef引用出来,这样就不需要再把整个对象向外返回了,写法上会简单些。
export default{ name:"Father", setup(){ let fname = ref('父亲') let person = reactive({ name:'张三', age:18 }) return { name:toRef(person,'name') } } }
- toRef引用响应式对象中的单个数据
- toRefs
**简介:**将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的ref
。
当从组合式函数返回响应式对象时,toRefs
非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行解构/展开:toRefs
引用响应式对象中的多个数据,可以以解构赋值的形式解析响应式对象
export default{ name:"Father", setup(){ let fname = ref('父亲') let person = reactive({ name:'张三', age:18 }) return { ...toRefs(person) } } } 可以直接把整个person对象中所有的数据都变成 toRef形式 使用的时候 直接使用person对象的属性名就可以了。
十、vue3中其余的新增特性
10.1 全局定义----自定义指令,组件,混入,全局挂载。。。。
app.mixin app.use app.directive
全局挂载 app.config.globalProperties.foo = 'bar'
10.2 其它特性
- data必须定义为函数式
- 移除
keycodes.数字
- 移除过滤器
fooRef.value++
console.log(state.foo) // 2
state.foo++
console.log(fooRef.value) // 3
我们可以把对象中的常用数据通过toRef引用出来,这样就不需要再把整个对象向外返回了,写法上会简单些。 ```js export default{ name:"Father", setup(){ let fname = ref('父亲') let person = reactive({ name:'张三', age:18 }) return { name:toRef(person,'name') } } } 我们可以通过toRef把一个响应式对象中的单个数据向外暴漏 并且这个单个数据 不会丢失对person对象的响应性。
- toRef引用响应式对象中的单个数据
- toRefs
**简介:**将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的ref
。
当从组合式函数返回响应式对象时,toRefs
非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行解构/展开:toRefs
引用响应式对象中的多个数据,可以以解构赋值的形式解析响应式对象
export default{ name:"Father", setup(){ let fname = ref('父亲') let person = reactive({ name:'张三', age:18 }) return { ...toRefs(person) } } } 可以直接把整个person对象中所有的数据都变成 toRef形式 使用的时候 直接使用person对象的属性名就可以了。
十、vue3中其余的新增特性
10.1 全局定义----自定义指令,组件,混入,全局挂载。。。。
app.mixin app.use app.directive
全局挂载 app.config.globalProperties.foo = 'bar'
10.2 其它特性
- data必须定义为函数式
- 移除
keycodes.数字
- 移除过滤器
- 。。。。。。更多新特性请自行探索。