Vue3.x–监听属性
vue3.x 的监听属性watch 与 vue2.x 中的watch配置功能一致
但是需要注意的是:
- 监视reactive定义的响应式数据时,oldvalue无法正确获取,强制开始了深度监视(deep的配置失效)
- 监视reactive定义的响应式数据的某一个值时:deep配置有效
<template>
<div>
<h3>{{name}}</h3>
<button @click="changeName">changeName</button>
</div>
</template>
<script setup>
import { ref, watch } from "vue";
let name = ref("karen");
let changeName = () => {
name.value = "jack";
}
watch(name,(newvalue,oldvalue)=>{
console.log(newvalue,oldvalue);
})
</script>
Vue3生命周期函数
什么是生命周期
Vue中每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁、这就是一个组件所谓的生命中周期
Vue2.x中的生命周期
beforeCreate created ----------------------- 创建前后
beforeMount mounted ---------------------- 挂载前后
beforeUpdate updated ---------------------- 更新前后
beforeDestroy destroyed ------------------- 销毁前后
activated ---------------------------------------- 组件激活时
deactivated ------------------------------------- 组件未激活时
errorCaptured ---------------------------------- 错误调用
Vue3.x的生命周期
在Vue3.x中,新增了一个setup生命周期函数,setup执行的时机是在beforeCreate生命函数之前执行,因为在这个函数中不能通过this来获取实例的;同时为了命名的统一,将beforeDestory改名为beforeUnmount,destoryed改名为unmounted
vue3新增了生命周期钩子,我们可以通过在生命周期函数前加on来访问组件的生命周期
setup 代替了 更新前后
onBeforeMount onMounted --------------------- 挂载前后
onBeforeUpdate onUpdated -------------------- 更新前后
onBeforeUnmount onUnmounted ------------- 销毁前后
onErrorCaptured
onRenderTracked
onRenderTriggered
作用跟上面的 vue2.x 的钩子函数函数一样,只是写法不一样了
<template>
<div>
<h3>vue3.x的声明周期钩子</h3>
<p>{{myData}}</p>
<button @click="changeData">changeData</button>
</div>
</template>
<script setup>
import { onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated, ref } from "vue";
let myData = ref(1)
let changeData = function(){
myData.value++
}
onBeforeMount(function () {
console.log("APP 挂载前 的时候执行");
})
onMounted(()=>{
console.log("APP 挂载后 的时候执行");
})
onBeforeUpdate(()=>{
console.log("APP 更新前 的时候执行");
})
onUpdated(()=>{
console.log("APP 更新后 的时候执行");
})
onBeforeUnmount(()=>{
console.log("APP 销毁前 的时候执行");
})
onUnmounted(()=>{
console.log("APP 销毁后 的时候执行");
})
</script>
Teleport 函数
这个函数可以让我们内容放到我们指定的位置上去,即可以跳出template标签
to属性:放到指定位置
例如:模态弹窗,就可以放在body里面去
to后跟的是一个标签名
<template>
<div>
<div class="box">
<h3>{{ title }}</h3>
<button @click="changeTitle">changeTitle</button>
</div>
<teleport to="body">
<div class="box1">
我在template标签外面,body里面
</div>
</teleport>
</div>
</template>
<script setup>
import { ref } from "vue";
let title = ref("template");
function changeTitle() {
title.value = "我在template标签里面";
}
</script>
<style lang="scss">
.box{
width: 200px;
height: 200px;
background-color: lightblue;
}
.box1{
width: 200px;
height: 200px;
background-color: yellow;
}
</style>
属性
属性传值
vue3组件内部组合式API setup中取属性值
必须在组件中注册属性不然setup函数收不到数据
<template>
<div>
{{name}} -- {{age}}
</div>
</template>
<script>
import { ref } from "vue";
export default {
props:["name", "age"],
setup(props) {
console.log(props,props.name,props.age);
return {props}
}
}
</script>
<style scoped lang="scss">
</style>
自定义组件
与组件和 prop 一样,事件名提供了自动的大小写转换。如果在子组件中触发一个以 camelCase (驼峰式命名) 命名的事件,你将可以在父组件中添加一个 kebab-case (短横线分隔命名) 的监听器。
父组件
<script setup>
import {ref} from "vue"
import Box from "./Box.vue"
function fn(arg,arg2){
console.log(arg,arg2)
}
import Box3 from "./Box1.vue"
let msg2=ref("hello2")
let msg3=ref("hello3")
let msg4=ref("hello4")
</script>
<template>
<div>
<h1>test</h1>
<Box title="hello" @myxxx="fn"></Box>
<p>{{msg}}</p>
<Box2 :value="msg" @input="input1"></Box2>
<p>爸爸--{{msg2}}--{{msg3}}-{{msg4}}</p>
<Box3 v-model:value="msg2" v-model:a="msg3" v-model:b="msg4"></Box3>
</div>
</template>
<style scoped>
</style>
Box.vue
<script setup>
import {ref,watch,defineEmits} from "vue"
let count=ref(1)
let fm=()=>{
count.value++
}
let emit=defineEmits()
watch(count,(v)=>{
if(v==5){
emit("myxxx",10,20)
}
})
</script>
<template>
<div>
<p>{{count}}</p>
<button @click="fm">increment</button>
</div>
</template>
<style>
</style>
Box1.vue
<template>
<div>
<p>box2-{{value}}-{{a}}--{{b}}</p>
<button @click="fn">box2-change1</button>
</div>
</template>
<script setup>
let obj=defineProps(["value","a","b"])
let emit=defineEmits()
let fn=()=>{
emit("update:value",100)
emit("update:a",200)
emit("update:b",300)
}
</script>
<style>
</style>
css变量
单文件组件的 <style>
标签可以通过 v-bind
这一 CSS 函数将 CSS 的值关联到动态的组件状态上
<template>
<div class="box">
<h2>{{text}}</h2>
<button @click="change">change</button>
</div>
</template>
<script setup>
import { ref } from "vue";
let text = ref("hello");
let color1 = ref("red");
let change=()=>{
color1.value="skyblue"
}
</script>
<style lang="scss">
.box{
color:v-bind(color1);
}
</style>
占位组件suspense
我们在加载中,会因为需要网络请求,而加载一会,而这时我们一般就会使用占位组件来,在未加载出来的时候,显示一些画面
<script setup>
import Box1 from "./Box1.vue"
import Box2 from "./Box2.vue"
import {defineAsyncComponent} from "vue"
let Box3=defineAsyncComponent(()=>import("./Box3.vue"))
</script>
<template>
<div>
<Box1></Box1>
<Box2></Box2>
<suspense>
<template #default>
<Box3></Box3>
</template>
<template #fallback>
<div>loading....</div>
</template>
</suspense>
</div>
</template>
<style scoped lang="scss">
</style>
<template>
<div class="box">
box1
</div>
</template>
<script setup>
</script>
<style lang="scss">
.box{
color:yellow;
}
</style>
<template>
<div class="box2">
box2--{{msg}}
</div>
</template>
<script>
import {ref,defineComponent} from "vue"
let Box2=defineComponent({
data(){
return {}
},
methods:{},
setup(){
let msg=ref("hello-box2")
return {msg}
}
})
export default Box2;
</script>
<style lang="scss">
.box2{
color:red;
}
</style>
<template>
<div class="box1">
加载box3
</div>
</template>
<script>
</script>
<style lang="scss">
.box1{
color:pink;
}
</style>