Vue常用指令
条件渲染
案例
<!-- 条件渲染
-->
<template>
<span v-if="flag">flag为true时显示这个span</span>
<br>
<span v-show="flag">条件为真时渲染</span>
<br>
<span v-if="sex==1">🚹</span>
<span v-else-if="sex==0">🚺</span>
<span v-else>不男不女</span>
<button @click="f1">改变sex值</button>
<br>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
let flag=true
let sex=ref(0)
function f1(){
if(sex.value==0){
sex.value=1
return
}
else{
sex.value=0
}
}
</script>
v-if和v-show的区别,当判定条件为假时,v-show只是不显示它所包裹的内容,会保留它的结构,而v-if时直接删除,不保留
列表渲染
案例
<!-- 列表渲染 -->
<template>
<table>
<tr v-for="stu in students" :key="stu.id">
<td>{{stu.id}}</td>
<td>{{stu.name}}</td>
<td>{{stu.age}}</td>
<td v-if="stu.sex==0">🚹</td>
<td v-else>🚺</td>
<td>{{ stu.classroom }}</td>
</tr>
</table>
<!-- v-for -->
<span>**************************</span>
<div v-for="value in myObject">
<span>{{ value }}</span>
</div>
<span>**************************</span>
<div v-for="(stu, key) in students">
{{ key }}: {{ stu }}
</div>
<span>**************************</span>
<div v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
let students=reactive([
{
id:"2",
name:"李四",
age:"36",
sex:1,
classroom:"2"
},
{
id:"3",
name:"周天",
age:"77",
sex:0,
classroom:"1"
},
{
id:"4",
name:"王五",
age:"99",
sex:0,
classroom:"8"
},
{
id:"5",
name:"刘六",
age:"10",
sex:1,
classroom:"5"
}
])
const myObject = reactive({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
})
watch
作用:监视数据的变化
牢记watch只能监视如下4种数据:
ref
定义的数据。reactive
定义的数据。- 函数返回一个值(
getter
函数)。 - 一个包含上述内容的数组。
因为ref可以定义基本类型和对象类型,所以watch对数据的监视可以分为5种情况
1.watch监视ref定义的基本类型数据
<template>
<div class="person">
<h1>情况一:监视ref定义的基本类型数据</h1>
<h2>当前求和为:{{sum}}</h2>
<button @click="changeSum">点我sum+1</button>
</div>
</template>
<script lang="ts" setup >
import {ref,watch} from 'vue'
// 数据
let sum = ref(0)
// 方法
function changeSum(){
sum.value += 1
}
/*
watch参数 要监视的数据 一个回调函数(在被监视的数据的地址值发生改变时被调用)
watch返回一个停止监视函数 调用它停止对watch的监视
*/
const stop=watch(sum,(newValue,oldValue)=>{
console.log("新值:"+newValue+"--"+"旧值"+oldValue)
if(newValue>=10){
stop() //停止监视
}
})
</script>
重点:回调函数在数据的地址值发生变化时被调用
2.watch监视ref定义的对象类型数据
<template>
<div class="person">
<h1>情况二:监视【ref】定义的【对象类型】数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改整个人</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
// 数据
let person = ref({
name:'张三',
age:18
})
// 方法
function changeName(){
person.value.name += '~'
}
function changeAge(){
person.value.age += 1
}
function changePerson(){
person.value = {name:'李四',age:90}
}
/*
监视,情况一:监视【ref】定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视
watch的第一个参数是:被监视的数据
watch的第二个参数是:监视的回调
watch的第三个参数是:配置对象(deep、immediate等等.....)
*/
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:true})
</script>
可以看到,开启深度监视后,name和age字段的改变也会被我们监视到
****************************************
如果watch是这样写的(没有开启深度监视,那么只有修改整个人,回调函数才会被调用)
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
})
3.watch监视reactive定义的对象类型数据
<template>
<h2>姓名:{{ student.name }}</h2>
<h2>年龄:{{ student.age }}</h2>
<button @click="f1">改变姓名</button>
<button @click="f2">改变年龄</button>
<button @click="f3">改变整个人</button>
</template>
<script setup>
import { reactive, watch } from 'vue';
let student=reactive({
"name":"张三",
"age":13
})
function f1(){
student.name=student.name+"~"
}
function f2(){
student.age=student.age+1
}
function f3(){
Object.assign(student,{
"name":"李四",
"age":99
})
}
watch(student,(newValue,oldValue)=>{
console.log("发生变化",newValue,oldValue)
})
/*
这样是不行的 因为reactive定义的整个对象会失去响应式
function f3(){
student={
"name":"李四",
"age":99
}
}*/
</script>
注意看,这里的newValue和oldValue都是一样的
我们首先需要明确的是:
1.回调函数只有被监视数据的地址发生改变时才被调用
2.reactive监视的数据默认开启深度监视,也就是student里面的name和age会被监视到
以改变姓名举例,watch监视到name地址值改变,回调函数被调用,但是我们监视的是student这个整体,它的地址值未曾改变(Object.assign只是覆盖了两个字段的值),因此这时候拿到的newValue和oldValue都是修改后的值。
在实际开发中,我们一般只用到修改后的值,因此不需要太纠结。
watch(person,(value)=>{
console.log('我只要修改后的值',value)
})
4.watch监视ref或reactive定义的对象类型里面的某个属性
reactive
<template>
<div class="person">
<h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeC1">修改第一台车</button>
<button @click="changeC2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script lang="ts" setup>
import {reactive,watch} from 'vue'
// 数据
let person = reactive({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
// 方法
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changeC1(){
person.car.c1 = '奥迪'
}
function changeC2(){
person.car.c2 = '大众'
}
function changeCar(){
person.car = {c1:'雅迪',c2:'爱玛'}
}
</script>
如果要监视的是对象里面的一个基本数据类型,要用getter方法
// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
watch(()=> person.name,(newValue,oldValue)=>{
console.log('person.name变化了',newValue,oldValue)
})
如果监视的是对象里面的一个对象类型,可以用getter方法,也可以不用,如果需要监视这个被监视的对象的里面,还是要开启深度监视
// 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
watch(()=>person.car,(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
ref(同理reactive)
<template>
<div class="person">
<h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeC1">修改第一台车</button>
<button @click="changeC2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script lang="ts" setup>
import {ref,watch} from 'vue'
// 数据
let person = ref({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
// 方法
function changeName(){
person.value.name+="~"
}
function changeAge(){
person.value.age += 1
}
function changeC1(){
person.value.car.c1 = '奥迪'
}
function changeC2(){
person.value.car.c2 = '大众'
}
function changeCar(){
person.value.car = {c1:'雅迪',c2:'爱玛'}
}
</script>
如果要监视的是对象里面的一个基本数据类型,要用getter方法
watch(()=>person.value.name,(newValue,oldValue)=>{
console.log("name改变了",newValue,oldValue)
})
监视对象里面的一个对象类型,开启深度监视
watch(()=>person.value.car,(newValue,oldValue)=>{
console.log("car改变了",newValue,oldValue)
},{deep:true})
5.监视多个数据
统一用getter方法 然后开深度监视
<template>
<div class="person">
<h1>情况五:监视上述的多个数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeC1">修改第一台车</button>
<button @click="changeC2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script lang="ts" setup >
import {reactive,watch} from 'vue'
// 数据
let person = reactive({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
// 方法
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changeC1(){
person.car.c1 = '奥迪'
}
function changeC2(){
person.car.c2 = '大众'
}
function changeCar(){
person.car = {c1:'雅迪',c2:'爱玛'} //因为这里是直接赋值 所以地址值改变了
}
// 监视,情况五:监视上述的多个数据
watch(()=>[person.car,person.age],(newValue,oldValue)=>{
console.log("car或age被修改",newValue,oldValue)
},{deep:true})
</script>
watchEffect
官网:立即运行一个函数(相当于{immediate}),同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。
说的通俗点就是watch的升级版,直接写你的代码逻辑,他会根据你用到的去监听,不需要你自己去告诉它你要监视哪些数据。
<template>
<div class="person">
<h1>需求:水温达到50℃,或水位达到20cm,则联系服务器</h1>
<h2 id="demo">水温:{{temp}}</h2>
<h2>水位:{{height}}</h2>
<button @click="changePrice">水温+10</button>
<button @click="changeSum">水位+10</button>
</div>
</template>
<script lang="ts" setup>
import {ref,watch,watchEffect} from 'vue'
// 数据
let temp = ref(0)
let height = ref(0)
// 方法
function changePrice(){
temp.value += 10
}
function changeSum(){
height.value += 10
}
/*
// 用watch实现,需要明确的指出要监视:temp、height
watch([temp,height],(value)=>{
// 从value中获取最新的temp值、height值
const [newTemp,newHeight] = value
// 室温达到50℃,或水位达到20cm,立刻联系服务器
if(newTemp >= 50 || newHeight >= 20){
console.log('联系服务器')
}
})
*/
// 用watchEffect实现,直接写你的代码逻辑,他会根据你用到的去监听
//格式:watchEffect( ()=>{} )
const stopWtach = watchEffect(()=>{
// 室温达到50℃,或水位达到20cm,立刻联系服务器
if(temp.value >= 50 || height.value >= 20){
console.log(document.getElementById('demo')?.innerText)
console.log('联系服务器')
}
// 水温达到100,或水位达到50,取消监视
if(temp.value === 100 || height.value === 50){
console.log('清理了')
stopWtach()
}
})
</script>