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 boot 官网学习笔记 - Spring DevTools 介绍
想要使用devtools支持,只需使用dependencies将模块依赖关系添加到你的构建中 运行打包的应用程序时,开发人员工具会自动禁用.如果你通过 java -jar或者其他特殊的类加载器进行启动 ...
- JDK 自带的性能监控工具
JDK安装完后,其内置了许多的监控工具,常用的有jvisualvm,jconsole,jps,jmap,jinfo,jstat,jstack,这些命令都在jdk安装的bin目录下: 1.jvisual ...
- .Net Core自动化部署系列(二):使用Jenkins打造镜像发布流水线
一.简介 之前写过一篇关于Jenkins搭配GitLab实现.net core项目自动发布到IIS的博文,比较简单哈,只是个Demo.本篇我们将会使用Jenkins搭配GitLab实现镜像的自动打包和 ...
- Transactional事务提交后触发异步方法
一.问题复现 1.场景 2个service方法, 方法A中调用方法B. 方法A 是核心业务方法,涉及多张表数据变更,为了保持数据一致,用spring事务注解:@Transactional(rollba ...
- Android NDK(二) CMake构建工具进行NDK开发
本文目录 一Androidstudio中需要的插件 二项目配置 ①build.gardle配置 ②CMakeLists.txt ③Android和Cpp的代码 ④so文件生成 ⑤so文件的位置 一.A ...
- ELK日志分析系统(3)-logstash数据处理
1. 概述 logspout收集数据以后,就会把数据发送给logstash进行处理,本文主要讲解logstash的input, filter, output处理 2. input 数据的输入处理 支持 ...
- Spring Boot WebFlux 增删改查完整实战 demo
03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello .这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD ...
- OEMCC 13.3 主机agent部署问题排查
部署安装 具体的安装过程可参考,Alfred Zhao的文章,非常详细,文章是OEMCC13.2的部署过程.OEMCC13.3没有太大差别. https://www.cnblogs.com/jyzha ...
- Web性能优化:雅虎35条
对web性能优化,一直知道是个很重要的方面,平时有注意到,但是对于雅虎35条是第一次听说,查了一下,发现平时都有用过,只是没有总结到一块,今天就总结一下吧. 雅虎35条: 1.[内容]尽量减少HTTP ...
- 【TencentOS tiny】深度源码分析(1)——task
任务的基本概念 从系统的角度看,任务是竞争系统资源的最小运行单元.TencentOS tiny是一个支持多任务的操作系统,任务可以使用或等待CPU.使用内存空间等系统资源,并独立于其它任务运行,理论上 ...