Vue基础6:computed计算属性及watch监听

watch监听用来监听某个prop或data的改变,当它们发生变化时,就会触发watch配置的函数,从而完成我们的业务逻辑。

watch监听的数据的回调函数handler(newVar,oldVar)有两个参数可用,第一个就是新的值第二就是旧的

1、watch监听基本例子

<div>
   <p>FullName: {{fullName}}</p>
   <p>FirstName: <input type="text" v-model="firstName"></p>
</div>
 
new Vue({
 el: '#root',
 data: {
  firstName: 'Dawei',
  lastName: 'Lou',
  fullName: ''
 },
 watch: {
  firstName(newName, oldName) {
   this.fullName = newName + ' ' + this.lastName;
  }
 } 
})

上面的代码的效果是,当我们输入firstName后,wacth监听每次修改变化的新值,然后计算输出fullName。

2、watch监听的deep属性

watch 里面还有一个属性deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个obj属性:

<div>
   <p>obj.a: {{obj.a}}</p>
   <p>obj.a: <input type="text" v-model="obj.a"></p>
</div>
 
new Vue({
 el: '#root',
 data: {
  obj: {
   a: 123
  }
 },
 watch: {
  obj: {
   handler(newName, oldName) {
     console.log('obj.a changed');
   },
   immediate: true
  }
 } 
})

     当我们在在输入框中输入数据视图改变obj.a的值时,我们发现是无效的。Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

watch: {
 obj: {
  handler(newName, oldName) {
   console.log('obj.a changed');
  },
  immediate: true,
  deep: true
 }
}

       deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。 

注意在watch监听的handler()方法中,第一个参数监听到的最新值,而第二个参数是旧值

3、watch应用

3.1、监听data中的属性

<div id="app">
    <input type="text" v-model="firstName"> +
    <input type="text" v-model="lastName"> =
    <span>{{fullName}}</span>
  </div>

  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen',
        fullName: 'jack - chen'
      },
      methods: {},
      watch: {
        'firstName': function (newVal, oldVal) { // 第一个参数是新数据,第二个参数是旧数据
          this.fullName = newVal + ' - ' + this.lastName;
        },
        'lastName': function (newVal, oldVal) {
          this.fullName = this.firstName + ' - ' + newVal;
        }
      }
    });
  </script>

3.2、监听路由对象的变化

<div id="app">
    <router-link to="/login">登录</router-link>
    <router-link to="/register">注册</router-link>

    <router-view></router-view>
  </div>

  <script>
    var login = Vue.extend({
      template: '<h1>登录组件</h1>'
    });

    var register = Vue.extend({
      template: '<h1>注册组件</h1>'
    });

    var router = new VueRouter({
      routes: [
        { path: "/login", component: login },
        { path: "/register", component: register }
      ]
    });

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      router: router,
      watch: {
        '$route': function (newVal, oldVal) {
          if (newVal.path === '/login') {
            console.log('这是登录组件');
          }
        }
      }
    });
  </script>

4、计算属性computed

在computed属性对象中定义计算属性的方法;在页面中使用{{方法名}}来显示计算的结果。

监视属性

通过通过vm对象的$watch()或watch配置来监视指定的属性;当属性变化时, 回调函数自动调用, 在函数内部进行计算。

计算属性高级

  通过getter/setter实现对属性数据的显示和监视;计算属性存在缓存, 多次读取只执行一次getter计算。

<div id="demo">
  姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
  名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
  姓名1(单向): <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
  姓名2(单向): <input type="text" placeholder="Full Name2" v-model="fullName2"><br>
  姓名3(双向): <input type="text" placeholder="Full Name3" v-model="fullName3"><br>

  <p>{{fullName1}}</p>
  <p>{{fullName1}}</p>
  <p>{{fullName1}}</p>
  <p>{{fullName1}}</p>

  <p>{{fullName3}}</p>
  <p>{{fullName3}}</p>
  <p>{{fullName3}}</p>
  <p>{{fullName3}}</p>

</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">

  // 对Vue进行全局配置
  Vue.config.productionTip = false // 不显示没使用生产环境模式的提示

  const vm = new Vue({
    // el: '#demo',
    data: {
      firstName: 'A',
      lastName: 'B',
      fullName2: 'A-B',
    },

    // 计算属性: 通过计算动态产生一个要显示的结果数据
    computed: {

      /* 
      计算属性方法: 包装getter
      执行的时机:
        初始显示第一个次执行, 得到初始值显示
        依赖数据发生改变就会再次调用
       */
      fullName1 () {
        console.log('fullName1()', this)
        return this.firstName + '-' + this.lastName
      },

      fullName3: {
        get () { // 计算产生要显示的值
          console.log('fullName3 get()')
          return this.firstName + '-' + this.lastName
        },

        set (value) { // 监视值的变化
          console.log('fullName3 set()', value)
          const names = value.split('-')
          this.firstName = names[0]
          this.lastName = names[1]
        }
      }
    },

    watch: { // 指定监视vm的哪个属性的变化
      firstName (value) { // 当firstName发生改变时自动回调
        console.log('firstName()', value)
        // 更新fullName2
        this.fullName2 = value + '-' + this.lastName
      }
    }
  })

  vm.$mount('#demo')

  // 监视lastName
  vm.$watch('lastName', function (value) {
    console.log('lastName()', value)
    this.fullName2 = this.firstName + '-' + value
  })

注意:所有vue控制的回调函数的this都是vm或者组件对应。使用计算属性:

(1)只用getter,计算属性就是一个函数;

(2)使用getter/setter,计算属性是一个包含getter和setter对象。

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值