06-vue中计算属性computed及监听属性watch
Posted Ultraman_agul
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06-vue中计算属性computed及监听属性watch相关的知识,希望对你有一定的参考价值。
计算属性及watch监听属性
-
计算属性
- 先看一个案例:动态渲染一个字母串,显示在页面时需要首字母大写,而从服务器请求回来的不一定会是首字母大写的情况,所以需要手动在前端作好处理。
<div id="box"> <!-- 将首字母大写,这里需要在页面中处理,这样的方式将业务逻辑写在了页面,会影响页面的可读性,这样的方式是不可取的。 --> myName.substr(0,1).toUpperCase() + myName.substr(1) </div> <script> var vm = new Vue( el:"#box", data: myName:"tom" ) </script>
上面的案例,将js的业务处理放在了页面html中,违背了表现与行为分离的原则,页面变得臃肿,可读性降低,难以维护,这种现象我们称之为模板过重。要解决这样模板过重问题,可以使用vue中的计算属性computed
- computed:定义计算属性的地方
<div id="box"> <!-- 将首字母大写,这里需要在页面中处理,这样的方式将业务逻辑写在了页面,会影响页面的可读性,这样的方式是不可取的。 --> <!-- myName.substr(0,1).toUpperCase() + myName.substr(1) --> <!-- 使用计算属性, 他用计算属性,无需像调用方法一样,它本质上是已经是方法执行后的返回值。 --> computedName </div> <script> var vm = new Vue( el:"#box", data: myName:"tom" , // 定义计算属性的地方 computed : //定义了一个计算属性computedName //当myName发生改变,这里的计算属性也会同步的执行并更新结果 computedName() return this.myName.substr(0,1).toUpperCase() + this.myName.substr(1) ) </script>
-
computed与methods的区别
computed:注重结果
1,逻辑计算,防止模板过重,有缓存 (计算属性在页面多次使用,方法不会重复调用,只有在模型数据发生更新时才会重新执行该函数 )
2,监听:依赖修改,get方法必须有return
methods(注重过程):
1,函数表达式的逻辑处理,没有缓存(页面使用几次,函数就会执行几次,没有缓存)
2,事件处理函数 ,return不是必需的
- 对比案例:
<div id="box"> <!-- 多次使用计算属性 --> computedName computedName computedName <!-- 换行 --> <br> <!-- 多次调用方法 --> comName() comName() comName() </div> <script> var vm = new Vue( el:"#box", data: myName:"tom" , methods: comName() //页面使用几次,函数就会执行几次,没有缓存 console.log("执行了方法") return this.myName.substr(0,1).toUpperCase() + this.myName.substr(1) , // 定义计算属性的地方 computed : computedName() //计算属性在页面多次使用,方法不会重复调用,只有在模型数据发生更新时才会重新执行该函数 console.log("运行了计算属性") return this.myName.substr(0,1).toUpperCase() + this.myName.substr(1) ) </script>
运行结果:
- 使用计算属性改造过滤搜索案例:
<div id="box">
<!-- v-model实现双向数据绑定 -->
<input type="text" v-model="myVal">
<ul>
<!-- 使用计算属性遍历数组 -->
<li v-for="item in computedData">
item
</li>
</ul>
</div>
<script>
var vm = new Vue(
el:"#box",
data:
//绑定数据的模型
myVal:"",
list:["aaa","bbb","abc","bac","bbc","cbb","ccc"]
,
computed:
//计算属性处理逻辑,返回更新后的数组
computedData()
//根据数据myVal的实时变化,返回过滤后的数组
return this.list.filter(item=>item.includes(this.myVal));
)
</script>
-
计算属性的完整写法
-
计算属性可以被赋值,前提是要使用计算属性的完整写法
以上案例的计算属性写法均为简写,简写是无法给计算属性赋值的,否则会报错
-
下面我们来看看完整写法是怎样的:
案例:
<div id="box">
<!-- 使用计算属性的简写 -->
简写方式输出: computedName
<br>
<!-- 使用计算属性的完整写法 -->
完整写法输出: compName
</div>
<script>
var vm = new Vue(
el:"#box",
data:
myName:"tom"
,
// 定义计算属性的地方
computed :
//这样的方式不是计算属性的完整写法,这是简写,简写方式无法赋值
computedName()
return this.myName.substr(0,1).toUpperCase() + this.myName.substr(1)
,
//计算属性完整写法
compName :
get()
return this.myName.substr(0,1).toUpperCase() + this.myName.substr(1)
,
set(data)
this.myName = data;
)
</script>
修改计算属性结果:
-
计算属性get和set方法的使用场景
- 在购物车案例中使用,使用计算性属性实现判断是否全部选中的功能
<body> <div id="box"> <div class="all" v-if="list.length === 0">购物车空空如也</div> <template v-else> <!-- <div class="all"><input type="checkbox" v-model="isChecked" @change="allCheck()">全选|全不选</div> --> <!-- 使用计算属性来判断是否全部选中 --> <div class="all"><input type="checkbox" v-model="isCheckedComputed">全选|全不选</div> <ul> <li v-for="(item,index) in list" :key="item.id"> <div> <!-- <input type="checkbox" v-model="checkGroup" :value="item" @change="isAllCheck()"/> --> <!-- 使用计算属性无需再使用isAllCheck()方法了 --> <input type="checkbox" v-model="checkGroup" :value="item"/> </div> <div> <img :src="item.pic" alt=""> </div> <div> <div>名称:item.name</div> <div>价格:¥item.price</div> </div> <div> <button @click="item.number--" :disabled="item.number===1">-</button> <span>item.number</span> <button @click="item.number++" :disabled="item.number===item.limit">+</button> </div> <div> <button @click="deleteGood(index,item.id)">删除</button> </div> </li> </ul> <div class="all">总金额: totalPrice()</div> </template> </div> <script> var vm = new Vue( el:"#box", data: isChecked:false, checkGroup:[], list:[.....] , methods: totalPrice() var total = 0; this.checkGroup.forEach((ele)=> total += ele.price * ele.number; ) return total , //删除商品 deleteGood(index,goodId) //删除原商品 this.list.splice(index,1); //更新选中的商品 this.checkGroup = this.checkGroup.filter(ele => ele.id !== goodId) //删除单个商品时也要检测是否全部被选中 this.isAllCheck(); , //全选全不选 // allCheck() // if(this.isChecked) // this.checkGroup = this.list // else // this.checkGroup = []; // // , //选择单个商品时,判断是否为全部选中 // isAllCheck() // if(this.checkGroup.length === this.list.length) // this.isChecked = true; // else // this.isChecked = false; // // , //定义计算属性判断是否全部被选中 computed : isCheckedComputed : get() //选择后的商品个数与原商品个数相同,说明全部被选中,否则为没有全部被选中 return this.checkGroup.length === this.list.length; , set(isChecked) if(isChecked) //全选按钮选中后,商品全部选中 this.checkGroup = this.list; else this.checkGroup = [];//取消全选,选中的数组列表这空 ) </script> </body>
-
watch监听属性
-
watch属性:监听,关注过程,无需return,无需调用。
监听指定数据状态,只要指定的数据发生改变,watch中所定义的对应属性会执行。
<div id="box"> <input type="text" v-model="myTest"> myTest </div> <script> var vm = new Vue( el:"#box", data: myTest:"" , //监听 watch : //定义要监听的属性 myTest(data) console.log(data)//只要myTest的状态发生改变,这个程序就会执行,改变的状态值会以形参data的方式传递过来 ) </script>
运行效果:
-
- watch实现购物车全选全不选功能
<div id="box">
<div class="all" v-if="list.length === 0">购物车空空如也</div>
<template v-else>
<!-- <div class="all"><input type="checkbox" v-model="isChecked" @change="allCheck()">全选|全不选</div> -->
<!-- 使用watch监听isChecked状态,无需再触发点击事件执行allCheck()方法 -->
<div class="all"><input type="checkbox" v-model="isChecked">全选|全不选</div>
<ul>
<li v-for="(item,index) in list" :key="item.id">
<div>
<input type="checkbox" v-model="checkGroup" :value="item" @change="isAllCheck()"/>
</div>
<div>
<img :src="item.pic" alt="">
</div>
<div>
<div>名称:item.name</div>
<div>价格:¥item.price</div>
</div>
<div>
<button @click="item.number--" :disabled="item.number===1">-</button>
<span>item.number</span>
<button @click="item.number++" :disabled="item.number===item.limit">+</button>
</div>
<div>
<button @click="deleteGood(index,item.id)">删除</button>
</div>
</li>
</ul>
<div class="all">总金额: totalPrice()</div>
</template>
</div>
<script>
var vm = new Vue(
el:"#box",
data:
isChecked:false,
checkGroup:[],
list:[.....]<以上是关于06-vue中计算属性computed及监听属性watch的主要内容,如果未能解决你的问题,请参考以下文章