computed 计算属性的用法
第一种用法:想要把字符串反转,这个只是单向的变化 getter属性
有时会在视图层放入太多的逻辑处理,导致违背了关注点分离的特点,也不好维护,这时考虑计算属性的用法,例如:
<div id="app">
<p> {{ msg }} </p>
<!-- 需求:将msg反向输出 str->arr->reverse -> str -->
<!-- V是视图,vm才是管逻辑,违背关注点分离 下面做法不太好 -->
<p> {{ msg.split('').reverse().join('') }} </p>
<!-- 更好的做法 -->
<p> {{ reverseMsg }} </p>
</div>
这时写成计算属性时,
var vm = new Vue({
el: '#app',
data: {
msg: 'I Love Lakers 我喜欢湖人队'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.msg.split('').reverse().join('')
}
}
})
用法是将在计算属性computed里声明了一个计算属性来放这段逻辑,vm.reversedMessage 的值始终取决于 vm.msg 的值。这时msg值改变时才会改变reversedMessage的值
这种计算属性的定义和定义方法的不同:
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
在组件methods中定义这个计算方法时,每次都会执行这个方法函数,但是计算属性是需要msg的值改变时才会重新求值,这就意味着只要 msg 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
如果需要做很大的计算量时,这时如果直接是用函数方法时,每次都会执行会很慢,但是计算属性的话就可以避免这种情况
第二种用法:想将实时输入的双向做改变 getter和setter属性
比如实现这样的效果↓
输入姓名的时候会合起来在第三个框显示,或者是在第三个框输入时会自动分割在第一和第二个框实现,注意这里要用双向数据传输
<div id="app">
<div>
<label for="">姓:</label>
<input type="text" v-model = "firstName"> //用的是v-model绑定,双向数据输出
</div>
<div>
<label for="">名:</label>
<input type="text" v-model = "lastName">
</div>
<div>
<label for="">全名:</label>
<input type="text" v-model = "fullName">
</div>
</div>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: ''
},
computed: {
// 计算属性第二种用法
fullName: {
get () { // getter
// get是用于初始化赋值的
return this.firstName + this.lastName
},
set ( value ) { // setter
// 不考虑特殊名字 四个字
// 默认姓只有一个
console.log(value);
this.firstName = value.slice(0,1) // 这里的this指向的是new Vue中的东西
this.lastName = value.slice(1)
}
}
}
})
这个计算属性是绑在第三个input那里的,get()属性是指 这个框没输入时显示的是什么,set()属性就是这个框输入什么的时候做什么样的操作,这时的value是指这个框写入的内容
侦听属性的使用
监听有两种,一种是只监听一层结构,一种是深度监听,类似数组和对象这种是引用类型,引用的是地址,改变时并不能触发简单的watch,所以有深度监听
监听是指当监听的数据发生改变时就执行里面的操作
第一种:简单监听
<div id="app">
<h2> 单层数据 </h2>
<button @click = "increment"> + </button>
<p> count的值为: {{ count }}</p>
new Vue({
el: '#app',
data: {
count: 0
},
watch: {
// 监听 ---》 监听的对象 --》 data当中的数据 --> watch中属性和data中的属性是同名
count (newCount,oldCount) {
//这个count就是指监听data中的count
//第一个是改变后的count,第二个是改变前的count
// 如果 data 当中count发生了改变,那么watch中的count方法会自动执行
alert(newCount);
console.log('oldCount',oldCount);
immediate: true
},
methods: {
increment () {
// 增加
this.count ++
}
监听的immediate属性(立即处理 进入页面就触发) 这个是什么意思呢??加上有什么意思?是指即使数据不发生变化也会进入监听状态吗?
第二种:深度监听
对象和数组都是引用类型,引用类型变量存的是地址,地址没有变,所以 不会触发watch。这时我们需要进行深度监听,就需要加上一个属性 deep,值为 true
<div id="app">
<h2> 多层数据 </h2>
<button @click = "changeName"> change Name </button>
<p>name的值为: {{ person.name }} </p>
</div>
<script>
new Vue({
el: '#app',
data: {
person: {
name: 'Lakers'
}
},
watch: {
// person () {
// // 这种方法的形式是无法监听多层结构的
// console.log('person发生了改变')
// }
person: {
deep: true, // 深度监听 这种深度监听是地址类型变化也能监听到
handler () { //hander是固定写法
console.log('person发生了改变')
},
immediate: true, // 表示立即执行
}
},
methods: {
changeName () {
this.person.name = '王二麻子'
}
}
})
</script>
==为什么需要watch监听呢?==来自官网
使用 watch 选项允许我们执行异步操作 (访问一个 API),????限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
注意:methods、computed和watch的区别
下面转述我朋友的笔记,仅供自己学习用
1. computed和methods
- 共同点:computed能实现的methods也能实现
- 不同点:computed是基于它的依赖进行缓存的。computed只有在它的相关依赖发生变化才会重新计算求值。
而只要它的相关依赖没有发生变化,多次访问会立即返回之前的计算结果,而不必再次执行计算。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。也就是说当我们不希望有缓存时,就用方法替代。
2. watch和computed
- 共同点:都是以Vue的依赖追踪机制为基础的,都是希望在依赖数据发生变化的时候,
被依赖的数据根据预先定义好的函数,发生“自动”变化。
- 不同点:
1. watch擅长处理的场景:一个数据影响多个数据????;computed擅长处理的场景:一个数据受多个数据影响。
2. 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器,当需要在数据变化时执行异步(如定时器)或开销较大的操作时,通过侦听器最有用。【当一个值改变了需要1s之后显示到页面中,通过watch可以轻松的实现】
3. computed那里不能写异步代码,watch可以写异步代码