vue3生命周期
移除了beforeCreate
和 created
这两钩子函数,取而代之 为 setup,setup
为最早执行,在created
以前就执行了,所有内部不能使用 this 来访问 vue 实列
2版本 和 3版本的区别
- beforeCreate -> setup()
- created -> setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
其次在vue3中新增了两个钩子函数#
onRenderTracked
和onRenderTriggered
onRenderTracked
直译过来就是状态跟踪
,它会跟踪页面上所有响应式变量和方法的状态,也就是我们用return
返回去的值,它都会跟踪。只要页面有update
的情况,它就会跟踪,然后生成一个event
对象,我们通过event
对象来查找程序的问题所在。
onRenderTriggered
直译过来是状态触发
,它不会跟踪每一个值,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来。
如果把onRenderTracked
比喻成散弹枪,每个值都进行跟踪,那onRenderTriggered
就是狙击枪,只精确跟踪发生变化的值,进行针对性调试。
vue3中ref 和 reactive 的理解
ref和reactive一样,都是用来实现响应式数据的方法
ref处理普通类型数据,reactive处理对象,数组类型数据。
Vue3中是通过Proxy来处理数据触发响应式的,但是Proxy不能处理普通类型的数据,ref底层就是就是将普通数据转换成 “value:” 这种对象的形式,然后交给Proxy再去做转换。
如果碰到时间类型的数据,那么reactive必须重新赋值,才能起作用。直接修改,是没效果的。例如:
<template>
<div>
<p>{{msg.date}}</p>
<button @click="c">button</button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
name: 'App',
setup() {
let msg = reactive({
date: new Date()
});
function c() {
console.log(msg);
msg.date.setDate((msg.date.getDate() + 1)); //这一步达不到数据,视图都更新
msg.date = new Date(msg.date); //必须再重新赋值一次
console.log(msg);
}
return {
msg,
c
};
}
}
创建了一个reactive对象,在template中是要用 xxx.zzz 方式使用,如果要使用解构赋值的方式展示,那就必须使用 toRefs() 包裹起来转换
readonly 表示只读,不能修改
let title = readonly('张三')
setup()函数的两个参数props,context
props是一个对象,包含父组件传递给子组件的所有数据。
context
参数是一个普通的javascript对象,它对组件暴露三个属性:attrs
、slots
、emit
。
attrs
用途:当父组件传递数据给子组件时,子组件不通过props
接收,那么父组件传递的数据就到了setup
中的context
的attrs
属性。
slots
:用于接收渲染父组件传递的插槽内容。
emit
:向父组件触发事件。
computed 和 watch
computed
计算属性,与vue2.0用法一致
let result = computed(()=>{
return ...
})
watch
监听, name 要监听的值,如果需要监听多个值的话,可以用数组的方式来写
//监听单个值
watch(name,(newvalue,oldvalue)=>{
...
})
//监听多个值
watch([name,age],([newName,newAge],[oldName,oldAge])=>{
...
})
当监听的数据是 reactive 类型的时候 监听他的某个属性 可以是 ()=> 来监听 如:
//单个值监听
watch(()=>info.name,(newvalue,oldvalue)=>{
...
})
//多个值监听
watch([()=>info.name,()=>info.age],([newName,newAge],[oldName,oldAge])=>{
...
})
除了
watch
外,compostition API还提供了watchEffect
这种监听方式
区别:
-
watch
监听有惰性,页面刷新不会立即执行,(设置immediate:true
也可以改变为立即执行),watchEffect
则没有惰性,页面刷新立即执行 -
watch
参数可以拿到原始值,当前值watchEffect
不能获取数据之前的值,不需要传递参数,自动会感知代码依赖.
组件传值
Vue2.0版本 常规的组件传值:子组件props接收一下值, 子组件触发事件,this.attrs
和
$listeners` inheritAttrs属性官方的解释:默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。
实际上可以这样理解, 设置 inheritAttrs: false
这样子组件就不会继承父子件的自定义属性,默认是true,也就是说 默认是继承的。
爷儿孙组件来讲, 要使用 $attrs
和 $listeners
,那么儿组件 就相当于一个中间站,从而连接爷孙的交互
<template>
<div>
<P>我是子组件 ----- {{msg}} </P>
<Sun v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
在vue3中 多层组件嵌套 直接使用 provide
和 inject
来交互
爷组件使用
provide('字段名','字段值')
在孙组件使用接收到,然后记得在 setup 中 return 出去
const xxx = inject('字段名')
这块的inject可以有两个参数,第二个参数是设置默认值的,也就是说如果某个字段没有获取到,那么后面的值就是这个字段的默认值
孙组件像爷组件传值,需要在爷组件中定义一个函数出来,并用 provide 注册下
const fromSun = (val) =>{
console.log('孙子传给我的值====',val);
}
provide('fromSun',fromSun)
同样的 孙组件 用 inject
接收 然后在自己内部定义的事件函数中 使用 inject
接收到的函数来 传递
const fromSun = inject('fromSun')
const add = () =>{
fromSun('传给爷组件的值')
}