一、组件的注册

1、 全局组件注册

1. 注册基本语法Vue.component

    Vue.component("my_header", {
template: `<div><h1>{{title}}</h1></div>`,
data() {
return {
title: "这是头部"
}
}
});

2. 第一个参数"my_header":组件名称
3. 第二个参数{}:配置信息
4. 配置信息里面必须要有template,它的值是这个组件的html代码
5. 还可以有data、methods等参数,不同的是data不是对象了,而是函数,return返回的值,在template中可以获取并使用
函数详写是 data:function(){}; ES6中可以直接简写 data(){return },其他函数一样可以简写省略 :function
6. Vue里面有的参数,组件里面多数也有,但是有一些参数是组件不能有的,比如el参数,所有组件都是Vue可复用的实例
7. 全局组件,所有app都可以使用

8. demo

<body>
<div id="app">
<my_header></my_header>
</div> <hr> <div id="app2">
<my_header></my_header>
</div> <script>
Vue.component("my_header", {
template: `<div><h1>{{title}}</h1></div>`,
data() {
return {
title: "这是头部"
}
}
});
const app = new Vue({
el: "#app", }); const app2 = new Vue({
el: "#app2"
})
</script>
</body>

2、局部组件注册

1. 在某个app下注册组件,其他app不能使用
2. 基本语句:某个app内使用参数components: {组件名称1: 配置信息1, 组件名称2: 配置信息2}

3. demo

<body>
<div id="app">
<my_com></my_com>
<my_com></my_com>
</div> <script>
// 组件配置信息(对象)
let my_com_config = {
template: `<div><h1>这是局部组件</h1></div>`
};
const app = new Vue({
el: "#app",
components: {
// 组件名称: 配置信息
my_com: my_com_config
} });
</script>
</body>

3、子组件的注册

1. 在某个组件内,也可以使用components注册它的子组件
2. 子组件需要这个组件的template代码内使用

3. demo

<body>
<div id="app">
<my_com></my_com>
</div>
<script>
let child_config = {
template: `<div><h2>我是子组件</h2></div>`
};
let my_com_config = {
// 在组件的代码里面引用它的子组件
template: `<div>
<h1>这是一个组件</h1>
<child></child>
</div>`,
// 在某个组件内部也可以定义的它的子组件
components: {
child: child_config
}
};
const app = new Vue({
el: "#app",
components: {
my_com: my_com_config
}
})
</script>
</body>

二、组件之间的通信

1、父子组件之间的通信

1. 在父组件的配置信息template中引用子组件,给子组件设置一个属性,值是父组件data的值
2. 在子组件中配置一个props参数(数组),里面是那个属性名
3. 然后在子组件的template代码中就可以直接使用这个属性获取到父组件传过来的值

4. demo

<body>
<div id="app">
<my_com></my_com>
</div> <script>
let child_config = {
template: `<div>
<h2>我是子组件</h2>
<p>父亲对我说:{{father_say}}</p>
</div>`,
props: ["father_say"]
};
let my_com_config = {
template: `<div>
<h1>这是一个组件</h1>
<child :father_say="f_say"></child>
</div>`,
components: {
child: child_config
},
data(){
return {
f_say: "好好学习"
}
}
};
const app = new Vue({
el: "#app",
components: {
my_com: my_com_config
}
})
</script>
</body>

2、子父组件之间的通信

1. 子组件向父组件传数据,需要提交一个事件
2. 通过this.$emit("事件名称", "要传的值")提交一个事件给父亲
3. 在父组件中绑定子组件提交过来的事件,创建一个方法处理这个事件
4. data函数接收子组件提交过来的数据

5. demo

<body>
<div id="app">
<my_com></my_com>
</div>
<script>
let child_config = {
// 设置一个click事件,通过click事件向父亲提交一个事件son_say和数据
template: `<div>
<h2>我是一个子组件</h2>
<button @click="my_click">点击向父亲说话</button>
</div>`,
methods: {
my_click() {
// 向父亲说话
// 子组件提交事件
this.$emit("son_say", "我会好好学习的")
}
}
};
let my_com_config = {
// 父组件接收子组件提交的事件son_say,并给这个事件设置一个处理方法my_son_say
// 处理后的数据就可以使用了{{say}}
template: `<div>
<h1>这是一个组件</h1>
<child @son_say="my_son_say"></child>
<p>儿子跟我说:{{say}}</p>
</div>
`,
components:{
child: child_config
},
data(){
return {
say: ""
}
},
// 接收子组件传来的数据data,并赋值给say,在代码中展示出来
methods: {
my_son_say: function (data) {
this.say = data
}
}
};
const app = new Vue({
el: "#app",
components: {
my_com: my_com_config
}
})
</script>
</body>

3、非父子组件之间的通信

1. 定义一个Vue实例作为两个组件之间通信的桥梁
2. 其中一个组件向中间调度器提交事件:Event.$emit("事件名称", data)
3. 另一个组件要监听中间调度器里的事件:Event.$on("事件的名称", function(data)
4. 注意this的问题:函数里面的this是最近的调用者,外面的this才是这个组件

5. demo

<body>
<div id="app">
<ming></ming>
<hong></hong>
</div> <script>
// 这个Vue实例不用传数据,只是用于两个组件之间通信的桥梁
// 一个组件给这个实例提交事件,另一个组件在这个实例里监听这个事件
let other = new Vue(); let ming_config = {
template: `<div>
<h1>我是明哥</h1>
<button @click="my_click">给小红打电话</button>
</div>`,
methods: {
my_click: function() {
// 给小红打电话,说晚上等我,一起嗨
// 两个组件之间没有关系(不是父子),需要通过一个Vue对象进行通信
// 给other对象提交事件
other.$emit("call", "晚上等我,一起嗨")
}
}
};
let hong_config = {
template: `<div>
<h1>我是红姐</h1>
<p>明哥勇猛地跟涐说:{{ming_say}}</p>
</div>`,
data(){
return {
ming_say: ""
}
}, // 钩子方法,组件加载完成后会执行这个方法
mounted(){
// 和$emit是一对的,$emit是提交事件,$on是监听$emit提交的事件
// 第一个参数是监听的事件名称,第二个参数是监听到后要执行的回调函数
let that = this; // 这个this是hong这个组件
other.$on("call", function(data){
// data是ming传过来的数据,里面的this是other的
that.ming_say = data;
})
}
}; const app = new Vue({
el: "#app",
components: {
ming: ming_config,
hong: hong_config
}
})
</script>
</body>

4、总结

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head> <body>
<div id="app">
<my_com></my_com>
<ming></ming>
<hong></hong>
</div> <script>
let other = new Vue();
let child_config = {
template: `<div><p>子组件{{father_say}}</p>
<button @click="my_click">向父组件通信</button></div>
`,
props: ["father_say"],
methods: {
my_click: function () {
this.$emit("son_say", "I will")
}
}
};
let my_com_config = {
template: `<div>
<h1>父组件</h1>
<child :father_say="f_say" @son_say="s_say"></child>
<p>儿子跟我说:{{s_data}}</p>
</div>`,
components: {
child: child_config
},
data() {
return {
f_say: "好好学习",
s_data: ""
}
},
methods: {
s_say(data) {
this.s_data = data
}
}
}; let ming_config = {
template: `
<div>
<p>我是明哥</p>
<button @click="my_click">给小红打电话</button>
</div>
`,
methods: {
my_click() {
other.$emit("call", "晚上一起嗨嗨嗨")
}
}
};
let hong_config = {
template: `<div>
<h1>我是红姐</h1>
<p>明哥勇猛地跟涐说:{{ming_say}}</p>
</div>`,
data() {
return {
"ming_say": ""
}
},
mounted() {
that = this;
other.$on("call", function (data) {
that.ming_say = data
})
}
}; const app = new Vue({
el: "#app",
components: {
my_com: my_com_config,
ming: ming_config,
hong: hong_config,
}
});
</script>
</body> </html>

5、拓展

不同vue实例的组件,通信方法跟非父子方法一致

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head> <body>
<div id="app"> <!--vue实例1-->
<ming></ming>
</div>
<div id="app2"> <!--vue实例2-->
<hong></hong>
</div>
<script>
// 用于组件通信的vue实例
let other = new Vue(); let ming_config = {
template: `
<div>
<p>我是明哥</p>
<button @click="my_click">给小红打电话</button>
</div>
`,
methods: {
my_click() {
other.$emit("call", "晚上一起嗨嗨嗨")
}
}
};
let hong_config = {
template: `<div>
<h1>我是红姐</h1>
<p>明哥勇猛地跟涐说:{{ming_say}}</p>
</div>`,
data() {
return {
"ming_say": ""
}
},
mounted() {
that = this;
other.$on("call", function (data) {
that.ming_say = data
})
}
}; // vue实例1
const app = new Vue({
el: "#app",
components: {
ming: ming_config,
}
}); // vue实例2
const app2 = new Vue({
el: "#app2",
components: {
hong: hong_config,
}
})
</script>
</body> </html>

三、混合和插槽

1、混合

1. 当两个组件复用共用的代码块时
2. 定义公共的代码块
3. 复用语法:mixins: [变量名]

4. demo

<body>
<div id="app">
<com1></com1>
<com2></com2>
</div> <script>
// 定义公用代码
let base = {
data() {
return {
is_show: false
}
},
methods: {
show_text: function(){
this.is_show = true;
},
hide_text(){
this.is_show = false;
}
}
}; let com1 = {
template: `<div>
<button @click="show_text">点击显示文本</button>
<button @click="hide_text">点击隐藏文本</button>
<div v-show="is_show">威猛的明哥出现了</div>
</div>`,
// 继承公用代码
mixins: [base],
// 还可以修改继承过来的代码
data(){
return {
is_show: true
}
}
}; let com2 = {
template: `<div>
<button v-on="{mouseenter: show_text, mouseleave: hide_text}">鼠标移入显示文本,移出隐藏</button>
<div v-show="is_show">威猛的明哥出现了</div>
</div>`,
// 继承代码
mixins: [base]
}; const app = new Vue({
el: "#app",
components: {
com1: com1,
com2: com2,
}
})
</script>
</body>

2、 插槽

命名的插槽

1. 把组件的template定义在html里面
2. 在script中通过id找到这段template
3. template代码内定义slot插槽,并使用name属性区分不同的插槽信息
4. 使用组件的时候通过slot="name",可以给组件添加上不同的内容
5. 生成的组件代码中不会有template标签
6.使用命名插槽时,跟使用标签的属性一样

7. demo

<body>
<div id="app">
<com>
<h3 slot="title">Python</h3>
<p slot="brief">从入门到精通</p>
</com>
<com>
<h3 slot="title">Mysql</h3>
<p slot="brief">从删库到跑路</p>
</com>
</div>
<!--组件的template还可以单独写出来-->
<template id="my_com">
<div>
<h1>这是一个组件</h1>
<!--用slot定义插槽-->
<slot name="title"></slot>
<slot name="brief"></slot>
<hr>
</div>
</template> <script>
let com = {
// 找到template模板
template: "#my_com"
};
const app = new Vue({
el: "#app",
components: {
com: com
}
})
</script>
</body>

不命名的插槽

1. template中的的slot不需要设置name属性
2. 使用组件的时候,直接用slot标签
3.使用不命名插槽时,当做标签使用
4. demo

<body>
<div id="app">
<com>
<slot>Python</slot>
</com>
<com>
<slot>Mysql</slot>
</com>
</div>
<!--组件的template还可以单独写出来-->
<template id="my_com">
<div>
<h1>这是一个组件</h1>
<!--用slot定义插槽-->
<slot></slot>
<hr>
</div>
</template> <script>
let com = {
// 找到template模板
template: "#my_com"
};
const app = new Vue({
el: "#app",
components: {
com: com
}
})
</script>
</body>

Vue组件以及组件之间的通信的更多相关文章

  1. Vue.js组件之同级之间的通信

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. vue的父子组建之间的通信(-),基于props和$emit之间的传递

    对于vue而言,以为其核心思想为前端组建化.所以组建之间的通信必不可少. 相信接触过Angularjs的童鞋都知道angularjs的控制器之间的通信机制. 1:父传子:官方的$broadcast() ...

  3. vue 基础-->进阶 教程(3):组件嵌套、组件之间的通信、路由机制

    前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零开始,教给大家vue的基础.高级操作.组件 ...

  4. vue工程利用pubsub-js实现兄弟组件之间的通信

    前言 项目是基于vue-cli创建的,不会搭建vue开发环境的同学可以百度,这里不再赘述. 步骤流程 vue项目搭建完成之后的文件图如下: 我的上一篇博客已经详细叙述vue工程中各个文件的作用,不清楚 ...

  5. vue组件之间的通信

    1.父组件给子组件传递数据 <body> <div id="app"> 父组件:{{total}} <br> <son-component ...

  6. Vue 组件&组件之间的通信 之 非父子关系组件之间的通信

    Vue中不同的组件,即使不存在父子关系也可以相互通信,我们称为非父子关系通信: 我们需要借助一个空Vue实例,在不同的组件中,使用相同的Vue实例来发送/监听事件,达到数据通信的目的: 实例: 初始加 ...

  7. Vue 组件&组件之间的通信 父子组件的通信

    在Vue的组件内也可以定义组件,这种关系成为父子组件的关系: 如果在一个Vue实例中定义了component-a,然后在component-a中定义了component-b,那他们的关系就是: Vue ...

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

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

  9. 【Vue课堂】Vue.js 父子组件之间通信的十种方式

    这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...

随机推荐

  1. 第九课 表单及表单控件 html5学习4

    表单有由表单域.提示文本.表单3部分构成 一.表单控件 input 控件 1.<input />单标签2.input属性: 可以通过type属性变换形状 value默认值 name名称 c ...

  2. vue element-ui 2.3.4版本 input number值为0时 显示不出来

    解决:官方修复了这个bug.升级element-ui为2.3.5版本就好了

  3. 【Dojo 1.x】笔记4 文字动画效果

    这个笔记,仅仅演示dojo/fx模块的slideTo()方法的简单使用. 有关该模块的用法,见API:有关Dojo的动画.效果,见页面 效果  和  动画 1. 页面组织 html部分同笔记3,js部 ...

  4. Windows7 64位环境6sv2.1大气传输模型修改源码添加国产高分卫星GF-1 GF-2光谱响应支持

    下面开始添加国产卫星光谱响应的支持: 以下主要参考文章“6S大气传输模型修改源码添加.自定义卫星光谱响应(以HJ-1B CCD为例)”网址:http://blog.csdn.net/sam92/art ...

  5. iOS----------弹窗动画

    - (void)animationAlert:(UIView *)view { CAKeyframeAnimation *popAnimation = [CAKeyframeAnimation ani ...

  6. Android: 在native中访问assets全解析

    本文总结在Android Native C++开发中访问APK中的assets资源的方法 在CMake中添加相关NDK LIB的 依赖 因为我们接下来用到的一些函数实现在NDK库libandroid. ...

  7. android 记一次富文本加载之路

    文章链接:https://mp.weixin.qq.com/s/69TRkmFL1aNuSqfw4ULMJw 项目中经常涉及到富文本的加载,后台管理端编辑器生成的一段html 代码要渲染到移动端上面, ...

  8. Spark dataframe【KV格式】模拟实现Map操作

    代码实现 // rdd转化为df[kv格式]val df = sqlContext.createDataFrame(check_data_type, structType) .select(" ...

  9. python实例二

    https://www.cnblogs.com/evablogs/p/6754974.html 题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于 ...

  10. hashCode()方法对HashMap的性能影响

    HashMap的put()方法会比较key的hash值,key的hash值获取方式如下: //HashMap的put方法 public V put(K key, V value) { return p ...