一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情
接下来继续总结Vue3的Composition API的剩余内容。
computed计算属性
具体使用如下demo:通过点击div标签,count值发生改变。而computed监听到count发生改变后,会执行我们想让他做的业务。
<script>
const app = Vue.createApp({
template:`
<div @click="handle">{{count}}---{{countAdd3}} </div>
`,
setup(props,context){
const {ref,computed} = Vue;
const handle=()=>{
count.value+=1;
}
const countAdd3=computed(()=>{
return count.value+=3;
})
/*也可以使用以下写法:
const countAdd3=computed(()=>{
get:()=>{
return count.value+=3;
},
set:()=>{
count.value=10;
}
})
*/
return {
count,handle,countAdd3
}
}
});
const vm = app.mount("#root");
</script>
watch侦听器/watchEffect
-
watch侦听器
具备一定的惰性(可通过属性immediate设置为true设置为可立即执行)
其参数可以拿到当前和原始值。
也可以侦听多个数据的变化,用一个侦听器去完成。
watch([()=>name,()=>age],([newName,oldName],[newAge,oldAge])=>{ console.log(newName,oldName,'---',newAge,oldAge) }
-
watchEffect
立即执行,没有惰性的(immediate)
不需要传递你要侦听的内容,自动会感知代码依赖,不需要传递很多参数,只需要一个回调函数。
但是不像watch,watchEffect无法获取到原始值。
以上两个属性均可停止侦听,如下设置四秒后停止侦听。
const stop = watchEffect(()=>{
console.log(name);
setimeout(()=>{
stop();},4000)
})
watch也如上。
具体关于watch和watchEffect使用如下demo:通过input标签改变name的值,则可以监听到name的值发生了改变。
<script>
const app = Vue.createApp({
template:`
<input v-model='name'/>
<div>{{name}}</div>
`,
setup(props,context){
const {ref,watch} = Vue;
const name = ref("vivi")
watch(name,(newValue,oldValue))=>{
console.log(newValue,oldValue)
}
watchEffect(()=>{
console.log(name);
})
return {
name
}
}
});
const vm = app.mount("#root");
</script>
生命周期新写法
因为setup执行介于beforeCreate和create之间,所以不需要用到这两个生命周期函数
其他的,在setup中使用生命周期,需要改写如下
beforeMount ===> onBeforeMount
mounted ===> onMounted
beforeUpdate ===>onBeforeUpdate
updated ===> onUpdated
beforeUnmount ===>onBeforeUnmount
unmounted ===> onUnmounted
同时还提供了onRenderTracked,onRenderTriggered
- onRenderTracked:每次渲染后重新收集响应式依赖
- onRenderTriggered:每次触发页面重新渲染的时候自动执行
<script>
const app = Vue.createApp({
template:`
<div>{{name}}</div>
`,
setup(props,context){
const {ref,onMounted} = Vue;
const name = ref("vivi")
onMounted(()=>{
console.log('onMounted');
})
return {
name
}
}
});
const vm = app.mount("#root");
</script>
Provide,inject
在父组件中使用provide将属性或者方法传递给子组件,子组件使用inject接收。
如下demo:父组件的name可以通过ref设置响应式,然后传递给子组件,子组件如果想要修改父组件的name,有些人会直接使用name.value="小新"去更改,但这样违反了vue的单向传递原则,子组件最好不要去改变父组件的值,于是建议可以给name变量加上一个readonly属性,一旦有人直接更改,则会报错。最优的做法是触发父组件的changeName方法去改变name的值。
<script>
const app = Vue.createApp({
setup(){
const {provide,ref,readonly} = Vue;
const name = ref("vivi");
provide("name":readonly(name));
provide("changeName",(value)=>{
name.value=value;
})
return {}
},
template:`
<child />
`
});
app.component("child",{
setup(){
const {inject} = Vue;
const name = inject("name");
const changeName = inject("changeName");
const handle(()=>{
//name.value="小新";
changeName("小新");
})
return {name}
},
template:`<div @click="handle">{{name}}</div>`
})
const vm = app.mount("#root");
</script>
模板Ref的使用
Composition API提供的获取真实DOM节点的ref方法。
<script>
const app = Vue.createApp({
template:`
<div ref="hello">{{name}}</div>
`,
setup(props,context){
const {ref,onMounted} = Vue;
const hello = ref(null)
onMounted(()=>{
console.log(hello.value);//可以获取到hello真实的dom节点
})
return {
hello
}
}
});
const vm = app.mount("#root");
</script>
\