computed用法
计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值。
有两种写法,对象模式和函数模式。他们的区别是:函数模式只可以读取计算属性,对象模式可以对计算属性的值进行修改
案例:
<script setup lang="ts">
import { ref,computed } from 'vue'
let firstName = ref('John')
let lastName = ref('Doe')
let fullName = computed(() => { return firstName.value + '-' + lastName.value })
function change():void {
fullName.value = 'Tom-foot'
}
</script>
<template>
<div>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
<br />
Full Name: {{ fullName }}
<button @click="change">Change</button>
</div>
</template>
<style scoped>
input {
margin: 5px;
display: block;
height: 30px;
}
</style>
对象形式案例:
<script setup lang="ts">
import { ref,computed } from 'vue'
let firstName = ref('John')
let lastName = ref('Doe')
let fullName = computed({
get: () => firstName.value + '-' + lastName.value,
set: (newValue) => {
[firstName.value, lastName.value] = newValue.split('-')
}
})
function change():void {
fullName.value = 'Tom-foot'
}
</script>
<template>
<div>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
<br />
Full Name: {{ fullName }}
<button @click="change">Change</button>
</div>
</template>
<style scoped>
input {
margin: 5px;
display: block;
height: 30px;
}
</style>
computed表格案例
<script setup lang="ts">
import { ref,computed,reactive } from 'vue'
const search = ref('')
interface Data {
name: string
price: number
num: number
}
const formData = reactive<Data[]>([
{
name: 'apple',
price: 10,
num: 1
},
{
name: 'banana',
price: 5,
num: 2
},
{
name: 'orange',
price: 15,
num: 3
}
])
const filterData = computed(() => {
return formData.filter(item => item.name.includes(search.value))
})
const total = computed(() => {
let sum = 0
filterData.value.forEach(item => {
sum += item.price * item.num
})
return sum
})
</script>
<template>
<div>
<input type="text" placeholder="搜索" style="width: 300px" v-model="search"/>
<table cellpadding="0" cellspacing="0" border="1" style="margin-top: 50px">
<thead>
<tr>
<th>名称</th>
<th>数量</th>
<th>价格</th>
<th>总价</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in filterData" :key="index">
<td>{{ item.name }}</td>
<td>
<button @click="item.num > 1 ? item.num-- : null">-</button>
{{item.num}}
<button @click="item.num < 99 ? item.num++ : null">+</button>
</td>
<td>{{ item.price }}</td>
<td>{{ item.price * item.num }}</td>
<td><button @click="formData.splice(index,1)">删除</button></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">总计:{{total}}</td>
</tr>
</tfoot>
</table>
</div>
</template>
<style scoped>
input {
margin: 5px;
display: block;
height: 30px;
}
th,td {
width: 200px;
height: 20px;
}
</style>
watch用法
监听一个数据源,并执行相关回调函数
watch第一个参数监听源
watch第二个参数回调函数cb(newVal,oldVal)
watch第三个参数一个options配置项是一个对象{
immediate:true //是否立即调用一次
deep:true //是否开启深度监听 reactive自动开启
}
监听多个ref案例:
<script setup lang="ts">
import { ref,reactive,watch } from 'vue'
const value = ref({
name: '张三',
age: 18
})
const value2 = ref({
name: '张三',
age: 18
})
watch([value,value2], (newValue, oldValue) => {
// 新旧value都会改变
console.log(newValue, oldValue)
},{
immediate: true,
deep: true
})
</script>
<template>
<input type="text" v-model="value.age">
<input type="text" v-model="value2.age">
</template>
<style scoped>
</style>
也会变成一个proxy数组,按照监听源数组的顺序进行排列
监听Reactive
使用reactive监听深层对象开启和不开启deep 效果一样
监控reactive的单一属性值
<script setup lang="ts">
import { ref,reactive,watch } from 'vue'
const value2 = reactive({
name: '张三',
age: 18,
person: {
salay: 100,
address: {
city: '北京'
}
}
})
watch(()=> value2.person.salay, (newValue, oldValue) => {
console.log(newValue, oldValue)
})
</script>
<template>
<input type="text" v-model="value2.person.salay">
</template>
<style scoped>
</style>
watchEffect
立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。也就是在函数里面用到的一些数据都会对其进行监听
案例:
也是不能深层监听的,也就是用到哪个数据就监听哪个数据
<script setup lang="ts">
import { ref,reactive,watchEffect } from 'vue'
const value = ref({
foo: {
bar: 'hello'
}
})
watchEffect(()=> {
console.log(value.value)
},{
flush: 'post'
})
</script>
<template>
<input type="text" v-model="value.foo.bar">
</template>
<style scoped>
input {
margin: 5px;
display: block;
height: 30px;
}
</style>
在触发监听之前会调用一个函数可以处理你的逻辑例如防抖
停止跟踪 watchEffect 返回一个函数 调用之后将停止更新
案例:
<script setup lang="ts">
import { ref,reactive,watchEffect } from 'vue'
const value = ref({
foo: {
bar: 'hello'
}
})
const stop = watchEffect(()=> {
console.log(value.value.foo.bar)
},{
flush: 'post'
})
stop()
</script>
<template>
<input type="text" v-model="value.foo.bar">
</template>
<style scoped>
input {
margin: 5px;
display: block;
height: 30px;
}
</style>