计算属性与监听属性(computed和watch)
计算属性
- 计算属性定义在computed选项中
- 当计算属性依赖的数据发生变化时,计算属性会自动更新,所有依赖该属性的数据绑定也会同步更新
- 最重要的一点:计算属性是一个属性,不是一个方法
简单示例如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div id="box"> <p>原字符串:{{str}}</p> <p>新字符串:{{netstr}}</p> </div> <script type="text/javascript"> var vm = new Vue({ el: '#box', data: { str: 'HTML*JavaScript*Vue.js' }, computed: { netstr: function () { return this.str.split('*').join('+'); } } }); </script>
|
注:当data里的str发生变化时,newstr也会自动更新
计算属性+过滤器的一个实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <div id="box"> <div class="title"> <div>商品名称</div> <div>单价</div> <div>数量</div> <div>金额</div> </div> <div class="content" v-for="value in shop"> <div>{{value.name}}</div> <div>{{value.price}}</div> <div>{{value.count}}</div> <div>{{value.price*value.count | twoDecimal}}</div> </div> <p>总计:{{totalprice | formatPrice("¥")}}</p> </div> <script type="text/javascript"> var vm = new Vue({ el: '#box', data: { shop: [{ name: 'OPPO R15', price: 2999, count: 3, }, { name: '华为P20', price: 3699, count: 2, }] }, computed: { totalprice: function () { var total = 0; this.shop.forEach(function (s) { total += s.price * s.count; }); return total; } }, filters: { twoDecimal: function (value) { return value.toFixed(2); }, formatPrice: function (value, symbol) { return symbol + value.toFixed(2); } }
}); </script>
|
getter和setter
- 每一个计算属性都包含一个getter和setter
- getter用来执行读取值的操作,setter用来执行设置值的操作
- 当没有指明方法时(属性名后的function),默认使用getter来读取数据
- 在未设置setter的情况下给计算属性重新赋值,是不会触发更新的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <div id="box"> <p>{{fullname}}</p> </div> <script type="text/javascript"> var vm = new Vue({ el: '#box', data: { firstname: '张', lastname: '斯特', }, computed: { fullname: { get: function () { return this.firstname + this.lastname; }, set: function (value) { this.firstname = value.substr(0, 1); this.lastname = value.substr(1); } } } }); vm.fullname = '利乌斯'; </script>
|
上述示例执行过程:
- 定义了一个计算属性fullname
- 在给fullname重新赋值时会自动调用setter,并将新值作为参数传递给set()方法
- 在set()方法中定义去修改data里的属性值,当data属性值改变后,fullname也会跟着改变(而不是直接改变fullname的值,直接改变是无效的)
计算属性缓存
- 使用计算属性时,每次获取的值都是基于依赖的缓存值(即基础值)
- 当页面重新渲染时,如果依赖的数据未发生改变,则计算属性值也不会改变。只有依赖的数据改变,才会重新执行getter
下面给出计算属性和方法的区别
计算属性:只有依赖的值发生改变时,计算属性才会变
方法:每当页面重新渲染时,方法就会再次执行
监听属性
- 定义:监听属性用于监听和响应Vue实例中的数据变化
- 在监听数据对象中的属性时,每当监听的属性发生变化时,都会执行特定的操作
- 监听属性的名字和要监听的对象相同,即要监听哪个属性,命名就和那个属性名一样
- 定义监听属性有两种方式:
watch选项和实例方法vm.$watch()
- watch选项:
watch:{}
- vm.$watch()在Vue实例后面定义:
vm.$watch('监听对象名',function(参数){代码})
两种方法简单示例如下,第一个参数是新值,第二个参数是旧值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script type="text/javascript"> var vm = new Vue({ el: '#box', data: { fullname: '张三', }, watch: { fullname: function (newValue,oldValue) { alert('原值:' + oldValue + ' 新值:' + newValue); } } }); vm.fullname = '李四'; </script>
|
1 2 3 4 5 6 7 8 9 10 11 12
| <script type="text/javascript"> var vm = new Vue({ el: '#box', data: { fullname: '张三', }, }); vm.$watch('fullname', function (newValue, oldValue) { alert('原值:' + oldValue + ' 新值:' + newValue) }); vm.fullname = '李四'; </script>
|
deep选项
handler
先简单介绍一下handler,当deep的值为true时,必须使用handler函数
如果监听的属性是一个对象(即字典),为了监听对象内部值的变化,必须在watch选项中设置deep的值为true,简单示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script type="text/javascript"> var vm = new Vue({ el: '#box', data: { shop: { name: 'XiaoMi10', price: 3899, }, }, watch: { shop: { handler: function (val) { alert(val.name + '新价格为' + val.price); }, deep: true } } }); vm.shop.price = 4899; </script>
|
参考链接
- vue中watch的handler,deep,immediate用法详解
- vue handler ()的参数是什么