1.1 computed

一个数据, 依赖另外一些数据计算而来的结果

语法:
computed: {     "计算属性名" () {        return "值"   }}
需求: 求2个数的和显示到页面上
<template>  <div>    <p>{{ num }}</p>  </div> </template> ​ <script> export
default {  data(){    return {      a: 10,      b: 20   } },  // 计算属性:  // 场景:
一个变量的值, 需要用另外变量计算而得来  /*   语法:   computed: {     计算属性名 () {       return 值    
}   } */ // 注意: 计算属性和data属性都是变量-不能重名 // 注意2: 函数内变量变化, 会自动重新计算结果返回  computed: {
   num(){      return this.a + this.b   } } } </script> ​ <style> ​ </style>
计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同

1.2 缓存

计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果

<template>  <div>    <p>{{ reverseMessage }}</p>    <p>{{ reverseMessage
}}</p>    <p>{{ reverseMessage }}</p>    <p>{{ getMessage() }}</p>    <p>{{
getMessage() }}</p>    <p>{{ getMessage() }}</p>  </div> </template> ​ <script>
export default {  data(){    return {      msg: "Hello, Vue"   } },  // 计算属性优势:
 // 带缓存  // 计算属性对应函数执行后, 会把return值缓存起来  // 依赖项不变, 多次调用都是从缓存取值  // 依赖项值-变化,
函数会"自动"重新执行-并缓存新的值  computed: {    reverseMessage(){    
 console.log("计算属性执行了");      return this.msg.split("").reverse().join("")   }
},  methods: {    getMessage(){      console.log("函数执行了");      return
this.msg.split("").reverse().join("")   } } } </script> ​ <style> ​ </style>
计算属性根据依赖变量结果缓存, 依赖变化重新计算结果存入缓存, 比普通方法性能更高

1.3 vue计算属性-完整写法

计算属性也是变量, 如果想要直接赋值, 需要使用完整写法

语法:
computed: {    "属性名": {        set(值){                   },        get() {    
       return "值"       }   } }
需求: 计算属性给v-model使用

页面准备输入框
<template>  <div>      <div>          <span>姓名:</span>          <input
type="text" v-model="full">      </div>  </div> </template> ​ <script> // 问题:
给计算属性赋值 - 需要setter // 解决: /*   完整语法:   computed: {       "计算属性名" (){},      
"计算属性名": {           set(值){ ​           },           get(){              
return 值           }       }   } */ export default {    computed: {      
 full: {            // 给full赋值触发set方法            set(val){              
 console.log(val)           },            // 使用full的值触发get方法            get(){
               return "无名氏"           }       }   } } </script> ​ <style> ​
</style>
想要给计算属性赋值, 需要使用 set 方法

1.4 案例-小选影响全选

 小选框都选中(手选), 全选自动选中

分析:

① 先静态后动态, 从.md拿到静态标签和数据

② 循环生成复选框和文字, 对象的c属性和小选框的选中状态, 用v-model双向绑定

③ 定义isAll计算属性, 值通过小选框们统计c属性状态得来
<template>  <div>    <span>全选:</span>    <!-- 4. v-model 关联全选 - 选中状态 -->  
 <input type="checkbox" v-model="isAll"/>    <button>反选</button>    <ul>    
 <li v-for="(obj, index) in arr" :key="index">        <!-- 3. 对象.c - 关联 选中状态
-->        <input type="checkbox" v-model="obj.c"/>        <span>{{ obj.name
}}</span>      </li>    </ul>  </div> </template> ​ <script> // 目标: 小选框 -> 全选
// 1. 标签+样式+js准备好 // 2. 把数据循环展示到页面上 export default {  data() {    return {    
 arr: [       {          name: "猪八戒",          c: false,       },       {      
   name: "孙悟空",          c: false,       },       {          name: "唐僧",      
   c: false,       },       {          name: "白龙马",          c: false,       },
    ],   }; },  // 5. 计算属性-isAll  computed: {    isAll () {         // 6.
统计小选框状态 -> 全选状态        // every口诀: 查找数组里"不符合"条件, 直接原地返回false        return
this.arr.every(obj => obj.c === true)   } } }; </script>
1.5 案例-全选影响小选

全选影响小选

*
需求1: 获取到全选状态 – 改装isAll计算属性

*
需求2: 全选状态同步给所有小选框

分析:

①: isAll改成完整写法, set里获取到全选框, 勾选的状态值

②: 遍历数据数组, 赋给所有小选框v-model关联的属性
<script> export default {  // ...其他代码  // 5. 计算属性-isAll  computed: {    isAll:
{      set(val){        // 7. 全选框 - 选中状态(true/false)      
 this.arr.forEach(obj => obj.c = val)     },      get(){        // 6. 统计小选框状态
-> 全选状态        // every口诀: 查找数组里"不符合"条件, 直接原地返回false        return
this.arr.every(obj => obj.c === true)     }   } } }; </script>
1.6 案例-反选

需求: 点击反选, 让所有小选框, 各自取相反勾选状态

分析:

①: 小选框的勾选状态, 在对象的c属性

②: 遍历所有对象, 把对象的c属性取相反值赋予回去即可
<button @click="btn">反选</button> ​ <script> export default {  // ...其他代码省略
 methods: {    btn(){      // 8. 让数组里对象的c属性取反再赋予回去      this.arr.forEach(obj =>
obj.c = !obj.c)   } } }; </script>
2. vue侦听器

2.1 watch

可以侦听 data/computed 属性值改变

语法:
watch: {     "被侦听的属性名" (newVal, oldVal){           }}
完整例子代码:
<template>  <div>    <input type="text" v-model="name">  </div> </template> ​
<script> export default {  data(){    return {      name: ""   } },  // 目标:
侦听到name值的改变  /* 语法:   watch: {     变量名 (newVal, oldVal){       //
变量名对应值改变这里自动触发     }   } */  watch: {    // newVal: 当前最新值    // oldVal: 上一刻值  
 name(newVal, oldVal){      console.log(newVal, oldVal);   } } } </script> ​
<style> ​ </style>
2.2 深度侦听和立即执行

侦听复杂类型, 或者立即执行侦听函数
watch: { "要侦听的属性名": { immediate: true, // 立即执行 deep: true, // 深度侦听复杂类型内变化
handler (newVal, oldVal) { } } }
完整例子代码:
<template>  <div>    <input type="text" v-model="user.name">    <input
type="text" v-model="user.age">  </div> </template> ​ <script> export default {
 data(){    return {      user: {        name: "",        age: 0     }   } },
 // 目标: 侦听对象  /* 语法:   watch: {     变量名 (newVal, oldVal){       //
变量名对应值改变这里自动触发     },     变量名: {       handler(newVal, oldVal){ ​       },    
  deep: true, // 深度侦听(对象里面层的值改变)       immediate: true // 立即侦听(网页打开handler执行一次)
    }   } */  watch: {    user: {      handler(newVal, oldVal){        //
user里的对象        console.log(newVal, oldVal);     },      deep: true,    
 immediate: true   } } } </script> ​ <style> ​ </style>
 immediate 立即侦听

 deep 深度侦听

handler 固定方法触发

2.3 案例-品牌管理(数据缓存)

 侦听list变化, 同步到浏览器本地

*
需求: 把品牌管理的数据实时同步到本地缓存

分析:

① 在watch侦听list变化的时候, 把最新的数组list转成JSON字符串存入到localStorage本地

② data里默认把list变量从本地取值, 如果取不到给个默认的空数组

效果:

新增/删除 – 刷新页面 – 数据还在
<template>  <div>    <div class="container">      <!-- 顶部框模块 -->      <div
class="form-group">        <div class="input-group">          <h4>品牌管理</h4>    
   </div>      </div> ​      <!-- 数据表格 -->      <table class="table
table-bordered table-hover mt-2">        <thead>          <tr>          
 <th>编号</th>            <th>资产名称</th>            <th>价格</th>          
 <th>创建时间</th>            <th>操作</th>          </tr>        </thead>      
 <tbody>          <tr v-for="obj in list" :key="obj.id">            <td>{{
obj.id }}</td>            <td>{{ obj.name }}</td> ​            <!--
如果价格超过100,就有red这个类 -->            <td :class="{ red: obj.price > 100 }">{{
obj.price }}</td>            <td>{{ obj.time | formatDate }}</td>          
 <td><a href="#" @click="delFn(obj.id)">删除</a></td>          </tr>        
 <!-- 4. 统计得有数据才显示 -->          <tr v-if="list.length !== 0"
style="background-color: #eee">            <td>统计:</td>            <td
colspan="2">总价钱为: {{ allPrice }}</td>            <td colspan="2">平均价: {{
avgPrice }}</td>          </tr>        </tbody>        <tfoot
v-show="list.length === 0">          <tr>            <td colspan="5"
style="text-align: center">暂无数据</td>          </tr>        </tfoot>    
 </table> ​      <!-- 添加资产 -->      <form class="form-inline">        <div
class="form-group">          <div class="input-group">            <input      
       type="text"              class="form-control"            
 placeholder="资产名称"              v-model="name"            />          </div>  
     </div>                    <div class="form-group">    
     <div class="input-group">            <input              type="text"      
       class="form-control"              placeholder="价格"            
 v-model.number="price"            />          </div>        </div>      
      ​        <button class="btn btn-primary"
@click.prevent="addFn">添加资产</button>      </form>    </div>  </div> </template>
<script> // 目标: 侦听list改变 - 同步到本地localStorage里 // 1. 侦听器-list export default {  
 data(){        return{            name: "", // 名称      price: 0, // 价格      //
3. 本地取出缓存list      list: JSON.parse(localStorage.getItem('pList')) || [],   };
},  methods: {    addFn() {      if (this.name.trim().length === 0 ||
this.price === 0) {        alert("不能为空");        return;     } ​      let id =
       this.list.length === 0 ? 100 : this.list[this.list.length - 1].id + 1; ​
     this.list.push({        // 当前数组最后一个对象的id+1作为新对象id值        id: id,      
 name: this.name,        price: this.price,        time: new Date(),     });  
},    delFn(id){     // 通过id找到这条数据在数组中下标      let index =
this.list.findIndex(obj => obj.id === id)      this.list.splice(index, 1)   }
},  computed: {      allPrice(){          return this.list.reduce((sum, obj) =>
sum += obj.price, 0)     },      avgPrice(){          return (this.allPrice /
this.list.length).toFixed(2)     } },  watch: {    list: {      handler(){    
   // 2. 存入本地        localStorage.setItem('pList', JSON.stringify(this.list))  
  },      deep: true   } } }; </script> <style scoped> .red {  color: red; }
</style>

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信