watch监听data里面的数据的变化
<body>
<div id="app">
<input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num: ''
},
watch: {
num(newVal, oldVal) {
// 监听 num 属性的数据变化
// 作用 : 只要 num 的值发生变化,这个方法就会被调用
// 第一个参数 : 新值
// 第二个参数 : 旧值,之前的值
console.log('oldVal:',oldVal)
console.log('newVal:',newVal)
}
}
})
</script>
</body>
immediate和handler
这样使用watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
比如当父组件向子组件动态传值时,子组件props首次获取到父组件传来的默认值时,也需要执行函数,此时就需要将immediate设为true。
<body>
<div id="app">
<input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num: 1
},
watch: {
num: {
// 数据发生变化就会调用这个函数
handler(newVal, oldVal) {
console.log('oldVal:', oldVal)
console.log('newVal:', newVal)
},
// 立即处理 进入页面就触发
immediate: true
}
}
})
</script>
</body>
监听的数据后面写成对象形式,包含handler方法和immediate,之前我们写的函数其实就是在写这个handler方法;
immediate表示在watch中首次绑定的时候,是否执行handler,值为true则表示在watch中声明的时候,就立即执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。
deep
当需要监听一个对象或者数组的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
<input type="text" v-model="cityName.name"/>
new Vue({
el: '#root',
data: {
cityName: {id: 1, name: 'shanghai'}
},
watch: {
cityName: {
handler(newName, oldName) {
// ...
},
deep: true,
immediate: true
}
}
})
设置deep: true 则可以监听到cityName.name的变化,此时会给cityName的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行handler。如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性:
watch: {
'cityName.name': {
handler(newName, oldName) {
console.log(`newVal:${newVal}, oldVal:${oldVal}`)
},
deep: true,
immediate: true
}
}
监听路由的变化
watch除了可以监听data中数据的变化,还可以监听路由的变化。 监听 $route.path属性
watch:{
'$route.path':function(newVal,oldVal){
//console.log(newVal+"---"+oldVal);
if(newVal === '/login'){
console.log('欢迎进入登录页面');
} else if(newVal === '/register'){
console.log('欢迎进入注册页面');
}
}
}
完整代码如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id='app'>
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
</body>
<script src="../lib/vue.js"></script>
<script src="../lib/vue-router-3.0.1.js"></script>
<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}
]
})
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
router,
watch:{
// this.$route.path
'$route.path':function(newVal,oldVal){
//console.log(newVal+"---"+oldVal);
if(newVal === '/login'){
console.log('欢迎进入登录页面');
} else if(newVal === '/register'){
console.log('欢迎进入注册页面');
}
}
}
})
</script>
</html>