VUE 自定义组件之间的相互通信

时间:2022-09-04 23:15:38

一、自定义组件

1、全局自定义组件

我们在var vm = new Vue({});的上面并列写上Vue.component('自定义组件名',{组件对象});来完成全局自定义组件的声明。示例代码如下:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'<h3>全局自定义组件</h3>'
});
var vm = new Vue({
el:'#box'
});
}
</script>
<div id="box">
<my-aaa></my-aaa>
</div>

VUE 自定义组件之间的相互通信

即我们在该自定义组件的组件对象的template属性值当中设置该组件标签即将被替换成的html标签字符串。即我们使用<my-aaa></my-aaa>,则相当于是<h3>全局自定义组件</h3>

2、局部自定义组件

我们在var vm = new Vue({});这个实例对象内部的属性components:{'自定义组件名':{该组件对象}}的对象内部声明局部自定义组件。 示例代码如下所示:

<script>
window.onload = function(){
var vm = new Vue({
el:'#box',
components:{
'my-bbb':{
template:'<h3>局部自定义组件</h3>'
}
}
});
};
</script>
<div id="box">
<my-bbb></my-bbb>
</div>

VUE 自定义组件之间的相互通信

全局自定义组件与局部自定义组件的用法大致都相似,下面主要以全局自定义组件为例来进行详细的说明。

3、自定义组件的数据属性

我们可以在自定义组件的组件对象的data属性当中放置该组件的数据属性。但data必须为函数的形式,并且该函数必须返回一个对象,我们在该返回的对象当中放置该组件的数据。示例代码如下所示:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'<h3>{{msg}}</h3>',
data:function(){
return {
msg:'哈哈!'
};
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa></my-aaa>
</div>

VUE 自定义组件之间的相互通信

4、自定义组件的事件方法

我们可以在自定义组件对象的methods当中定义该组件的事件方法,示例代码如下所示:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'<h3 @click="change">{{msg}}</h3>',
data:function(){
return {
msg:'哈哈!'
};
},
methods:{
change:function(){
this.msg = 'change';
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa></my-aaa>
</div>

5、template属性值配合模板标签使用

如果我们自定义组件对象的template属性值当中的html标签比较多时,可以配合模板标签一起使用,把这些成堆的标签单独放在一起。示例代码如下所示:

  <script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc',
data:function(){
return {
msg:'哈哈!',
arr:['apple','banana','pear','tomato']
};
},
methods:{
change:function(){
this.msg = 'change';
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa></my-aaa>
</div>
<template id="ccc">
<div>
<h3 @click="change">{{msg}}</h3>
<ul>
<li v-for="(val,index) in arr">
{{index}}----{{val}}
</li>
</ul>
</div>
</template>

显示结果如下所示,当点'哈哈!'时,会变为change

VUE 自定义组件之间的相互通信

vue1.x的版本过渡到vue2.0的版本的变化之一为,每个组件模板不再支持片段代码,即在vue2.0当中的组件模板必须有一个根元素来包裹住所有的代码。即当上述代码更改为

    <template id="ccc">
<h3 @click="change">{{msg}}</h3>
<ul>
<li v-for="(val,index) in arr">
{{index}}----{{val}}
</li>
</ul>
</template>

则会报错component template should contain exactly one root element.

6、动态组件

我们在页面上放置一个固定名称的组件标签作为动态组件,如<component :is="a"></component>,其中a来自于vue实例对象的data属性,通过给a赋予不同的自定义组件名,可以控制该动态组件当前的状态。示例代码如下所示:

<script>
window.onload = function(){
var vm = new Vue({
el:'#box',
data:{
a:'my-aaa'
},
components:{
'my-aaa':{
template:'<h3>我是组件aaa</h3>'
},
'my-bbb':{
template:'<h3>我是组件bbb</h3>'
}
}
});
};
</script>
<div id="box">
<button @click="a='my-bbb'">变为组件bbb</button>
<button @click="a='my-aaa'">变为组件aaa</button>
<component :is="a"></component>
</div>

VUE 自定义组件之间的相互通信

当页面完成加载之后,a的初始值为'my-aaa',故此时页面上的动态组件代表<my-aaa></my-aaa>,当我们点击变为组件bbb按钮时,a被赋值,此时页面的动态组件变为<my-bbb></my-bbb>。但当点击变为组件aaa按钮时,a又被重新赋值,此时页面上的动态组件变回<my-aaa></my-aaa>

7、<slot>标签的使用

slot为位置、槽口的意思,作用为占位置。当自定义组件当中有一些特定的布局,不想被该组件当中的template的代码完全覆盖时,可以采用slot这个标签,该标签可以用来向组件内部插入一些内容,即我们在定义组件的时候留几个口子,由用户来决定插入的内容。单个插槽的示例代码如下所示:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc'
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa>
<ul>
<li>aaaa</li>
<li>bbbb</li>
</ul>
</my-aaa>
</div>
<template id="ccc">
<div>
<slot>只有在没有要分发的内容时才会显示</slot>
<h3>自定义组件aaa</h3>
</div>
</template>

VUE 自定义组件之间的相互通信

当我们在使用<my-aaa></my-aaa>组件标签时,内部没有其他内容,则slot标签对当中的文字内容会正常显示,但当该组件标签对当中有html代码时,则slot标签对当中的文字部分不会显示,并且在默认情况下,一对slot标签对即代表该组件标签对当中全部的html代码段。

vue2.0当中,重名的插槽被移除,即同一模板当中重名的slot已经被弃用,当一个插槽已经被渲染过了,那么就不能在同一模板的其他地方被再次渲染,如果要在不同位置渲染同一内容,可以用prop来传递。

具名插槽的示例代码如下所示:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc'
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa>
<ul slot="ul-slot1">
<li>aaaa</li>
<li>bbbb</li>
</ul>
<ul slot="ul-slot2">
<li>cccc</li>
<li>dddd</li>
</ul>
</my-aaa>
</div>
<template id="ccc">
<div>
<slot name="ul-slot2"></slot>
<h3>自定义组件aaa</h3>
<slot name="ul-slot1"></slot>
</div>
</template>

VUE 自定义组件之间的相互通信

二、组件间的通信

1、父子组件

我们可以在自定义组件对象当中的components属性当中定义该组件对应的子组件。示例代码如下所示:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc',
components:{
'my-bbb':{
template:'<h4>{{msg}}</h4>',
data:function(){
return {
msg:'子组件bbb'
};
}
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa></my-aaa>
</div>
<template id="ccc">
<div>
<h3>自定义组件aaa</h3>
<my-bbb></my-bbb>
</div>
</template>

VUE 自定义组件之间的相互通信

2、子组件获取其父组件的数据

在默认情况下,子组件是无法访问到其父组件当中的数据的。如果希望子组件能获取到父组件的data数据,使其能在子组件的templatehtml代码当中直接使用。则我们可以在给子组件的标签绑定上一个属性m(该属性名可以任取),将父级的数据挂载到子组件的m属性值上。然后我们在子组件对应的组件对象当中使用props:['m']来得到该m属性值,之后的可以把m当作是来自于子组件对象当中的data,即在子组件的template当中可以用{{m}}来获取,在methods当中可以用this.m来进行获取。示例代码如下所示:

<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc',
data:function(){
return {
msg1:'嘻嘻!',
msg2:'哈哈!',
msg3:'呵呵!'
};
},
components:{
'my-bbb':{
template:'#ddd',
props:['m1','m2','myM3']
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
<div id="box">
<my-aaa></my-aaa>
</div>
<template id="ccc">
<div>
<h3>自定义组件aaa</h3>
<my-bbb :m1="msg1" :m2="msg2" :my-m3="msg3"></my-bbb>
</div>
</template>
<template id="ddd">
<div>
<h1>{{m1}}</h1>
<h2>{{m2}}</h2>
<h3>{{myM3}}</h3>
</div>
</template>

VUE 自定义组件之间的相互通信

自定义属性名为my-m3,使用-来进行连接,则我们在props当中一律改为对应的驼峰命名下的myM3

在上述这种方式当中,子组件可以获取到父组件的数据,但是不允许直接对获取到的数据进行赋值操作。想要对获取到的数据进行赋值操作,同时达到更改父组件当中数据的目的,可以采取解决办法是,我们可以把父组件当中的数据包裹在一个对象当中来进行传递。示例代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="bower_components/vue/dist/vue.js"></script>
<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc',
data:function(){
return {
msg1:{
a:'呵呵!'
},
};
},
components:{
'my-bbb':{
template:'#ddd',
props:['m1'],
methods:{
change:function(){
this.m1.a = '哈哈!'
}
}
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
</head>
<body>
<div id="box">
<my-aaa></my-aaa>
</div>
<template id="ccc">
<div>
<h3>{{msg1.a}}</h3>
<my-bbb :m1="msg1"></my-bbb>
</div>
</template>
<template id="ddd">
<div>
<button @click="change()">change</button>
<h3>{{m1.a}}</h3>
</div>
</template>
</body>
</html>

VUE 自定义组件之间的相互通信

当点击按钮之后,变为:

VUE 自定义组件之间的相互通信

3、父组件获取其子组件的数据

父组件想要获取子组件的数据,一般都是等子组件主动把自己的数据发送给父级。我们可以给子组件的某个dom元素绑定一个事件,该事件函数体为this.$emit('自定义事件名',子组件的数据)。即这个可以触发子组件身上的事件。示例代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="bower_components/vue/dist/vue.js"></script>
<script>
window.onload = function(){
Vue.component('my-aaa',{
template:'#ccc',
data:function(){
return {
msg1:'父组件的数据'
};
},
methods:{
get:function(data){
this.msg1 = data;
}
},
components:{
'my-bbb':{
template:'#ddd',
data:function(){
return {
msg2:'子组件的数据'
};
},
methods:{
send:function(){
this.$emit('sendtofahter',this.msg2);
}
}
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
</head>
<body>
<div id="box">
<my-aaa></my-aaa>
</div>
<template id="ccc">
<div>
<h3>{{msg1}}</h3>
<my-bbb @sendtofahter="get"></my-bbb>
</div>
</template>
<template id="ddd">
<div>
<button @click="send()">send-to-father</button>
<h3>{{msg2}}</h3>
</div>
</template>
</body>
</html>

VUE 自定义组件之间的相互通信

当点击按钮之后,结果变为:

VUE 自定义组件之间的相互通信

4、使用单一事件来管理组件间的通信

使用下面介绍的单一事件管理组件间通信可以替代之前介绍的两种父子组件之间的通信方式,还可以实现任意两个组件(如兄弟组件)之间的数据通信。

我们可以先在var vm = new Vue({});并列的上方准备一个空的vue实例对象,如var Event = new Vue();。假设我们要实现A组件发送数据给B组件,我们可以给A组件绑定一个事件,该事件函数体为Event.$emit('自定义事件名',A组件上的数据);,然后我们再在B组件的组件对象上的mounted(该组件挂载完成之后触发执行的函数)函数体上写上Event.$on('对应的自定义事件名',function(data){});其中的data即代表接收到的来自A组件上的数据。示例代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="bower_components/vue/dist/vue.js"></script>
<script>
window.onload = function(){
var Event = new Vue();
Vue.component('my-aaa',{
template:'#ccc',
data:function(){
return {
msg1:'父组件的数据'
};
},
mounted:function(){
Event.$on('sendtofahter',function(data){
this.msg1 = data;
}.bind(this));
},
components:{
'my-bbb':{
template:'#ddd',
data:function(){
return {
msg2:'子组件的数据'
};
},
methods:{
send:function(){
Event.$emit('sendtofahter',this.msg2);
}
}
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
</head>
<body>
<div id="box">
<my-aaa></my-aaa>
</div>
<template id="ccc">
<div>
<h3>{{msg1}}</h3>
<my-bbb></my-bbb>
</div>
</template>
<template id="ddd">
<div>
<button @click="send()">send-to-father</button>
<h3>{{msg2}}</h3>
</div>
</template>
</body>
</html>

上述代码可以实现与父组件获取其子组件当中的数据的示例代码一样的效果。下面给出两个兄弟组件之间通信的示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="bower_components/vue/dist/vue.js"></script>
<script>
window.onload = function(){
var Event = new Vue();
Vue.component('my-aaa',{
template:'#ccc',
data:function(){
return {
msg1:'兄弟组件aaa的数据'
};
},
mounted:function(){
Event.$on('sendtobrother',function(data){
this.msg1 = data;
}.bind(this));
}
});
Vue.component('my-bbb',{
template:'#ddd',
data:function(){
return {
msg2:'兄弟组件bbb的数据'
};
},
methods:{
send:function(){
Event.$emit('sendtobrother',this.msg2);
}
}
});
var vm = new Vue({
el:'#box'
});
};
</script>
</head>
<body>
<div id="box">
<my-aaa></my-aaa>
<my-bbb></my-bbb>
</div>
<template id="ccc">
<div>
<h3>{{msg1}}</h3>
</div>
</template>
<template id="ddd">
<div>
<button @click="send()">send-to-brother</button>
<h3>{{msg2}}</h3>
</div>
</template>
</body>
</html>

VUE 自定义组件之间的相互通信

当我们点击按钮之后,显示的结果为:

VUE 自定义组件之间的相互通信

VUE 自定义组件之间的相互通信的更多相关文章

  1. Vue父子组件之间的相互通信

    组件是Vue知识体系中最重要的一部分之一,父子组件由于作用域的不同,无法直接对对方的数据进行操作.它们之间的数据传递都是通过中间介质进行的,父组件给子组件传值是通过props属性,而子组件给父组件传值 ...

  2. vue中组件之间的相互调用,及通用后台管理系统左侧菜单树的迭代生成

    由于本人近期开始学习使用vue搭建一个后端管理系统的前端项目,在左侧生成菜单树的时候遇到了一些问题.在这里记录下 分析:由于本人设定的菜单可以使多级结构,直接使用vue的v-for 遍历并不是很方便. ...

  3. 【转】vue父子组件之间的通信

    vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...

  4. VUE 父子组件之间通信传值 props和 &dollar;emit

    1.父组件传值给子组件 $props,子组件传值给父组件 $emit 父组件          <div id="app" >               <tr ...

  5. vue&period;js 组件之间传递数据

    前言 组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.如何传递数据也成了组件的重要知识点之一. 组件 组件与组件之间,还存在着不同的关 ...

  6. Vue自定义组件实现v-model指令

    Tips: 本文所描述的Vue均默认是Vue2版本 在我们初次接触Vue的时候,一定会了解到一个语法糖,那就是v-model指令,它带给我们的第一印象就是它可以实现双向绑定 那么,什么是双向绑定?通俗 ...

  7. 【整理】解决vue不相关组件之间的数据传递----vuex的学习笔记,解决报错this&period;&dollar;store&period;commit is not a function

    解决vue不相关组件之间的数据传递----vuex的学习笔记,解决报错this.$store.commit is not a function https://www.cnblogs.com/jaso ...

  8. Vue 兄弟组件之间传递数值

    Vue 兄弟组件之间传值 创建一个公用文件夹,在文件夹中设置一个事件处理中心,即 然后在需要设置值的组件中引入该事件处理中心 import Hub from '../../common/eventHu ...

  9. vue自定义组件(vue&period;use&lpar;&rpar;,install)&plus;全局组件&plus;局部组件

    相信大家都用过element-ui.mintui.iview等诸如此类的组件库,具体用法请参考:https://www.cnblogs.com/wangtong111/p/11522520.html ...

随机推荐

  1. Windows下用tree命令生成目录树

    有时候我们想为某个目录制作一个文档结构图,在Windows上,我们知道是使用tree命令. 但是,默认情况下tree只显示子目录名,而不显示子目录里的文件名,需要加上/F参数才能显示完整的文件名.   ...

  2. jsp页面输入小写金额转大写

    <script> function chineseNumber(num){ if (isNaN(num) || num > Math.pow(10, 12)) return &quo ...

  3. SVN客户端常用命令

    1. 将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如: cd /home/www  #进入准备获取的项目路径 svn checkout svn: ...

  4. php安装json模块

    centOS上因为看php源码中没有json模块,于是采用pecl自动编译安装:# yum install php-devel# yum install php-pear# yum install g ...

  5. SQL 调试:无法启动 T-SQL 调试。未能附加到 SQL Server 进程

    将 Windows 登录帐户添加为 sysadmin 已经具有 sysadmin 特权的用户必须执行以下命令: sp_addsrvrolemember 'Domain\Name', 'sysadmin ...

  6. 1015&colon; &lbrack;JSOI2008&rsqb;星球大战starwar - BZOJ

    Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...

  7. C&num;&lowbar;dropdownlist&lowbar;1

    关于ASP.net MVC 中DropDownList绑定与提交数据   在做 ASP.net MVC项目中,数据绑定也是很关键的,现在以个人经验与大家交流下 ASP.net MVC 中DropDow ...

  8. UVA 10905 Children&&num;39&semi;s Game &lpar;贪心&rpar;

    Children's Game Problem Description There are lots of number games for children. These games are pre ...

  9. 【原创】单片系统SoC

    人们根据需要把一些功能模块(蓝牙.GPRS.TCP/IP通信模块等等)与MCU进行有机的结合,制造出集成度更高的系统级的芯片.     SoC是System on Chip的缩写,直译是“芯片级系统” ...

  10. Poj2386 Lake Counting (DFS)

    Lake Counting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 49414   Accepted: 24273 D ...