Happy Vue.js Components - Custom Events

Vue.js Components - Custom Events

The parent component uses props to pass data to the child component, but if the child component wants to pass the data back, you need to use a custom event!

We can use v-on to bind custom events, and each Vue instance implements the event interface (Events interface), namely:

  • Use  $on(eventName) listener events
  • Using  $emit(eventName) trigger events

In addition, the parent component can directly use v-on to listen to the events triggered by the child component where the child component is used.

In the following example the child component has been completely decoupled from its exterior. All it does is trigger an internal event that the parent component cares about.

example

<div id="app">
    <div id="counter-event-example">
      <p>{
   
   { total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>
 
<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{
   
   { counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>

If you want to listen to a native event on the root element of a component. You can modify v-on with .native. For example:


<my-component v-on:click.native="doTheThing"></my-component>

data must be a function

In the above example, you can see that the data in the button-counter component is not an object, but a function:

data: function () {
  return {
    count: 0
  }
}

The advantage of this is that each instance can maintain an independent copy of the returned object. If data is an object, it will affect other instances, as follows:

example

<div id="components-demo3" class="demo">
    <button-counter2></button-counter2>
    <button-counter2></button-counter2>
    <button-counter2></button-counter2>
</div>
 
<script>
var buttonCounter2Data = {
  count: 0
}
Vue.component('button-counter2', {
    /*
    data: function () {
        // data 选项是一个函数,组件不相互影响
        return {
            count: 0
        }
    },
    */
    data: function () {
        // data 选项是一个对象,会影响到其他实例
        return buttonCounter2Data
    },
    template: '<button v-on:click="count++">点击了 {
   
   { count }} 次。</button>'
})
new Vue({ el: '#components-demo3' })
</script>


v-model for custom components

A v-model on a component will by default utilize a prop named value and an event named input.

<input v-model="parentData">

Equivalent to:

<input 
    :value="parentData"
    @input="parentData = $event.target.value"
>

The following example customizes the component kxdang-input. The initial value of the num of the parent component is 100. Changing the value of the child component can update the num of the parent component in real time:

example

<div id="app">
    <kxdang-input v-model="num"></kxdang-input>
    <p>输入的数字为:{
   
   {num}}</p>
</div>
<script>
Vue.component('kxdang-input', {
    template: `
    <p>   <!-- 包含了名为 input 的事件 -->
      <input
       ref="input"
       :value="value" 
       @input="$emit('input', $event.target.value)"
      >
    </p>
    `,
    props: ['value'], // 名为 value 的 prop
})
   
new Vue({
    el: '#app',
    data: {
        num: 100,
    }
})
</script>

Since v-model passes value by default, not checked, we need to use the model option for check box or radio box components, which can specify the current event type and incoming props.

example

<div id="app">
    <base-checkbox v-model="lovingVue"></base-checkbox> 
     <div v-show="lovingVue"> 
        如果选择框打勾我就会显示。 
    </div>
</div> 
<script>
// 注册
Vue.component('base-checkbox', {
 
  model: {
    prop: 'checked',
    event: 'change'  // onchange 事件
  },
  props: {
    checked: Boolean
  },
   
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    lovingVue: true
  }
})
</script>

The value of lovingVue in the instance will be passed to the checked prop, and when the change event is triggered by <base-checkbox>, the value of lovingVue will also be updated.

Guess you like

Origin blog.csdn.net/weixin_72651014/article/details/130723927