目录
#1.解决直接赋值导致 proxy代理对象失去响应式
<template>
<button @click="getMsg">获取数据</button>
<h1 v-for="(item) in arr">{{item}}</h1>
</template>
let arr = reactive <string[]> ([])
let getMsg = () =>{
let msg = ['red','yellow','pink'];
arr = msg
}
这样直接赋值的写法会让 arr 从一个响应式数组 变成一个普通数组 ['red','yellow','pink']
导致页面无法显示数据
处理方法是
1. let getMsg = () =>{
let msg = ['red','yellow','pink'];
arr.push(...msg) 保留arr 的响应式
}
2. let arr = reactive <{
rra:string[]
}> ({
rra:[]
})
let getMsg = () =>{
let msg = ['red','yellow','pink'];
arr.rra = msg ; //意思是在arr对象的属性上 添加一个rra 属性是一个 字符串数组
}
相应的 <h1 v-for="(item) in arr.rra" // 改一下>{{item}}</h1>
2. toRef toRefs
toRef 让响应式对象的某个属性变成响应式 接收两个参数 目标对象&目标属性 返回一个refImp 相应式对象 通过value 修改
toRefs toRef 加强版 传 一个 响应式目标对象为参数 可以利用 结构赋值 直接将 对象属性 放在 模板
let toRefs = <T extends Object>(Object:T)=>{
let map:any = {};
for(let key in Object){
map[key] = toRef(Object,key)
}
return map
}
3.toRow markRow
toRow 将响应式对象变回普通对象
markRow 标记某个对象 使其不具有响应式 例如 多级结构对象
4.reactive 响应式原理
let obj = {name:'zs',age:18};
let reactive = (target)=>{
return new Proxy(target,{
get(target,key,receiver){
console.log('getter 触发了');
return Reflect.get(target,key)
},
set(target,key,value,receiver){
console.log('setter 触发了');
Reflect.set(target,key,value,receiver)
}
})
}
let p = reactive(obj);
5.计算属性购物车案例
<template>
<div>
<table border width="500px">
<thead>
<tr>
<th>名称</th>
<th>数量</th>
<th>单价</th>
<th>小结</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in list" :key="index">
<td>{{ item.name }}</td>
<td align="center">
<button @click="changeNum(item,0)" style="padding: 0 10px;">-</button>
{{ item.num }}
<button @click="changeNum(item,1)" style="padding: 0 10px;">+</button>
</td>
<td>{{ item.price }}</td>
<td>{{item.num *item.price }}</td>
<td>
<a href="javascript:;" @click="del(index)">删除</a>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>总价:{{ total }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script lang="ts" setup>
import { reactive,computed,ref } from "vue";
type clo = {
name: string;
price: number;
num: number;
};
let list = reactive<clo[]>([
{
name: "内衣",
price: 66,
num: 1,
},
{
name: "鞋子",
price: 77,
num: 1,
},
{
name: "裤子",
price: 88,
num: 1,
},
]);
let del = (i:number)=>{
list.splice(i,1);
// $total()
}
let changeNum = (item:clo,type:number)=>{
if(item.num >1 && !type){
item.num --
};
if(item.num <99 && type){
item.num++
}
// $total()
}
let total = computed(()=>{
return list.reduce((pre,cur)=>{
return pre + cur.num * cur.price
},0)
})
// let total = ref(0)
// let $total= ()=>{
// return list.reduce((pre,cur)=>{
// return pre + cur.num * cur.price
// },0)
// }
// $total()
</script>
<style scoped></style>