开心档之Vue.js 组件 - 自定义事件

简介: 【摘要】 由于 v-model 默认传的是 value,不是 checked,所以对于复选框或者单选框的组件时,我们需要使用 model 选项,model 选项可以指定当前的事件类型和传入的 props。

Vue.js 组件 - 自定义事件


父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

实例


<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>

如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:

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

data 必须是一个函数


上面例子中,可以看到 button-counter 组件中的 data 不是一个对象,而是一个函数:

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

这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例,如下所示:

实例


<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


组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。

<input v-model="parentData">

等价于:

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

以下实例自定义组件 kxdang-input,父组件的 num 的初始值是 100,更改子组件的值能实时更新父组件的 num:

实例


<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>

由于 v-model 默认传的是 value,不是 checked,所以对于复选框或者单选框的组件时,我们需要使用 model 选项,model 选项可以指定当前的事件类型和传入的 props。

实例


<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>

实例中 lovingVue 的值会传给 checked 的 prop,同时当 <base-checkbox> 触发 change 事件时, lovingVue 的值也会更新。

相关文章
|
2天前
|
编译器
vue3组件TS类型声明实例代码
vue3组件TS类型声明实例代码
4 0
|
2天前
|
JavaScript 前端开发 IDE
vue3基础: 组件注册
vue3基础: 组件注册
10 0
|
2天前
|
JavaScript
vue3使用element-plus 树组件(el-tree)数据回显
vue3使用element-plus 树组件(el-tree)数据回显
5 0
|
3天前
|
缓存 JavaScript
在 Vue 组件中使用计算属性和侦听器来响应路由变化
Vue Router 中,计算属性和侦听器常用于根据路由变化更新组件状态。计算属性缓存依赖,当路由参数改变时自动更新,如示例中的 `userId`。侦听器则监听 `$route` 变化,执行相应操作,例如在 `currentUserId` 示例中响应 `userId` 更新。计算属性适合简单变化,而异步操作或复杂场景可选用侦听器。Vue 3 中,`watchEffect` 减少了部分侦听场景的复杂性。总之,它们用于组件内部响应路由变化,而非直接处理路由逻辑。
11 4
|
3天前
|
JavaScript
Vue3的 组件事件
Vue3的 组件事件
16 0
|
JavaScript 前端开发
ActiveX组件与JavaScript交互
1.在COM组件中调用JavaScript函数// 连接点方式页面javascript脚本        alert("State(" + s + ")");        return 123;        testCom.
1024 0
|
JavaScript 前端开发 C++
一步一步实现ATL开发的ActiveX组件与javascript的交互(一)
1.      打开VS2008,单击起始页中的“New Project…”,选择“ATL”分类下的“ATL Project”项目,项目名称为“ATLtest”。在随后出现的项目向导中,使用默认配置即可。
1563 0
|
11天前
|
存储 移动开发 JavaScript
学习javascript,前端知识精讲,助力你轻松掌握
学习javascript,前端知识精讲,助力你轻松掌握
|
18天前
|
JavaScript 前端开发 测试技术
学习JavaScript
【4月更文挑战第23天】学习JavaScript
13 1
|
26天前
|
JavaScript 前端开发 应用服务中间件
node.js之第一天学习
node.js之第一天学习