VUE组件化开发的精髓
日期: 2019-05-22 分类: 个人收藏 306次阅读
- 开篇:vue.js的简单介绍和演示
- vue的开发精髓-组件
- vue组件的三个API:prop、event、slot
- 组件之间的通信方式
- 实例讲解:銖宝益帮助中心前端组件
开篇:vue.js的简单介绍和演示
vue发布于2013年,是一个渐进式的框架, 同时也是一个轻量级的框架,它只关心数据,从而让开发者不用过多的关注DOM的改变和操作DOM,vue的作者为Evan You(尤雨溪),任职于Google Creative Lab
DOM:document object model(文档对象模型)也就是操作html或xml的通用编程接口,这里不过度描述
双向绑定代码演示
// html
<body>
<div id="app">
<input type="text" v-model="note">
<p>{{ note }}</p>
</div>
</body>
// js
var app = new Vue({
el: '#app',
data: {
note: ''
}
})
复制代码
对比其它web前端框架,vue更容易上手,代码和API更为简洁和直观,且速度更快!
vue的开发精髓-组件
vue最精髓的,正是它的组件与组件化,写一个 Vue 工程,其实就是在写一个个的组件。
vue组件的分类(三大类)
- 由 ==vue-router产生的每个页面==,它本质上也是一个组件(.vue),主要承载当前页面的 HTML 结构,会包含数据获取、数据整理、数据可视化等常规业务。整个文件相对较大,因为它作为路由的渲染,不会被复用,因此也不会对外提供接口;在项目开发中,我们写的大部分代码都是这类的组件(页面),协同开发时,每人维护自己的页面,很少有交集。这类组件相对是最好写的,因为主要是还原设计稿,完成需求,不需要太多模块和架构设计上的考虑;
- 不包含业务,独立、具体功能的==基础组件==,比如日期选择器、模态框等。这类组件作为项目的基础控件,会被大量使用,因此组件的 API 进行过高强度的抽象,可以通过不同配置实现不同的功能;
- ==业务组件==。它不像第二类独立组件只包含某个功能,而是在业务中被多个页面复用的,它与独立组件的区别是,业务组件只在当前项目中会用到,不具有通用性,而且会包含一些业务,比如数据请求;而独立组件不含业务,在任何项目中都可以使用,功能单一,比如一个具有自定义数据校验功能的输入框。
vue组件的三个API:prop、event、slot
一个组件的复杂与否,都是由三部分组成的,==prop(属性)==,==event(事件)==,==slot(插槽)==,必须要先设计好这三部分,才能继续开发组件,否则,代码一旦发布,后面再修改API就很困难了,组件的维护都是以新增功能为主,而不是经常变更接口;
prop(属性)
prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。写通用组件时,props 最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,这点在组件开发中很重要,然而很多人却忽视,直接使用 props 的数组用法,这样的组件往往是不严谨的。
例如:收银端的打印弹框组件(部分代码已简略)
<template>
<!--打印-->
<el-dialog
:show-close="false"
:visible="visiable"
:closeOnClickModal="false"
custom-class="zbe-dialog chose-sale"
width="1000px"
center
>
<p slot="title" class="zbe-dialog-title">打印单据</p>
<div class="box">
<el-row style="margin-top:10px">
<el-col :span="24" v-if="!web_view_error" v-loading="loading">
<!-- 预览窗口 -->
<webview
ref="view"
id="view"
:src="visiable?data_web_view_url:' '"
autosize
plugins
disablewebsecurity
allowpopups
style="display:inline-flex; width:100%;height:400px;"
></webview>
</el-col>
<!-- 打印加载失败提示 -->
<el-col :span="24" v-if="web_view_error&&!loading">打印加载失败</el-col>
</el-row>
<!-- 关闭按钮 -->
<el-row>
<el-col :span="11" :offset="20" style="margin-top:20px">
<el-button @click="doCancle">关闭</el-button>
</el-col>
</el-row>
</div>
</el-dialog>
</template>
<script>
export default {
name: "print",
props: {
// 控制组件的显示隐藏
show: {
type: Boolean,
default: false
},
// 打印URL
web_view_url: "",
// 关闭打印后的跳转地址
web_view_reback_path: "",
// 是否打印加载失败
web_view_error: false
},
data() {
return {
visiable: false,
domReady: true,
data_web_view_url: "/",
loading: false
};
},
methods: {
// 关闭后跳到传过来的path
doCancle() {
this.$emit("dailog-close", "printDialogVisible");
this.$router.push({ name: this.web_view_reback_path });
}
},
watch: {
show(item) {
this.visiable = item;
},
web_view_url(newValue, oldValue) {
this.loading = true;
this.data_web_view_url = "/";
setTimeout(() => {
this.data_web_view_url = newValue;
}, 200);
this.loading = false;
},
}
};
</script>
复制代码
组件中定义了4个prop,分别是==show==(控制组件的显示隐藏),==web_view_url==(打印URL),==web_view_reback_path==(关闭打印后的跳转地址),==web_view_error==(是否打印加载失败)
值得注意的是,组件里定义的prop都是单向数据流,只能通过父级组件对齐进行修改,组件本身不能修改props的值,只能修改定义在data里的数据,非要修改,也是通过后面介绍的自定义事件通知父级,由父级来修改;
solt(插槽)
先看下代码
<template>
<button>
<slot name="icon"></slot>
<slot></slot>
</button>
</template>
复制代码
这里的节点就是指定的一个插槽的位置,这样在组件内部就可以扩展内容了;
<i-button>
<i-icon slot="icon" type="checkmark"></i-icon>
按钮 1
</i-button>
复制代码
这样,父级内定义的内容,就会出现在组件对应的 slot 里,没有写名字的,就是默认的 slot;
event(事件)
还是先看代码
<template>
<button @click="handleClick">
<slot></slot>
</button>
</template>
<script>
export default {
methods: {
handleClick (event) {
this.$emit('on-click', event);
}
}
}
</script>
复制代码
在组件中可以通过$emit触发自定义事件on-click,在父组件通过@on-click来监听
<i-button @on-click="handleClick"></i-button>
复制代码
组件之间的通信方式
Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据。必须使用特定的方法才能实现组件之间的数据传递
1、父子组件之间的通信方式
父组件向子组件的通信方式可以通过props传递: 如果需要从父组件获取 username 的值,就需要
props:{
username:{
}
}
复制代码
子组件向父组件传递数据则可以通过event传递:
methods:{
handelSwitch(index){
this.actIndex=index;
this.$emit("transferTabIndex",this.actIndex)
}
}
复制代码
2、非父子组件之间的通信方式:eventBus
eventBus这种通信方式,针对的是非父子组件之间的通信,它的原理还是通过事件的触发和监听;
但是因为是非父子组件的关系,他们需要有一个中间组件来连接;
我是使用的通过在根组件,也就是#app组件上定义了一个所有组件都可以访问到的组件,具体使用方式如下;
使用eventBus传递数据,我们一共需要做3件事情
- 1.给app组件添加Bus属性 (这样所有组件都可以通过this.$root.Bus访问到它,而且不需要引入任何文件);
- 2.在组件1里,this.
emit触发事件;
- 3.在组件2里,this.
on监听事件;
3、利用本地化缓存机制
这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护;
通过window.localStorage.getItem(key) 获取数据; 通过window.localStorage.setItem(key,value) 存储数据;
注意用JSON.parse() / JSON.stringify() 做数据格式转换;
实例讲解:銖宝益帮助中心前端组件
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
精华推荐