本文我们通过案例来介绍一下vue中 watch
和 computed
的使用规则,案例效果如下:
以上案例就是实现一个简单的 名称拼接处理。实现的方式有很多,本文我们将采用以下三种方式来实现。
1、DOM对象操作
我们可以通过普通的dom对象操作来实现这个效果:
首先给三个 input
输入框和 vm实例
做双向绑定,然后给前两个输入框分别绑定 keyup
事件,并且在 vm
实例的 methods
中定义拼接名称的方法即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model='one' @keyup='getres'> +
<input type="text" v-model='two' @keyup='getres'> =
<input type="text" v-model='res'>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
one:'',
two:'',
res:''
},
methods: {
getres(){
this.res = this.one + '-' + this.two
}
}
})
</script>
</body>
</html>
2、watch方法
watch
会监视 data
中指定的数据,当这些数据发生变动的时候会触发对应的 function
来处理相关的业务。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model='one'> +
<input type="text" v-model='two'> =
<input type="text" v-model='res'>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
one:'',
two:'',
res:''
},
methods: {},
watch:{
'one':function(to,from){
this.res = this.one + '-' + this.two
},
'two':function(to,from){
this.res = this.one + '-' + this.two
}
}
})
</script>
</body>
</html>
此处可能大家会比较疑惑,watch
需要监视 one
和 two
这两个信息,而我们通过 keyup
只需要在 methods
中定义一个方法就可以了,感觉 watch
反而没有前面例子中来的方便,那么 watch
还有什么作用呢?
注意:前面的事件监听只能处理 DOM元素,而针对 路由 的变化就无能为力了,我们来看看下面这个案例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.4.3/vue-router.min.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: "<h1>这是一个登录组件</h1>"
}
var register = {
template: "<h1>这是一个注册组件</h1>"
}
var routerObj = new VueRouter({
routes:[
{ path : "/login" , component : login },
{ path : "/register" , component : register }
]
})
var vm = new Vue({
el: "#app",
data: {},
methods: {},
router: routerObj
})
</script>
</body>
</html>
现在我们希望能够在路由变化的时候,捕获到这个行为,并给出响应。这时我们可以通过监视 vm.$route.path
来处理。
var vm = new Vue({
el: "#app",
data: {},
methods: {},
router: routerObj,
watch:{
'$route.path':function(newVal,oldVal){
if(newVal == '/login'){
alert('欢迎进入登录页面')
}else if(newVal == '/register'){
alert('这是注册界面')
}
}
}
})
watch
监视路由变化的效果就搞定了~
3、computed方法
在 computed
中,可以定义一些属性,这些属性叫做 计算属性, 计算属性的本质就是一个方法,只不过,我们在使用这些计算属性的时候,是把它们的名称直接当作属性来使用的,而不会把计算属性当作方法去调用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model='one'> +
<input type="text" v-model='two'> =
<input type="text" v-model='res'>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
one:'',
two:'',
},
methods: {},
computed: {
'res':function(){
return this.one + '-' + this.two
},
},
})
</script>
</body>
</html>
注意:
- 计算属性在引用的时候,一定不要加 () 去调用,直接把它当作普通属性去使用就好。
- 只要计算属性的
function
内部所用到的任何data
中的数据发送了变化,就会立即重新计算这个计算属性的值。 - 计算属性的求值结果会被缓存起来,方便下次直接使用。如果计算属性方法中任何数据都没有发生过变化,则不会重新求值。
methods、watch、computed的区别
元素 | 描述 |
---|---|
methods | 表示一个具体的操作,主要书写业务逻辑。 |
watch | 一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行具体的业务逻辑操作,可以看作是computed和methods的结合体。 |
computed | 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算,主要当作属性来使用。 |