没有合适的资源?快使用搜索试试~ 我知道了~
首页vue组件精讲.docx
Vue组件精讲
需积分: 0 1 下载量 145 浏览量
更新于2023-11-23
收藏 462KB DOCX 举报
《Vue组件精讲》是一本关于Vue.js框架的前端开发技术小册,主要介绍了Vue.js组件的核心思想和使用技巧。作者在本小册中着重分享了自己在3年的Vue.js开发和两年的iView开源项目中所积累和沉淀的关于Vue.js组件的见解和经验。本小册适合已经了解或使用过Vue.js的开发者阅读。在开篇中,作者首先介绍了Vue.js的重要性以及组件写作的基本概念,强调了掌握了Vue.js组件的各种开发模式,即使在复杂的业务场景中也可以轻松化解问题。文中还对Vue.js组件进行了分类,分为由vue-router产生的页面组件和不包含业务、独立、具体功能的基础组件两类,并详细介绍了它们的特点和使用场景。整体来看,这本小册总共包含134页内容,对Vue.js组件开发给出了深入的讲解,对于想要深入了解Vue.js框架的开发者来说,是一本不可多得的学习资料。
资源详情
资源推荐
2019/9/25
Markdoc Preview
16/134
function broadcast(componentName, eventName, params)
{ this.$children.forEach(child => {
const name = child.$options.name;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
export default
{ methods: {
dispatch(componentName, eventName, params)
{ let parent = this.$parent || this.$root;
let name = parent.$options.name;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.name;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params));
}
},
broadcast(componentName, eventName, params) {
上例中行 ① 和行 ② 的两个方法就是在导入的混合 emitter.js 中定义的,这个稍后我们再讲,先来分析这两
个方法应该传入什么参数。一般来说,为了跟 Vue.js 1.x 的方法一致,第一个参数应当是自定义事件名,比
如 “test”,第二个参数是传递的数据,比如 “Hello, Vue.js”,但在这里,有什么问题呢?只通过这两个参数,
我们没办法知道要在哪个组件上触发事件,因为自行实现的这对方法,与 Vue.js 1.x 的原生方法机理上是有
区别的。上文说到,实现这对方法的关键点在于准确地找到组件实例。那在寻找组件实例上,我们的“惯用伎
俩”就是通过遍历来匹配组件的 name 选项,在独立组件(库)里,每个组件的 name 值应当是唯一的,
name 主要用于递归组件,在后面小节会单独介绍。
先来看下 emitter.js 的代码:
export default
{ mixins:
[ Emitter ],
methods: {
handleDispatch ()
{ this.dispatch(); //
①
},
handleBroadcast () {
this.broadcast();
// ②
}
}
}
2019/9/25
Markdoc Preview
17/134
<!-- A.vue -->
<template>
<button @click="handleClick">触发事件</button>
</template>
<script>
import Emitter from '../mixins/emitter.js';
export default
{ name:
'componentA',
mixins: [ Emitter ],
methods: {
handleClick () {
this.broadcast('componentB', 'on-message', 'Hello Vue.js');
}
}
}
</script>
// B.vue
export default
{ name:
'componentB',
created () {
this.$on('on-message', this.showMessage);
},
methods: {
showMessage (text)
{ window.alert(text);
}
}
}
因为是用作 mixins 导入,所以在 methods 里定义的 dispatch 和 broadcast 方法会被混合到组件里,自然就
可以用 this.dispatch 和 this.broadcast 来使用。
这两个方法都接收了三个参数,第一个是组件的 name 值,用于向上或向下递归遍历来寻找对应的组件,第
二个和第三个就是上文分析的自定义事件名称和要传递的数据。
可以看到,在 dispatch 里,通过 while 语句,不断向上遍历更新当前组件(即上下文为当前调用该方法的组
件)的父组件实例(变量 parent 即为父组件实例),直到匹配到定义的 componentName 与某个上级组件的
name 选项一致时,结束循环,并在找到的组件实例上,调用 $emit 方法来触发自定义事件 eventName 。
broadcast 方法与之类似,只不过是向下遍历寻找。
来看一下具体的使用方法。有 A.vue 和 B.vue 两个组件,其中 B 是 A 的子组件,中间可能跨多级,在 A 中
向 B 通信:
同理,如果是 B 向 A 通信,在 B 中调用 dispatch 方法,在 A 中使用 $on 监听事件即可。
以上就是自行实现的 dispatch 和 broadcast 方法,相比 Vue.js 1.x,有以下不同:
broadcast.call(this, componentName, eventName, params);
}
}
};
2019/9/25
Markdoc Preview
18/134
<i-form>
<i-form-item>
<i-input v-model="form.name"></i-input>
</i-form-item>
<i-form-item>
<i-input v-model="form.mail"></i-input>
</i-form-item>
</i-form>
[
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
]
需要额外传入组件的 name 作为第一个参数;
无冒泡机制;
第三个参数传递的数据,只能是一个(较多时可以传入一个对象),而 Vue.js 1.x 可以传入多个参
数,当然,你对 emitter.js 稍作修改,也能支持传入多个参数,只是一般场景传入一个对象足以。
结语
Vue.js 的组件通信到此还没完全结束,如果你想“趁热打铁”一口气看完,可以先阅读第 6 节组件的通信 3。亦
或按顺序看下一节的实战,来进一步加深理解 provide / inject 和 dispatch / broadcast 这两对通信方法的使用
场景。
注:本节部分代码参考 iView。
实战 1:具有数据校验功能的表单组件——Form
在第 3 节和第 4 节中,我们介绍了组件间的两种通信方法:provide / inject 和 dispatch / broadcast,前者是
Vue.js 内置的,主要用于子组件获取父组件(包括跨级)的状态;后者是自行实现的一种混合,用于父子组
件(包括跨级)间通过自定义事件通信。本小节则基于这两种通信方法,来实现一个具有数据校验功能的表
单组件——Form。
Form 组件概览
表单类组件在项目中会大量使用,比如输入框(Input)、单选(Radio)、多选(Checkbox)、下拉选择器
(Select)等。在使用表单类组件时,也会经常用到数据校验,如果每次都写校验程序来对每一个表单控件
校验,会很低效,因此需要一个能够校验基础表单控件的组件,也就是本节要完成的 Form 组件。一般的组
件库都提供了这个组件,比如 iView,它能够校验内置的 15 种控件,且支持校验自定义组件,如下图所示:
(也可以在线访问本示例体验:run.iviewui.com/jwrqnFss)
img
Form 组件分为两个部分,一个是外层的 Form 表单域组件,一组表单控件只有一个 Form,而内部包含了多
个 FormItem 组件,每一个表单控件都被一个 FormItem 包裹。基本的结构看起来像:
Form 要用到数据校验,并在对应的 FormItem 中给出校验失败的提示,校验我们会用到一个开源库:async-
validator,基本主流的组件库都是基于它做的校验。使用它很简单,只需按要求写好一个校验规则就好,比
如:
2019/9/25
Markdoc Preview
19/134
<template>
<div>
<i-form :model="formValidate" :rules="ruleValidate">
<i-form-item label="用户名" prop="name">
<i-input v-model="formValidate.name"></i-input>
</i-form-item>
<i-form-item label="邮箱" prop="mail">
<i-input v-model="formValidate.mail"></i-input>
</i-form-item>
</i-form>
</div>
</template>
<script>
import iForm from '../components/form/form.vue';
import iFormItem from '../components/form/form-item.vue';
import iInput from '../components/input/input.vue';
export default {
这个代表要校验的数据先判断是否为空(required: true),如果为空,则提示“邮箱不能为空”,触发校验的事
件为失焦(trigger: 'blur'),如果第一条满足要求,再进行第二条的验证,判断是否为邮箱格式(type: 'email')
等等,还支持自定义校验规则。更详细的用法可以参看它的文档。
接口设计
我们先使用最新的 Vue CLI 3 创建一个空白的项目(如果你还不清楚 Vue CLI 3 的用法,需要先补习一下
了,可以阅读文末的扩展阅读 1),并使用 vue-router 插件,同时安装好 async-validator 库。
在 src/components 下新建一个 form 文件夹,并初始化两个组件 form.vue 和 form-item.vue ,然后初始
化项目,配置路由,创建一个页面能够被访问到。
本节所有代码可以在 github.com/icarusion/v… 中查看,你可以一边看源码,一边阅读本节;也可以
边阅读,边动手实现一遍,遇到问题再参考完整的源码。
第 2 节我们介绍到,编写一个 Vue.js 组件,最重要的是设计好它的接口,一个 Vue.js 组件的接口来自三个
部分:props、slots、events。而 Form 和 FormItem 两个组件主要做数据校验,用不到 events。Form 的
slot 就是一系列的 FormItem,FormItem 的 slot 就是具体的表单控件,比如输入框 <i-input> 。那主要设计
的就是 props 了。
在 Form 组件中,定义两个 props:
model:表单控件绑定的数据对象,在校验或重置时会访问该数据对象下对应的表单数据,类型为
Object。
rules:表单验证规则,即上面介绍的 async-validator 所使用的校验规则,类型为 Object。
在
FormItem
组件中,也定义两个
props:
label:
单个表单组件的标签文本,类似原生的 <label> 元素,类型为 String。
prop:对应表单域 Form 组件 model 里的字段,用于在校验或重置时访问表单组件绑定的数据,类型
为 String。
定义好 props,就可以写出大概的用例了:
2019/9/25
Markdoc Preview
20/134
<!-- form.vue -->
<template>
<form>
<slot></slot>
</form>
</template>
<script>
export default
{ name:
'iForm',
props: {
model:
{ type:
Object
},
rules:
{ type:
Object
}
}
}
</script>
<!-- form-item.vue -->
有两点需要注意的是:
1. 这里的 <i-input> 并不是原生的 <input> 输入框,而是一个特制的输入框组件,之后会介讲解的功
能和代码;
2. <i-form-item> 的属性 prop 是字符串,所以它前面没有冒号(即不是 :prop="name" )。
当前的两个组件只是个框框,还没有实现任何功能,不过万事开头难,定义好接口,剩下的就是补全组件的
逻辑,而对于使用者,知道了 props、events、slots,就已经能写出上例的使用代码了。
到此,Form 和 FormItem 的代码如下:
components: { iForm, iFormItem, iInput },
data () {
return
{ formValidate:
{
name: '',
mail: ''
},
ruleValidate:
{ name: [
{ required: true, message: '用户名不能为空', trigger: 'blur' }
],
mail: [
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
],
}
}
}
}
</script>
剩余133页未读,继续阅读
蚁库
- 粉丝: 31
- 资源: 99
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- zigbee-cluster-library-specification
- JSBSim Reference Manual
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功