博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
组件(7) —— 通信
阅读量:5985 次
发布时间:2019-06-20

本文共 6741 字,大约阅读时间需要 22 分钟。

在表单输入组件节点上使用v-model

el: "#app-1",data() {    return {        text: ''    }},components: {    'component-1': {        template: ''    }}

直接在表单组件的标签上使用v-model,没有任何作用。

clipboard.png

首先看看v-model如何在原生input元素上工作的。

data() {    return {        text: ''    }}

上面的标签为v-model指令的完全形式,v-model是下面代码的语法糖,通过事件处理函数与数据绑定完成双向绑定。需要注意的是事件处理函数的内容是默认的。

v-bind:value="somedata"v-on:input="somedata = $event.target.value"

clipboard.png

对比原生input元素,可以得出,输入组件上的v-model也是由事件处理与数据绑定组成。

data() {    return {        text_1: '',        text_2: ''    }}//......'component-2-1': {    template: '',    props: ['value'],    methods: {        eventHandler: function (event) {            this.$emit('input', event.target.value)        }    }}

输入组件模板中,监听每次输入,每次输入时就触发input自定义事件,并以元素的值作为该事件负载;在父组件上监听这个input自定义事件,触发该事件时执行默认的方法,将事件负载传递给父组件自己的data;这里要关注默认的处理方法somedata = arguments[0],这个arguments[0]即是自定义事件的负载;若父组件数据修改了,会通过:value=props下发给子组件,因此子组件需要定义一个Propsvalue,子组件还要将value绑定在自己的input元素上,向其他使用该组件的地方传递变化。

变化的过程: 输入 - 子组件触发自定义事件 - 父组件监听到事件 - 根据负载修改数据 - 将修改数据下发给组件 - 引起其他位置的变化

对于子组件模板上,绑定自己原生input事件的方式,以上使用一个eventHandler事件处理方法。我们也可以在没有参数的v-on上绑定一个事件对象(在computed中定义),如下:

'component-2-2': {    template: '',    props: ['value'],    computed: {        eventDict: function () {            return { input: event => this.$emit('input', event.target.value) }        }    }}

clipboard.png

子组件props.value用来传递变化给其他使用该输入组件的地方,如果没有它,只是单向的绑定。

使用$attrs、$listeners在多层次的组件结构中实现通信

如果在多层组件结构中,只是单纯的数据通信,那么使用$attrs、$listeners是最方便的。

在使用它们之前,先来看个选项inheritAttrs

data(){    return {        foo:'foo',        bar:'bar'    }},components:{    'component-3':{        props:['foo'],        template:'{
{foo}}
', }}

在父组件中,我们绑定了两个Props,foobar,下发数据给子组件时,子组件只定义了foobar没地方传,组件渲染时它就留在了子组件的根元素上。

图片描述

如果我们不想在子组件根元素上保留这个属性,我们可以设置选项inheritAttrs为false。

inheritAttrs:false

图片描述

使用$attrs$listeners

new Vue({    el: '#app-4',    data() {        return {            firstData: 'firstData',            secondData: 'secondData',            thirdData: 'thirdData',            fourthData: 'fourthData'        }    },    methods: {        firstEvent: function () {            console.log('第一层组件触发的事件')        },        secondEvent: function () {            console.log('第二层组件触发的事件')        },        thirdEvent:function(){            console.log('第三层组件触发的事件')        },        fourthEvent:function(){            console.log('第四层组件触发的事件')        }    },    components: {        'first': {            'props': ['firstData'],            template: '

{
{firstData}}

', mounted() { this.$emit('first'); }, inheritAttrs:false, components:{ 'second':{ 'props':['secondData'], template:'

{
{secondData}}

', mounted() { this.$emit('second'); }, methods: { eventHandler(payload){ $(this.$el).find('h2').after('' + payload + '') } }, inheritAttrs:false, components:{ 'third':{ 'props':['thirdData'], template:'

{
{thirdData}}

', mounted() { this.$emit('third'); }, methods: { eventHandler(payload){ $(this.$el).find('h3').after('' + payload + '') } }, inheritAttrs:false, components:{ 'fourth':{ 'props':['fourthData'], template:'

{
{fourthData}}

', mounted() { this.$emit('fourth','负载在第四层上事件上的数据'); } } } } } } } } }})

clipboard.png

$listeners上保存着所有低层组件触发的自定义事件,使用v-on="$listeners"将本层及以下层触发的事件传递给上一层,上一层中可以监听$listeners对象中所有的事件。整个过程即一个事件广播的形态。

clipboard.png

$attrs上保存着所有未被下发的上层组件中的数据,各层组件使用v-bind="$attrs"向下层组件传递下发的数据。$attrs好像一块数据蛋糕,被高层组件拿走的部分,低层组件无法再使用。配合inheritAttrs:false可以使那些用不到的数据属性,不会保留在组件的根元素上。

v-on="$listeners"向上广播事件,
v-bind="$attrs"向下下发数据

父子组件的引用

示例结果是这样:

clipboard.png

使用$parent和$refs在父子组件间传递数据
{
{message}}
{
{message}}
new Vue({    el:'#app-2',    data:{        message:''    },    methods:{        handle(){            this.$refs.child.message = this.message        }    },    components:{        'component-21':{            template:'',            data(){                return {message:''}            },            methods:{                handle(){                    this.$parent.message = this.message                 }            }        }    },    })

在子组件中可以使用$parent获取父组件数据,也可以修改它。

在父组件中可以使用$refs获取子组件数据,也可以修改,之前必须在视图节点上给子组件取一个名字如:ref="child"(见)。
就靠这两个属性,进行父子组件间的通信。

事件管理器Bus

通过该方法不仅可在任意组件内进行通信。创建一个全局的实例bus管理事件触发和监听

var bus = new Vue()

之后创建表单输入组件,在其输入事件中触发bus上的message事件,在created钩子中监听该事件。

Vue.component('component-a', {    template:``,    data(){        return {message:''}    },    methods:{        emitEvent(){            bus.$emit('message',this.message)        }    },    created(){        var _this = this        bus.$on('message', c_msg => {            _this.message = c_msg        })    }})Vue.component('component-b', {    template:``,    data(){        return {message:''}    },    methods:{        emitEvent(){            bus.$emit('message',this.message)        }    },    created(){        var _this = this        bus.$on('message', c_msg => {            _this.message = c_msg        })    }    })new Vue({    data:{        message:''    },    methods:{        emitEvent(){            bus.$emit('message',this.message)        }    },    created(){        var _this = this        bus.$on('message', c_msg => {            _this.message = c_msg        })    }}).$mount('#app-1')
使用全局View实例管理事件,在任意组件间传递数据
{
{message}}
{
{message}}
{
{message}}

当一个组件输入时触发bus上的事件,所有组件都会监听到,并使用事件上的负载数据。

clipboard.png

转载地址:http://bxylx.baihongyu.com/

你可能感兴趣的文章
[对抗训练]“中国菜刀”安装,20180222
查看>>
关于进程和线程的问题
查看>>
PHP中foreach用法详细讲解
查看>>
PHP如何进阶,提升自己
查看>>
谈一谈URL
查看>>
Create Custom Instruments
查看>>
C#写文本日志帮助类(支持多线程)
查看>>
ThreadPool.QueueUserWorkItem的用法
查看>>
【小游戏】C++手工制作贪吃蛇
查看>>
poj 1050 To the Max
查看>>
SQL Server三种表连接原理
查看>>
Linux修改时间
查看>>
centos6.8服务器配置之vsftpd配置
查看>>
hibernate面试题
查看>>
第二阶段冲刺第九天
查看>>
centos6.6安装hadoop-2.5.0(一、本地模式安装)
查看>>
回收站,恢复
查看>>
Android单元测试之一:基本概念
查看>>
jsp多模块相同数据提交到后台之数据处理
查看>>
lua 的一些常用概念
查看>>