Vue.js 事件监听

普通事件写法

常规事件

<div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <button v-on:click="greet">Greet</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  },
  methods: {
     greet: function (event) {
       // event 是原生 DOM 事件
       if (event) {
         alert(event.target.tagName)
       }
     }
   }
})

事件中传递原始 DOM

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
methods: {
  warn: function (message, event) {
    // 现在我们可以访问原生事件对象
    if (event) event.preventDefault()
    alert(message)
  }
}

监听方法

计算属性 computed

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello',
    reversedMessage: '',
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    },
    fullName: {
     get: function () {
       return this.firstName + ' ' + this.lastName
     }
    } 
  }
})

侦听器 watch

当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

对象内属性的监听

先 computed,再 watch

  data(){
    return {
      ruleForm: {
        loginName: ""
      },
    }
  },
  computed: {
    loginName: function(){
      return this.ruleForm.loginName
    }
  },
  watch: {
    loginName(newForm,oldForm){
      if(newForm !== oldForm){
        ...
      }
    }
  },

深层 watch,deep 设置

  watch: {
    ruleForm: {
      handler(newForm,oldForm){
        if(newForm.loginName !== oldForm.loginName){
        ...
        }
      },
      deep: true
    }
  },

直接监听对象里的属性

 'e.f': function (val, oldVal) { /* ... */ } 

父子组件间事件监听 $emit

默认监听事件

<blog-post
  ...
  v-on:enlarge-text="postFontSize += 0.1"
></blog-post>

同时子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件:

<button v-on:click="$emit('enlarge-text')">
  Enlarge text
</button>
<input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >

子组件修改父组件中要传递给子组件的prop值

在一个包含 title prop 的假设的组件中,我们可以在子组件中用以下方法表达对其赋新值的意图:

this.$emit('update:title', newTitle)

父组件中使用 .sync 修饰符,以监听那个事件并根据需要更新一个本地的数据属性

<text-document v-bind:title.sync="title"></text-document>