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>预览效果,如下所示:




还没有留言,还不快点抢沙发?