Contents

举一个案例,我们要拼接一个fullname,因此要监听到文本框数据的改变,这样才能知道什么时候去拼接 出一个 fullname
案例结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<div id="app">
<input type="text" v-model="firstname">+
<input type="text" v-model="lastname">=
<input type="text" v-model="fullname">
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: '',
fullname: ''
},
methods: {},
});
</script>

页面结构:
页面结构
在前两个文本框里输入字符串,最终拼接成一个整体的字符串。

#一、利用keyup事件来实现

####1.我们在input标签里绑定keyup事件
定义一个函数getFullname:

1
2
3
<input type="text" v-model="firstname" @keyup="getFullname"> +
<input type="text" v-model="lastname" @keyup="getFullname"> =
<input type="text" v-model="fullname">

在vm中定义方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: '',
fullname: ''
},
methods: {
getFullname() {
this.fullname = this.firstname + '-' + this.lastname
}
}
});

结果如下:
keyup事件结果

#二、使用watch
watch和methods平级

###1.watch监听数据变化
使用这个 属性,可以监视 data 中指定数据的变化,然后触发这个 watch 中对应的 function 处理函数
该方法可以不用绑定事件

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
<body>
<div id="app">
<input type="text" v-model="firstname">+
<input type="text" v-model="lastname">=
<input type="text" v-model="fullname">
</div>



<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: '',
fullname: ''
},
methods: {},
watch: {
'firstname': function(newVal){
this.fullname = newVal + '-' + this.lastname
},
'lastname': function(newVal){
this.fullname = this.firstname + '-' + newVal
}
}
});
</script>
</body>

结果如下:
watch结果
注意:watch函数有两个变量,只是在该函数中有一个没有用上,写上也没有关系

1
2
3
4
5
6
7
8
watch: {
'firstname': function(newVal,oldVal){
this.fullname = newVal + '-' + this.lastname
},
'lastname': function(newVal){
this.fullname = this.firstname + '-' + newVal
}
}

结果还是一样:
watch结果2

###2.watch监听路由变化
在上一篇博客中介绍了路由的基本使用
现在,我们把结构照搬过来

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
50
51
<!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>
<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>
var login = {
template: '<h3>这是登录子组件,这个组件是 奔波霸 开发的。</h3>'
}

var register = {
template: '<h3>这是注册子组件,这个组件是 霸波奔 开发的。</h3>'
}

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: router
router,
watch: {}
});
</script>
</body>

</html>

在watch中定义方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var vm = new Vue({
el: '#app',
data: {},
methods: {},
// router: router
router,
watch: {
//$route.path == this.$route.path
'$route.path': function(newVal,oldVal){
if(newVal === '/login'){
console.log('欢迎进入login')
}else if(newVal === '/register'){
console.log('欢迎进入register')
}
}
}
});

结果如下:
watch监听路由变化

#三、computed计算属性的使用
在 computed 中,可以定义一些 属性,这些属性,叫做 【计算属性】, 计算属性的本质,就是 一个方法,只不过我们在使用 这些计算属性的时候,是把它们的名称直接当作属性来使用的;并不会把 计算属性当作方法去调用;
computed和methods平级



注意1: 计算属性,在引用的时候,一定不要加 () 去调用,直接把它当作普通 属性去使用就好了;
注意2: 只要 计算属性,这个 function 内部,所用到的 任何 data 中的数据发送了变化,就会立即重新计算 这个 计算属性的值

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
<body>
<div id="app">
<input type="text" v-model="firstname">+
<input type="text" v-model="lastname">=
<input type="text" v-model="fullname">
</div>


<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: '',
},
methods: {},
watch: {},
computed: {
'fullname': function(){
return this.firstname + '-' + this.lastname
}
}
});
</script>
</body>

注意:
1.fullname没有在data中定义
2.在compute定义fullname后直接return出去就好



注意3: 计算属性的求值结果,会被缓存起来,方便下次直接使用; 如果 计算属性方法中,所有的任何数据,都没有发生过变化,则不会重新对计算属性求值;

例:我们在fullname函数中定义输出一个ok,并且在主页中调用输出fullname

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
<body>
<div id="app">
<input type="text" v-model="firstname">+
<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: '',
},
methods: {},
watch: {},
computed: {
'fullname': function(){
console.log('ok')
return this.firstname + '-' + this.lastname
}
}
});


</script>
</body>

打开页面:
打开页面

输入值之后结果如下:
结果

#####也就是说,不会因为页面中调用几次函数去执行几次,只会根据函数执行来调用函数

#四、watch、computed和methods之间的对比

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  2. methods方法表示一个具体的操作,主要书写业务逻辑;
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体;
Contents