Bootstrap

Vue3 + ts 笔记

目录

1.解决直接赋值导致 proxy代理对象失去响应式

2. toRef   toRefs 

3.toRow markRow

4.reactive 响应式原理

5.计算属性购物车案例


#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>

;