自定义事件与非父子组件间传值

简介: 《Vue实战》系列

API

在组件标签v-on绑定的事件是自定义事件

<div id="root">
    <child @click="handleClick"></child> <!--这里click是自定义事件-->
</div>
<script type="text/javascript">
    Vue.component('child', {
        template: '<button>Child</button>',
    })
    var vm = new Vue({
        el: '#root'
        methods: {
            handleClick() {
                alert('click')
            }
        }
    })
</script>

上面这种情况,当点击子组件时并不会触发handleClick()事件,因为此时的click并非原生的点击事件,而是一个自定义事件。

要想触发组件标签中的click事件需要通过子组件$emit来派发

<div id="root">
    <child @click="handleClick"></child>
</div>
<script type="text/javascript">
    Vue.component('child', {
        template: '<button @click="handleChildClick">Child</button>', // 这里的click是原生事件
        methods: {
            handleChildClick() {
                this.$emit('click')
            }
        }
    })
    var vm = new Vue({
        el: '#root'
        methods: {
            handleClick() {
                alert('click')
            }
        }
    })
</script>

上面代码中,子组件内的click是原生点击事件,通过$emit派发click自定义事件触发父组件的handleClick()

使自定义事件变为原生事件

使用.native修饰符把自定义事件变为原生事件

<div id="root">
    <child @click.native="handleClick"></child> <!--自定义事件添加了native修饰符变原生事件-->
</div>
<script type="text/javascript">
    Vue.component('child', {
        template: '<button>Child</button>',
    })
    var vm = new Vue({
        el: '#root'
        methods: {
            handleClick() {
                alert('click')
            }
        }
    })
</script>

上面代码中,自定义事件click添加了.native修饰符,使其变为原生事件,从而触发handleClick()

自定义事件名会自动变小写

当使用camelCase(驼峰)命名的自定义函数

this.$emit('myEvent')

则监听这个名字的 kebab-case(烤串) 版本是不会有任何效果的:

<!-- 没有效果 -->
<my-component v-on:my-event="doSomething"></my-component>

v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。

因此,我们推荐你始终使用 kebab-case(烤串) 的事件名

非父子组件间传值

当组件的嵌套多时,非父子组件间传值就显得复杂,除了使用vuex实现之外,还可以通过Bus(或者叫 总线/发布订阅模式/观察者模式)的方式实现非父子组件间传值。


<div id="root">
    <child1 content="组件1:点我传出值"></child1>
    <child2 content="组件2"></child2>
</div>
<script type="text/javascript">
    Vue.prototype.bus = new Vue()
    // 每个Vue原型上都会有bus属性,而且指向同一个Vue实例
    Vue.component('child1', {
        props: {
            content: String
        },
        template: '<button @click="handleClick">{{content}}</button>',
        methods: {
            handleClick(){
                this.bus.$emit('change', '我是组件1过来的~') // 触发change事件,传出值
            }
        }
    })
    Vue.component('child2', {
        data() {
            return {
                childVal: ''
            }
        },
        props: {
            content: String,
        },
        template: '<button>{{content}} + {{childVal}}</button>',
        mounted() {
            this.bus.$on('change', (msg) => { // 绑定change事件,执行函数接收值
                this.childVal = msg
            })
        }
    })
    var vm = new Vue({
        el: '#root'
    })
</script>

上面代码中,在Vue原型上绑定一个bus属性,指向一个Vue实例,之后每个Vue实例都会有一个bus属性。

此方法传值,不限于兄弟组件之间,其他关系组件间都适用。

See the Pen  非父子组件间传值2(Bus /总线/发布订阅模式/观察者模式) by xugaoyi (@xugaoyi)   on CodePen.

相关文章
|
4月前
父子组件传值
父子组件传值
|
4月前
|
JavaScript
Vue2中子组件调用父组件的方法,父组件调用子组件的方法,父子组件互相传值和方法调用
Vue2中子组件调用父组件的方法,父组件调用子组件的方法,父子组件互相传值和方法调用
Vue2中子组件调用父组件的方法,父组件调用子组件的方法,父子组件互相传值和方法调用
|
3月前
|
JavaScript
子组件向父组件传参的方式?
子组件向父组件传参的方式?
37 0
|
4月前
|
JavaScript
vue通讯 传值 3大传值方法 快速上手 父子间传值和非父子间传值
vue通讯 传值 3大传值方法 快速上手 父子间传值和非父子间传值
|
JavaScript
vue中子组件如何向父组件传值与父组件如何向子组件传值
vue中子组件如何向父组件传值与父组件如何向子组件传值
139 0
|
JavaScript
Vue——05-02组件的数据、为什么data要使用函数、父组件给子组件传递数据的三种写法、父传子以及传两种以上的值、默认值以及父传子的引用类型
组件的数据、为什么data要使用函数、父组件给子组件传递数据的三种写法、父传子以及传两种以上的值、默认值以及父传子的引用类型
145 0
|
JavaScript 开发者
组件传值-子组件通过事件调用向父组件传值|学习笔记
快速学习组件传值-子组件通过事件调用向父组件传值
109 0
组件传值-子组件通过事件调用向父组件传值|学习笔记
|
JavaScript 开发者 前端开发
组件传值-父组件向子组件传值和 data 与 props 的区别|学习笔记
快速学习组件传值-父组件向子组件传值和 data 与 props 的区别
143 0
组件传值-父组件向子组件传值和 data 与 props 的区别|学习笔记
子组件触发父组件自定义事件(defineEmits):子组件传值给父组件
子组件触发父组件自定义事件(defineEmits):子组件传值给父组件
296 0
|
前端开发
react中父子组件传值详解,如何进行传值校验(父传子,子组件改变父组件的值)
本篇主要给大家介绍react中父子组件传值详解,如何进行传值校验
606 0