5--vue计算computed与监听watch、使用lodash库减少watch对后台请求的压力
视图层调用数据中心data中的变量,调用方法中心methods方法,使用计算属性
html:
<div id="app"> <!-- 视图层调用数据中心data中的变量,调用方法中心methods方法,使用计算属性 --> {{i}},{{sum()}},{{sum2}} </div>
vuejs:
<script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ i:0, j:0 }, computed:{ sum2(){ console.log('computed...') return this.i*2-1 } }, methods:{ sum(){ console.log('methods...') return this.i*2-1 } } }) </script>
点击按钮,数据中心数据i 在视图层的点击事件@click="i++" 发生变化i++,后,数据中心的i随时发生变化。方法中心methods和计算属性computed中的i同步跟着变化。
在视图层添加按钮,操作如下所示:
<button @click="i++">+</button>
当用户点击按钮,i变化,效果如下所示:
特别注意:
只有在data中的属性(只有在data中声明的属性),才叫响应式属性,这个响应式叫数据的响应式
不在data中的属性,页面不会发生变化
html:
{{j}} <button @click="j++">+</button>
vuejs:
<script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ i:0, j:0 }, computed:{ sum2(){ console.log('computed...') return this.i*2-1 } }, methods:{ sum(){ console.log('methods...') return this.i*2-1 } } }) </script>
特别注意:
不在数据中心data中定义变量,变量定义在:
var vm = new Vue({ el:'#app', k:0, data:{ i:0, j:0 },
在视图层,调用k,
注意:k 是自定义属性 可以 通过 vm.$options.k获取到属性值。
html:
{{$options.k}}
在html:
<button @click="add">+</button>
在vuejs:
methods:{ sum(){ console.log('methods...') return this.i*2-1 }, add(){ //使用 vm.$options 可以获取 实例上自定义的 属性 this.$options.k++; console.log(this.$options.k) } }
vm.$options:是用来获取data属性之外属性的方法
使用 vm.$options 可以获取 实例上自定义的 属性-----this.$options.k
预览效果如下所示:
因为k不是data数据中心的数据,所以在视图层 不会 发生 数据的响应式变化!!!(重点,一定要理解!)
watch监听单个(数据)---Vue侦听器(侦听者)watch -----用于观察Vue实例上的数据变动
注意:数据:一般类型的数据 和 复杂类型的数据。
watch监听 一般类型的数据 和 复杂类型的数据,监听方式不同。
watch监听的是复杂数据类型的时候,需要做深度监听。
注意:watch监听的数据,一定是在data中是存在的!!
vue通过watch来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
(1) 监听变量的变化~~~一般数据类型的数据--num的变化
例如1:
html:
<div id="app"> {{i}} <button @click="i++">+</button> <hr> </div>
vuejs:
<script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ i:0 }, watch:{ // 监听 变量 新,旧的变化 i(newValue,oldValue){ console.log(newValue,oldValue) } }, methods:{ } }) </script>
例如2:
<p>计数器:{{num}}</p>
<button @click="num++">点我</button>
-----
var vm = new Vue({
el: '#app',
data:{
num: 1
},
// vue中watch的作用:响应数据的变化。
watch:{
// 监听num的变化
'num': function(newVal,oldVal){
console.log('num变化:'+oldVal+'变为:'+newVal+'!');
},
// 注意:可以这样写
num(newVal,oldVal){
console.log('num变化:'+oldVal+'变为:'+newVal+'!');
},
// 注意:可以这样写
num:{
// handler中传入了两个参数
// 处理“监听数据变化时”的函数
handler(newVal,oldVal){
console.log('num变化:'+oldVal+'变为:'+newVal+'!');
}
}
}
})
注意:监听的数据 'num' 或 "num" 或 num
(2) 监听数组的变化
html:
<div id="app"> <ul> <li v-for="(item,index) in list"> {{item}} <!-- 通过点击按钮,修改当前数据项上的内容为hello --> <button @click="update(index)">修改</button> </li> </ul> </div>
vuejs:
<script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ list:['a','b','c','d'] }, watch:{ // 监听数组变化(没有新旧值得说法,只监听到变化后的新值) // 所以下面这种写法不用 // list(newValue,oldValue){ // console.log(newValue,oldValue) // } list(value){ console.log(value) } }, methods:{ update(index){ // 两种方法,都可以替换数组中指定位置上的内容 // (1)方法1 // this.list.splice(index,1,'hello') // (2)方法2 this.list[index] = 'hello' } } }) </script>
预览效果如下所示:
(3) 监听对象(属性的)变化
例如1
将实例中数据中心data中的数据,
var vm = new Vue({ el:'#app', data:{ list:[ {id:1,name:'a'}, {id:2,name:'b'}, {id:3,name:'c'} ] },
渲染到视图层
html:
<div id="app"> <ul> <li v-for="(item,index) in list"> {{item.name}} <button @click="update(index)">修改</button> </li> </ul> </div>
效果如下所示:
点击视图层,按钮,修改 对象中 某个属性上的值,方法如下所示:
methods:{ update(index){ // 指定id为2上的name换成hello this.list.splice(index,1,{ id:2, name:'hello' }) console.log('methods...',this.list) } }
我们通过watch深度deep:true监听---对象上属性的变化,设置如下所示:
watch:{ list:{//深度监听 handler(val){ console.log(val) }, deep:true } },
效果如下所示:
例如2
html:
<div id="app"> {{obj.a.b.c.d}} <button @click="obj.a.b.c.d++">+</button> </div>
vuejs:
<script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ obj:{ a:{ b:{ c:{ d:1 } } } } }, watch:{ handler(val){ console.log(val) }, deep:true }, methods:{ change(){ this.obj = { a:{ b:{ c:{ d:2 } } } } } } }) </script>
例如3
<p>
<input type="text" name="" id="" v-model="msg.text">
</p>
<p v-if="msg.text !== ''">你输入的信息是:{{msg.text}}</p>
-----
var vm = new Vue({
el: '#app',
data:{
msg: {text:''}
},
// vue中watch的作用:响应数据的变化。
watch:{
// 监听num的变化
msg:{
// handler中传入了两个参数
handler(newVal,oldVal){
if(newVal.text == '你好,李焕英'){
console.log(newVal.text)
}
},
deep:true
}
}
})
我们需要监听对象的属性值是否发生改变用handler和deep!
我们使用watch监听数据时,有三个选项,handler,deep,immediate!
handler方法:
handler方法:
handler中传入了两个参数
handler(newVal,oldVal){
}
deep属性:深度监听对象变化 (代表是否深度监听)
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,此时就需要deep属性对对象进行深度监听。
vue是不能检测到对象属性的添加或删除,我们使用watch监听一个对象时,除非是直接重新给对象赋值,否则是不能监听到对象里的值的变化的。
deep就是用来进行深度监听的!
deep:false //值为true或false,默认false
deep为true
把deep设为true后,就可以得到我们想要的结果了,可以监听到对象属性的变化。
数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。
使用watch时有一个特点:
就是当值第一次绑定时,不会执行handler()监听函数,只有值发生改变时才会执行handler()监听函数。
如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
immediate [ɪˈmiːdiət] 立即
属性:该值默认是false,在进入页面时,第一次绑定值,watch不会“立刻执行”监听,只有数据发生改变 watch 才会执行handler中的操作。
immediate:false, //值为true或false,默认false
immediate:true,---- 刚进入页面的时候,watch 可以立刻 监听到 对象中属性的值。
immediate:false,---- 刚进入页面的时候,watch 不会“立刻执行” 监听。
immediate为true
我们可以看到,handler方法会在第一次绑定值时就触发(调用执行)。
Vue中使用watch监听"路由变化"的方法
watch除了可以监听数据的变化,路由的变化也能被其监听到。
vue核心插件之一————Vue Router路由模块
vue-router 路由插件是vue的核心插件
1.下载
npm install vue-router -S
路由,其实就是"指向"的意思。 / 路由
例如:
<div class="container"> <div id="app"> <router-link to="/login">登录</router-link> <router-link to="/register">注册</router-link> <router-view></router-view> </div> <template id="login"> <h2>登录</h2> </template> <template id="register"> <h2>注册</h2> </template> </div>
vuejs:
<script src="js/vue.js"></script> <script src="js/vue-router.js"></script> <script> // 创建2个组件 let login = { template:'#login' } let register = { template:'#register' } // 创建路由对象 let router = new VueRouter({ routes:[ { path:'/', redirect:'/login' }, { path:'/login', component:login }, { path:'/register', component:register } ] }) let vm = new Vue({ el:'#app', data:{ }, // 使用路由 router, //侦听器---监听路由的变化 watch:{ '$route.path':function(newVal,oldVal){ if(newVal=='/login'){ console.log('欢迎进入登录页面'); } if(newVal=='/register'){ console.log('欢迎进入注册页面'); } } } }) </script>
预览效果,如下所示:
还没有留言,还不快点抢沙发?