Vue躬行记(5)——组件通信
组件之间除了保持独立之外,还需要相互通信,本章将介绍几种通信的方式。
一、直接访问
Vue提供了三个实例属性,可直接访问父组件、子组件和根实例,如下所列。
(1)$parent:父组件。
(2)$root:根实例,如果没有父实例,那么读取的将是自身。
(3)$children:直接子组件,无法获取隔代的子组件,并且不保证组件的顺序,也非响应式。
下面用一个示例来演示它们的用法,首先创建两个父子关系的组件parent和child;接着初始化根实例vm,挂载的<div>元素包含parent组件;最后为根实例和parent组件的数据对象添加name属性。
<div id="container">
<parent></parent>
</div>
<script>
Vue.component("child", {
template: '<p>子组件</p>',
mounted: function() {
this.$parent.name; //"parent"
this.$root.name; //"root"
}
});
Vue.component("parent", {
data: function() {
return {
name: "parent"
};
},
template: '<child></child>'
});
var vm = new Vue({
el: "#container",
data: {
name: "root"
}
});
vm.$children; //[VueComponent]
</script>
当执行vm.$children时,得到的是一个子组件数组。在child组件的mounted钩子中调用了实例的$parent和$root的name属性,其值分别是“parent”和“root”。
大部分情况下,应当避免直接修改组件的内部,因为这么做不仅让父子组件紧密耦合,而且还难以追踪是谁发起的变更。
二、ref和$refs
如果要直接访问子元素或子组件,那么除了使用上文的$children属性之外,还能通过ref特性配合$refs属性实现。
DOM元素或组件可通过声明ref特性来指定一个索引标识符,即注册引用信息。而父组件的$refs属性则记录了声明过ref特性的子元素和子组件,它的值是一个对象,其键就是ref特性的值。下面是一个简单的例子,注册了父组件parent和子组件child,并且为child组件和<input>元素分别声明了ref特性。
Vue.component("child", {
template: '<input ref="txt" />',
mounted: function() {
this.$refs; //{txt: input}
}
});
Vue.component("parent", {
template: '<child ref="child"></child>',
mounted: function() {
this.$refs; //{child: VueComponent}
}
});
在两个组件的mounted钩子中,读取了各自实例的$refs属性。如果要在parent组件中读取child组件的$refs属性,那么可以像下面这样。
this.$refs.child.$refs
注意,$refs不是响应式的,并且在渲染到页面之前是无法访问的,即不能在mounted之前的钩子中使用。
当ref特性与v-for指令配合时,引用的将是一个数组,如下所示。
Vue.component("child", {
data: function() {
return {
names: ["strick", "freedom"]
};
},
template: `<div>
<input v-for="item in names" ref="txt" />
</div>`,
mounted: function() {
this.$refs; //{txt: [input, input]}
}
});
三、自定义事件
组件支持自定义事件,并且能在子组件中触发该事件,从而实现组件之间的通信。假设有两个父子关系的组件parent和child,在child组件上声明了自定义的dot事件,而在<button>元素上添加了click事件,它们接收的事件处理程序都叫add,如下所示。
Vue.component("child", {
template: '<button @click="add">提交</button>',
methods: {
add: function() {
this.$emit("dot", 1, 2);
}
}
});
Vue.component("parent", {
template: '<child @dot="add"></child>',
methods: {
add: function(left, right) {
console.log(left, right); //1 2
}
}
});
Vue提供的实例方法$emit(),它的第一个参数是要触发的事件名称,其余参数都将回传给该事件的处理程序。在子组件child的add()方法中向$emit()传递了三个参数(“dot”、1和2),父组件parent中的add()方法能接收从子组件传递过来的两个数值(1和2)。
注意,自定义的事件名称不要用驼峰的命名方式,因为它没有等价的连字符分隔式的名称,例如下面的addNumber和add-number是两个事件。
<child @addNumber="handle"></child>
<!-- 不同 -->
<child @add-number="handle"></child>
在DOM模板中,由于事件名称会被自动转换为小写,因此像下面这样调用addNumber事件将会失败。但在字符串模板中不会受其影响,依然能调用成功。
this.$emit("addNumber");
1)v-model
组件也支持v-model指令,但需要做些配置。默认情况下,组件的v-model只监听value特性的变化以及input事件。如果要定制,那么可以使用model选项,并且需要在props中添加要监听的特性。下面注册一个checkbox组件,并让它的v-model指令关联模板内的复选框的checked特性和change事件。
Vue.component("checkbox", {
model: {
prop: "checked",
event: "change"
},
props: {
checked: Boolean
},
template: '<input type="checkbox" :checked="checked" @change="dot" />',
methods: {
dot: function(e) {
console.log(e.target.checked);
}
}
});
在将v-model作用于checkbox组件上后(如下所示),每次点击渲染出的复选框,就会在控制台输出当前的选中状态。
<div id="container">
<checkbox v-model="current"></checkbox>
</div>
<script>
var vm = new Vue({
el: "#container",
data: {
current: true
}
});
</script>
Vue躬行记(5)——组件通信的更多相关文章
- Vue躬行记(4)——组件
组件是可复用的Vue实例,拥有属于自己的数据.模板.脚本和样式,可避免繁重的重复性开发.由于组件都是独立的,因此其内部代码不会影响其它组件,但可以包含其它组件,并且相互之间还能通信. 一.注册 在使用 ...
- Vue躬行记(1)——数据绑定
Vue.js的核心是通过基于HTML的模板语法声明式地将数据绑定到DOM结构中,即通过模板将数据显示在页面上,如下所示. <div id="container">{{c ...
- Vue躬行记(2)——指令
Vue不仅内置了各类指令,包括条件渲染.事件处理等,还能注册自定义指令. 一.条件渲染 条件渲染的指令包括v-if.v-else.v-else-if和v-show. 1)v-if 该指令的功能和条件语 ...
- Vue躬行记(3)——样式和表单
Vue对DOM元素的class和style两个特性做了专门的增强,即对CSS类和内联样式做了一层封装,通过v-bind指令来处理它们,而接收的表达式既可以是简单的字符串.对象或数组,也可以是复杂的计算 ...
- Vue躬行记(6)——内容分发
Vue提供了一种内容分发技术,可将父组件中的内容传递给子组件的模板,实现方式参照了Web组件规范草案. 一.插槽 Vue内置了一个<slot>元素,能作为插槽(slot)存在,而插槽内可包 ...
- Vue躬行记(7)——渲染函数和JSX
除了可通过模板创建HTML之外,Vue还提供了渲染函数和JSX,前者的编码自由度很高,后者对于开发过React的人来说会很熟悉.注意,Vue的模板最终都会被编译成渲染函数. 一.渲染函数 虽然在大部分 ...
- Vue躬行记(8)——Vue Router
虽然Vue.js未提供路由功能,但是官方推出了Vue Router(即vue-router库),以插件的形式支持.它与Vue.js深度集成,可快速的创建单页应用(Single Page Applica ...
- Vue躬行记(9)——Vuex
Vuex是一个专为Vue.js设计的状态管理库,适用于多组件共享状态的场景.Vuex能集中式的存储和维护所有组件的状态,并提供相关规则保证状态的独立性.正确性和可预测性,这不仅让调试变得可追踪,还让代 ...
- ES6躬行记(1)——let和const
古语云:“纸上得来终觉浅,绝知此事要躬行”.的确,不管看了多少本书,如果自己不实践,那么就很难领会其中的精髓.自己研读过许多ES6相关的书籍和资料,平时工作中也会用到,但在用到时经常需要上搜索引擎中查 ...
随机推荐
- 品Spring:对@PostConstruct和@PreDestroy注解的处理方法
在bean的实例化过程中,也会用到一系列的相关注解. 如@PostConstruct和@PreDestroy用来标记初始化和销毁方法. 平常更多的是侧重于应用,很少会有人去了解它背后发生的事情. 今天 ...
- 实现一个图片轮播-3d播放效果
前言:最近在做一个音乐播放器,首页要做一个图片轮播,看了bootstrap的carousel插件以及移动端的swipe.js库,都是平面图片轮播的效果,所以自己想着实现类似网易云app里那种3d图片轮 ...
- linux下安装Elasticsearch
一.简单介绍: Elasticsearch提供了近乎实时的数据操作和搜索功能,es集群中所有节点可以一起提供索引和搜索功能,能够相互发现彼此和自动地加入到集群中 二.基础概念: 1.索引: 表征的文档 ...
- JS的加减乘除高精度
//除法函数,用来得到精确的除法结果 //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显.这个函数返回较为精确的除法结果. //调用:accDiv(arg1,arg2) ...
- SpringBootSecurity学习(20)前后端分离版之OAuth2.0刷新token
刷新token 前面的例子和配置都是从头开始申请授权码和令牌,现在来看一下如何根据获取令牌时,回参中的 refresh_token 来刷新令牌.现在在项目中配置的是内存模式的默认用户名密码,第一步先改 ...
- 常见过滤器表格整理,Date,time过滤格式表;常用标签表
一.常用过滤器表 二.date.time过滤器参数表 三.模板常用标签 四.模板标签示例 ①if,for ②url解析标签 ③with缓存标签 ④autoescape的使用 ⑤注释标签(多行注释)一般 ...
- java中的Collection和Collections
Collection是集合类的上级接口,继承他的接口主要有Set和List. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作.
- ef core实现软删除
很多web程序一般的偶不会设计真的物理删除了. 基本上都是在在数据库加一个标记,就得当作已经删除了.同时在查询的时候,过滤已经标记删除的数据 ef core实现软删除是非常简单的,直接在OnModel ...
- 不依赖远程API启动SEER区块链命令行钱包和网页钱包的方法
不依赖远程API启动命令行钱包和网页钱包的方法 在SEER的见证人操作等需要使用命令行钱包的操作中,我们介绍了通过钱包连接远程API来和区块链交互的方法.类似这样: cli_wallet.exe -s ...
- NoticeBoard
本人蒟蒻,请轻点虐. 本人是一个即将退役的蒟蒻. 有些题目和模拟赛用密码保护起来了,请小伙伴们不要猜了,猜不出来的.想知道大佬们如果想查看可以直接找我问,您们高抬贵眼会让我受宠若惊. 哇终于有人找我要 ...