7.监听属性:watch函数
使用方法:
1.引入watch:
import {watch} from "vue"
2.使用watch
第一种:监听ref定义的响应式数据
// 让msg这个变量成为一个响应式数据
let msg=ref("karen")
let mn=ref("chongqi")
msg.value="jack"
// 监听msg、mn值的改变
//在vue3.0中可以监听多个数据
// 在vue3.0中监听函数可以写多个,注意必须要写是对那个变量进行监听的
watch([msg,mn],(newvalue,oldvalue)=>{
// 当监听函数监听到msg值改变
// 并且msg改变后的值为marry,就打印“值改变了”
console.log(newvalue,oldvalue)
if(newvalue[0]=="marry"){
console.log("值改变了")
}
})
// 点击事件触发,改变msg中的value值
let fn=function(){
msg.value="marry"
}
let num =ref(0)
第二种:监听reactive定义的响应式数据
// 监听reactive所定义的一个响应式数据的全部属性
// 注意1:此处无法正确的获取oldvalue值(我们发现获取的值oldvalue=newvalue)
// 注意:并且强制开启了深度监视(此时的deep配置无效)
let obj=reactive({name:"颜淡",age:20,son:{age:1}})
let fn2=()=>{
obj.son.age++
}
//监听obj
watch(obj,(newvalue,oldvalue)=>{
console.log(newvalue,oldvalue)
})
案例:
8.生命周期函数
在vue3中,新增了一个setup生命周期函数,setup执行的时机是在beforeCreate生命函数之前执行,因此在这个函数中是不能通过this来获取实例的;同时为了命名的统一,将beforeDestroy改名为beforeUnmount,destroyed改名为unmounted,
vue3.0在vue2.0的基础上的更新:
| vue2.0 | vue3.0 |
|---|---|
| beforeCreate | setup |
| created | setup |
| beforeMount | beforeMount |
| mounted | mounted |
| beforeUpdate | beforeUpdate |
| updated | updated |
| beforeDestroy | beforeUnmount |
| destroyed | unmounted |
| activated | |
| deactivated | |
| errorCaptured |
vue3新增了生命周期钩子,我们可以通过在生命周期函数前加on来访问组件的生命周期
Composition API 形式的生命周期钩子
//Composition API:组合式API
//如果要在steup函数中使用,就需要在生命周期函数前面加on
onBeforeMount onMounted
onBeforeUpdate onUpdated
onBeforeUnmount onUnmounted
onErrorCaptured
onRenderTracked
onRenderTriggered
使用方法:
1.引入生命周期函数:
import {on+生命周期函数} from "vue"
2.使用生命周期函数:
on+生命周期函数(){
代码;
}
案例:
9.Teleport
Vue 鼓励我们通过将 UI 和相关行为封装到组件中来构建 UI。我们可以将它们嵌套在另一个内部,以构建一个组成应用程序 UI 的树。
然而,有时组件模板的一部分逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到 DOM 中 Vue app 之外的其他位置
具体使用场景:比如:模态弹窗
使用方法:
//to属性:放到指定位置
<div>
<h1>{{msg}}</h1>
<button @click="fn">按钮</button>
<teleport to='body' >
<h1>{{msg}}</h1>
</teleport>
</div>
案例:
10.属性传值(父组件给子组件传值:)
第一种:继续使用vue2.0的语法
<script>
export default {
props:["msg"],// props:{msg:String},
setup(){}
}
< /script>
<template>
<div>
{{msg}}
</div>
</template>
父组件:
<script setup>
import Box from "./Box.vue"
let n="hello"
</script>
<template>
<div>
<Box :msg="n"></Box>
</div>
</template>
第二种:vue3组件内部组合式API setup中取属性值
<script>
export default {
//注册属性
props:["msg","count"],// pops:{msg:String},
setup(props,ctx){
//props:父组件给子组件的属性传值
//ctx:代表上下文对象,也就是vue提供的功能:emit、inject等
let fn=()=>{console.log(props.msg,props.count)}//必须在组件中注册属性不然setup函数收不到数据
return {fn}
}
}
< /script>
<template>
<div>
<p> {{msg}}</p>
<button @click="fn">look</button>
</div>
</template>
父组件:
<Box :msg="n" :count="200"></Box>
第三种:setup语法糖中获取属性值
<script setup>
import {defineProps} from "./Box1.vue"
//注意3.2之后不用引入可以直接使用
let obj=defineProps(["msg","count"])
let fn=()=>{console.log(obj.msg,obj.count)}
}
< /script>
<template>
<div>
<p> {{obj.msg}}</p>
<button @click="fn">look</button>
</div>
</template>
父组件:
<Box :msg="n" :count="200"></Box>
11.自定义属性(子组件给父组件传值)
第一种:vue3.2之前的版本
- 定义自定义事件
可以通过 emits 选项在组件上定义发出的事件
//父组件
<HomeView @my-event="fn" @my-submit="fn1"></HomeView>
//子组件
<template>
<div @mouseenter="fm">
<button @click="fn">点我触发mybtn组件内部的myclick事件</button>
</div>
</template>
<script>
export default {
emits:["myEvent","myclick"],
methods:{
fn(){
this.$emit("myClick",200)
},
fm(){
this.$emit("click",300)
}
}
}
</script>
v-model参数
//父组件
<HomeView v-model:title="bookTitle"></HomeView>
//子组件
//1.接收参数
props:["title"]
//2.定义事件
emits: ['update:title']
//3.触发事件
this.$emit("update:title","子组件传递给父组件的值")
- 多个
v-model绑定
//2.0这样写会有矛盾
<MyVmodel v-model="msg" v-model="msg2" v-model="msg3"></MyVmodel>
//2.0应该这样写:
<MyVmodel
v-model="msg"
:msg2="msg2" @changemsg2="changemsg2"
:msg3="msg3" @changemsg3="changemsg3">
</MyVmodel>
js:
changemsg2(arg){this.msg2=arg}
changemsg3(arg){this.msg3=arg}
//3.0
<MyVmodel v-model="msg" v-model:msg2="msg2" v-model:msg3="msg3"></MyVmodel>
//父组件
<user-name
v-model:msg1="msg1"
v-model:msg2="msg2"
></user-name>
//子组件
//1.接收参数
props:["msg1","msg2"]
//2.定义事件
emits: ['update:msg1','update:msg2']
//3.触发事件
this.$emit('update:msg1',"子组件传递给父组件的值1")
this.$emit('update:msg2',"子组件传递给父组件的值2")
案例:
12. 状态驱动的动态 CSS
单文件组件的 <style> 标签可以通过 v-bind 这一 CSS 函数将 CSS 的值关联到动态的组件状态上
<template>
<div class="box1">hello</div>
<button @click="changcolor">修改box1的样式</button>
<div class="box2">hello66666</div>
<button @click="changother">修改box2的样式</button>
</template>
<script setup>
import { ref, reactive } from "vue"
//给这个变量定义成响应式数据
let color = ref("red")
let changcolor = () => {
color.value = "blue"
}
let other = reactive({
width: "200px",
height: "100px"
})
let changother = () => {
other.width = "400px"
}
</script>
<style lang="scss" scoped>
.box1 {
//绑定一个变量
color: v-bind('color');
}
.box2 {
background-color: yellow;
width: v-bind('other.width');
height: v-bind('other.height');
}
</style>
案例:
13.Suspense
-
等待异步组件时渲染一些额外的内容,让应用有更好的用户体验
<suspense>组件有两个插槽。它们都只接收一个直接子节点。default插槽里的节点会尽可能展示出来。如果不能,则展示fallback插槽里的节点。<template> <div class="fa"> <h1>父组件HomeView</h1> <!-- <Helloworld></Helloworld> --> <suspense> //真正组件 <template #default> <MyChild></MyChild> </template> //#:代表的是v-solt: //占位组件 <template #fallback> <div> <h1> 正在加载中Loading...</h1> </div> </template> </suspense> </div> </template> <script setup> //defineAsyncComponent:异步组件 import { defineAsyncComponent } from "vue" // import Helloworld from "../components/HelloWorld.vue" //静态引用 let MyChild = defineAsyncComponent(() => import("../components/HelloWorld.vue")) //异步引入 </script> <style lang="scss" scoped> .fa { height: 300px; background-color: #ccc; } </style>