19.Vue计算属性:computed

简介

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

虽然可以通过函数、事件等解决上面问题,但vue提供了更便捷的计算属性computed。

	<body>
		<div id="app">
			<input type="text" v-model="xing" placeholder="" />
			<input type="text" v-model="ming" placeholder="" />
			<div>
				<input type="text" v-model="xingming" placeholder="姓 名" />
			</div>
		</div>
	</body>
	<script type="text/javascript">
		let vm = new Vue({
			el: "#app",
			data: {
				xing: "",
				ming: "",
				// xingming:"" //不要在data定义计算属性名,否则computed里会失效
			},
			computed: {
				xingming: function() {
					return this.xing + " " + this.ming
				}
			}
		});
	</script>

运行:
在这里插入图片描述
 

getter与setter

计算属性默认只有 getter 用来返回计算出来的值,但我们也可以提供一个为计算属性设置值时候调用的函数setter。以上面的例子来说,如果我们直接输入【姓 名】栏,【姓】【名】都不会变,如果需要【姓】随之响应,则可以用到setter:

	<script type="text/javascript">
		let vm = new Vue({
			el: "#app",
			data: {
				xing: "",
				ming: "",
			},
			computed: {
                //为了方便展示,有小修改
				xingming: {
                    //getter
					get: function() {
						return this.xing + this.ming
					},
                    //setter
					set: function(newValue) {
						this.xing = newValue.charAt(0)
						this.ming = newValue.charAt(1)
					},
				}
			}
		});
	</script>

运行,此时设置【姓名】会按set方法中写的逻辑改变【姓】:
在这里插入图片描述
 

缓存

上面的例子如果使用methods可以达到同样的效果,但不同的是,如果使用了computed,值是有缓存的,只在相关响应式依赖发生改变时它们才会重新求值,那么在多次调用时,computed会执行更少次数:

	<body>
		<div id="app">
			<input type="text" v-model="xing" placeholder="" />
			<input type="text" v-model="ming" placeholder="" />
			
			<div v-for="index in 6" :key="index">
				<!-- v-for中用methods打印 -->
				<div style="background-color: red;">方法打印{{funXingMing()}}</div>
				<!-- v-for中用computed打印 -->
				<div style="background-color: blue;">计算属性打印{{xingming}}</div>
			</div>
		</div>
	</body>
	<script type="text/javascript">
		let vm = new Vue({
			el: "#app",
			data: {
				xing: "",
				ming: "",
			},
			methods: {
				funXingMing() {
					console.log("methods执行");
					return this.xing + this.ming;
				}
			},
			computed: {
				xingming: {
					get: function() {
						console.log("computed get执行");
						return this.xing + this.ming;
					},
				}
			}
		});
	</script>

运行会发现,改变input后,循环中每个div都会调用funXingMing(),而computed只调用1次。
在这里插入图片描述
 

深入响应式原理

下面的例子中用computed属性绑定了v-model,v-model中的输入将被用于和data中属性组成新的属性obj1中元素,并在下方<div>展示,而最上方<button>用于切换隐藏/显示该<div>。

	<body>
		<div id="content">
			<button @click="show=!show">点一下</button>
			<input type="text" v-model="myObj" />
			<div v-show="show">{{myObj}}</div>
		</div>
	</body>
	<script>
		var vm = new Vue({
			el: '#content',
			data: {
				show: true,
				obj: [
					{"name": "张三"},
					{"name": "李四"},
					{"name": "王五"},
				],
				obj1: []
			},
			computed: {
				myObj: {
					get() {
						if (this.obj1[0]) {
							return this.obj1[0].name;
						} else {
							return "";
						}
					},
					set(newValue) {
						this.obj1[0] = {
							"id": this.obj[0],
							"name": newValue
						}
					}
				}
			}
		});
	</script>

运行,当<input>中输入时,变量obj1和<div>没有任何响应,但当我们隐藏/展示后,obj1和<div>都能正确显示——因为受js的限制,Vue.js 不能检测到对象属性的添加或删除,因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的(详细原理可以参看下方相关资料)。
在这里插入图片描述
可以修改computed的set来达到预期效果:
在这里插入图片描述
 

相关资料

Vue某些情况下 v-model绑定数据不实时更新解决办法
vue深入响应式原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值