一、computed 计算属性
对于任何复杂的计算逻辑,当前属性值是根据其他属性计算出来的,都应当使用计算属性。
与methods对比
- 计算属性必须返回结果
- 计算属性是基于它的依赖缓存的。一个计算属性所依赖的数据发生变化时,它才会重新取值。
- 使用计算属性还是methods取决于是否需要缓存,当遍历大数组和做大量计算时,应当使用计算属性,除非你不希望得到缓存。
- 计算属性是根据依赖自动执行的,methods需要事件调用。
与watch属性的对比
watch属性用来观察和响应 Vue 实例上的数据变动。
两者相比,如果我们需要数据变化后的结果,只要关注结果和影响的参数就好,而不用去跟踪每个影响的参数。计算属性
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter 。比如原来的全名是li long 拼接起来的,当全名变成zhang hong 之后,对应的firstname lastname也会发生改变。computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
- computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择
<div id="app">
{{total}}
</div>
<script>
var vm = new Vue({
el:"#app",
data(){
return{
firstName:"zhang",
lastName:"san"
}
},
/* 当参与计算的值发生改变时,总值会改变 */
computed: {
total(){
return this.firstName+this.lastName
}
},
})
</script>
<body>
<div id="app">
<input type="text" v-model="firstname"> +
<input type="text" v-model="middlename"> +
<input type="text" v-model="lastname"> =
<input type="text" v-model="fullname">
<p>{{ fullname }}</p>
<p>{{ fullname }}</p>
<p>{{ fullname }}</p>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: '',
middlename: ''
},
methods: {},
computed: {
// 在computed中可以定义一些属性,这些属性叫做【计算属性】,计算属性的本质就是一个方法,只不过我们在使用这些计算属性的时候是把它们的名称直接当作属性来使用的,并不会把计算属性当作方法去调用
// 注意1: 计算属性在引用的时候,一定不要加()去调用,直接把它当作普通属性去使用就好了;
// 注意2: 在计算属性的function中所用到的任何data中的数据发送了变化,就会立即重新计算这个计算属性的值
// 注意3: 计算属性的求值结果会被缓存起来,方便下次直接使用。
'fullname': function () {
console.log('ok')
return this.firstname + '-' + this.middlename + '-' + this.lastname
}
}
});
</script>
</body>
</html>
1.1 get和set函数
计算属性由两部分组成:get和set,分别用来获取计算属性和设置计算属性。默认只有get函数,如果需要set,需要自己添加。另外set设置属性,并不是直接修改计算属性,而是修改它的依赖。(修改data里的数据)
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
//计算属性
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
//this.fullName = newValue 这种写法会报错
var names = newValue.split(' ');//将newValue的firstname和lastName分开
this.firstName = names[0]//对它的依赖进行赋值
this.lastName = names[names.length - 1]
}
}
}
二、watch 侦听器
- watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象
- watch一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数据
2-1.深度监视
<!--
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
-->
2-2 监听文本框变化
```javascript <!DOCTYPE html>
+
=
<a name="AriPG"></a>
### 2-3 监听路由地址的变化
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/vue-2.4.0.js"></script>
<!-- 1. 导入包 -->
<script src="./lib/vue-router-3.0.1.js"></script>
</head>
<body>
<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<!-- 容器 -->
<router-view></router-view>
</div>
<script>
// 2. 创建子组件
var login = {
template: '<h3>这是登录子组件,这个组件是 奔波霸 开发的。</h3>'
}
var register = {
template: '<h3>这是注册子组件,这个组件是 霸波奔 开发的。</h3>'
}
// 3. 创建一个路由对象
var router = new VueRouter({
routes: [
// 路由规则数组
{ path: '/', redirect: '/login' },
{ path: '/login', component: login },
{ path: '/register', component: register }
],
linkActiveClass: 'myactive'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router,
watch: {
// this.$route.path
'$route.path': function (newVal, oldVal) {
if (newVal === '/login') {
console.log('欢迎进入登录页面')
} else if (newVal === '/register') {
console.log('欢迎进入注册页面')
}
}
}
});
</script>
</body>
三、watch、computed和methods之间的对比
computed
当前属性的值是依赖于其他属性的值求出来的,计算属性的结果会被缓存,除非依赖的属性变化才会重新计算,主要当作属性来使用;methods
方法表示一个具体的操作,主要书写业务逻辑;watch
一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;