Vuejs - 组件式开发
初识组件
组件(Component)绝对是 Vue 最强大的功能之一。它可以扩展HTML元素,封装可复用代码。从较高层面讲,可以理解组件为自定义的HTML元素,Vue 的编译器为它添加了特殊强大的功能。所有的 Vue 组件同时也都是 Vue 的实例,因此可以接受相同的选项对象(除了一些特有的选项)并提供相同的生命周期函数。
再来回顾下 你也许不知道的Vuejs - 花式渲染目标元素 中的代码:
1 |
<div id="app1"> |
1 |
Vue.component("helloworld", {
|
上面通过 Vue.component 注册了一个全局组件,然后在 div#app 元素内通过 <helloworld/> 标签直接使用。可以看出,这里就是相当于自定义了一个 HTML 元素 helloworld,它的功能就是输出一个内容为 msg 的 h1 标签。这就是一个基本全局组件的定义方式,当然你也可以注册为局部组件:
1 |
var app2 = new Vue({
|
无论是全局或者局部注册组件,它跟上一篇中的指令注册是非常相似的。局部注册组件就是在创建 Vue 实例的时候添加一个 components 对象属性,它的键值对就是一个自定义组件,键是组件名,值是创建组建的配置对象参数。当然也可以将组件定义放到单独的文件,然后通过引入的方式,然后添加到components属性中,这个在单文件组件中会具体讲到。
组件间通信
既然说到组件,就不得不说组件间通信了,实际开发中,我们经常需要在不同组件间传递/共享数据,所以实现组件间通信是非常重要的。
组件间关系可以总结为 父子组件 和 非父子组件,自然通信方式也就是这两种了。
父子组件间通信

如上图,在 Vue 中,父子组件的关系可以总结为 props向下传递,事件向上传递。也就是父组件通过 prop 给子组件下发数据,子组件通过 $emit 事件, 给父组件发送数据。先来看个例子:
1 |
<div id="app3"> |
1 |
Vue.component('com-input', {
|
原理解析:上面的代码中,先通过
Vue.component定义了com-input组件,给它添加了props属性,用来接收父级通过属性传递的属性数据text,这里text是个对象,含有type - 属性值类型和default - 默认值两个属性。当然props也可以为所有从父级接受的属性数组,有关props基础知识请直接阅读 官方文档。然后将初始值赋值给了 data 中的msg,该子组件的模板是个input,通过v-model实现input的值和msg的双向绑定,当input值变化时,通过this.$emit('change', this.msg),发出change事件,同时将当前值作为监听器回调参数,这样父级组件就可以通过v-on:change来监听此事件,获取修改后的值,执行相关操作了。
虽然这段代码同时实现了上述图片中的 父 -> 子 和 子 -> 父 通信流程,但是代码还是比较繁琐的,单纯实现单个数据的循环传递,就需要父子组件同时监听改变事件,执行监听回调函数,是不是太麻烦了。要是能直接修改 props 中的 text 值就好了,实践证明,这是不行的,因为直接修改,会报下面错误(注意只有引入 vue.js 文件才会出现,因为 vue.min.js 文件移除了 [Vue warn] 错误提示功能):
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “text”
这个问题,Vue 作者早就想到了,那就是使用 .sync 修饰符。早在 1.x 版本中此功能是一直存在的,但是作者认为它破坏了 单向数据流 的原则,所以 2.0 发布后,就移除了该修饰符,但是后来发现在实际开发中,有很多相关需求, 于是在 2.3.0+ 版本后,又重新引入了 .sync 修饰符,不过内部实现是跟 1.x 版本有区别的,它并没有破坏 单向数据流 原则,实际上内部就是帮我们实现了父级组件监听和修改相关属性值的操作。
使用 .sync 修改后的代码如下:
1 |
<div id="app4"> |
1 |
Vue.component('com-input2', {
|
这次我们只是将子组件的 $emit 事件名修改为 update:text,并删除了父级组件 v-on:change 监听和相关监听回调,并在模板中 v-bind:text 后面添加了 .sync 修饰符,这样就是实现了相同的功能,代码确实精简了很多。实际上 Vue 在编译含有 .sync 修饰符的 v-bind 指令时,会自动实现监听 update 事件的相关代码,也就是:
1 |
<com-input2 v-bind:text.sync="text"/> |
会被扩展为:
1 |
<com-input2 v-bind:text="text" v-on:update="val => text = val"/> |
注意:
val => text = val是箭头函数,关于箭头函数的介绍可以看这里:箭头函数
这样一解析就很好理解了,全部是我们上一节讲到的内容。
非父子组件间通信
如果是两个非父子组件,并且有共同的父级组件,那么它拆解为 子 -> 父 -> 子 的过程,这个就完全可以使用 父子组件间通信 方法实现。如果是多个组件或者不同父组件的组件间通信,这时我们可以借助创建空的 Vue 实例作为事件总线,通过 发布订阅模式 进行数据传递。 代码如下:
1 |
<div id="app5"> |
1 |
var bus = new Vue() |
熟悉 发布订阅模式 的同学,应该很容易理解上面这段代码,创建的全局空 Vue 实例 bus 就是用来充当中央事件总线,所有的事件都经过它来触发和传播。
思路解析:在组件
com-a中,当input值发生改变时,通过bus.$emit('a-change', this.msg)来触发修改事件,并将其更新后的值做为参数传递,组件com-b通过bus.$on('a-change', xxx)来监听,进行值更新操作,组件com-b也是相同原理。
当然在复杂情况下,我们应该考虑使用专门的 状态管理模式,比如 vuex,这个将在后续的文章中讲到。
动态组件
Vue 中还提供了 component 元素,允许我们在实际开发中,通过修改其 is 属性值,来动态切换组件。这个在某些应用场景非常实用,笔者曾经有个需求就是,需要根据参数 type来绘制不同类型的图表,而我的所有图表类型都已经装成了一个独立的组件,所以我只需要依据此特性,通过参数 type 来动态修改元素 component 的属性 is 为对应的组件名称即可。
下面来看示例代码:
1 |
<div id="app6"> |
1 |
var app6 = new Vue({
|
运行上面代码,点击改变组件按钮,就可以轻松的实现组件 com-a 和 com-b 的动态切换了,是不是很酷?赶紧动手尝试下吧。
Vuejs - 组件式开发的更多相关文章
- Agile.Net 组件式开发平台 - 组件开发示例
所谓组件式开发平台,它所有的功能模块都是以组件的形式扩展的,下面我来演示一个简单的组件开发例程. Agile.Net开发管理平台项目,已经托管在开源中国码云平台(http://git.oschina. ...
- Agile.Net 组件式开发平台 - 平台系统介绍
平台介绍 Agile.Net 组件式开发平台是一款针对企业级产品的开发框架,平台架构基于SOA服务体系,多层组件式架构打造.平台提供企业应用开发所需的诸如ORM.IOC.WCF.EBS.SOA等分布式 ...
- 基于TypeScript的FineUIMvc组件式开发(开头篇)
了解FineUIMvc的都知道,FineUIMvc中采用了大量的IFrame框架,对于IFrame的优缺点网上也有很多的讨论,这里我要说它的一个优点“有助于隔离代码逻辑”,这也是FineUIMvc官网 ...
- 组件式开发(Vue)
什么是组件式开发: 组件式开发就是将单个组件组合起来,形成一个大的组件进行页面的开发完成 什么是复合型组件: 复合型组件就是将相同的功能写成一个公用的组件(单元组件),供其他组件使用,就类似于后台开发 ...
- PIE SDK组件式开发综合运用示例
1. 功能概述 关于PIE SDK的功能开发,在我们的博客上已经分门别类的进行了展示,点击PIESat博客就可以访问,为了初学者入门,本章节将对从PIE SDK组件式二次开发如何搭建界面.如何综合开发 ...
- Agile.Net 组件式开发平台 - 驱动开发示例
首先讲一下概念,此驱动非彼驱动.在Agle.Net中我们将组件规划成两种类型,一种是基于业务的窗体组件,一种是提供扩展功能的驱动组件. 打个比方例如一般系统中需要提供身份证读卡功能,然而市面上有很多种 ...
- Agile.Net 组件式开发平台 - 服务开发示例
在上一篇文章中已经讲解了组件的开发,这篇文章讲解平台服务开发. Agile.Net开发管理平台项目,已经托管在开源中国码云平台(http://git.oschina.net) 登陆码云平台进入项目主页 ...
- 基于TypeScript的FineUIMvc组件式开发(概述)
WebForm与Mvc 我简单说一下WebForm与Mvc,WebForm是微软很早就推出的一种WEB开发架构,微软对其进行了大量的封装,使开发人员可以像开发桌面程序一样去开发WEB程序,虽然开发效率 ...
- Agile.Net 组件式开发平台 - 内核管理组件
敏捷开发体系 软件构件技术:所谓软件构件化,就是要让软件开发像机械制造工业一样,可以用各种标准和非标准的零件来进行组装.软件的构件化和集成技术的目标是:软件系统可以由不同厂商提供的,用不同语言开发 ...
随机推荐
- djano modles values+ajax实现无页面刷新更新数据
做项目的过程中想通过不刷新页面的方式来进行页面数据刷新,开始使用http://www.cnblogs.com/ianduin/p/7761400.html方式将查询结果数据进行序列化.发现可以行,但是 ...
- 第三部分shell编程3(shell脚本编写1)
做监控和备份最多 1. shell脚本是什么它是一种脚本语言,并非编程语言可以使用一些逻辑判断.循环等语法可以自定义子函数是系统命令的集合shell脚本可以实现自动化运维,大大增加我们的工作效率 第一 ...
- canvas drawImage 不显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ASP.NET MVC4计划任务实现方法(定时执行某个功能)
系统中定时执行某个任务是比较常用的功能,如一个部门定期向上级部门上报数据是一个典型的例子,下面就简单说说在.net mvc中如何实现定时执行某个功能的方法. 1.首先修改Glocal.asax文件,在 ...
- 【python】 requirements使用方法
记得导入导出包的时候要想激活虚拟环境.1.导出requirements方法pip freeze > requirements.txt 2.安装requirements方法pip install ...
- Python替换字符串中的反斜杠\
s = 'cdp\nd' result = eval(repr(s).replace('\\', '@')) print(result) repr() 函数可以将字符串转换为python的原始字符串( ...
- Gevent-socket
1. 通过Gevent实现单线程下的多socket并发. server 端: #server side import sys import socket import time import geve ...
- [CF888G]Xor-MST
题目大意:给一个$n$个点的完全图,第$i$个点有点权$v_i$,一条边$x-y$的边权为$v_x\oplus v_y$,求最小生成树 题解:明显$Kruskal$和$Prim$都会$TLE$,有一种 ...
- BZOJ4570:[SCOI2016]妖怪——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4570 邱老师是妖怪爱好者,他有n只妖怪,每只妖怪有攻击力atk和防御力dnf两种属性.邱老师立志成 ...
- BZOJ5338:[TJOI2018]异或——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5338 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi. 现在有Q 次操 ...