js模塊化開(kāi)發(fā)
為什么會(huì)有模塊化開(kāi)發(fā)?
- 代碼重用時(shí),引入js文件的數(shù)目可能少了,避免來(lái)代碼的累贅。
- 代碼復(fù)用高,開(kāi)發(fā)效率也會(huì)提高。
- 方便后期的維護(hù)。
模塊化開(kāi)發(fā)
模塊化封裝(組件封裝)思想
- 智能組件
- 和一切數(shù)據(jù)打交道,發(fā)生各種請(qǐng)求。
- 只接受父組件的參數(shù)。返回給父組件需要的值。
- 木偶組件
- 不依賴父組件的實(shí)例,不受父組件影響(css)。
- 接受父組件的一切,不返回任何值。
- 渲染確定的結(jié)果。
頁(yè)面渲染通過(guò)智能組件。它們專門做數(shù)據(jù)相關(guān)的應(yīng)用邏輯,和各種數(shù)據(jù)打交道、和 Ajax 打交道,然后把數(shù)據(jù)通過(guò) props 傳遞給木偶組件,它們帶領(lǐng)著 木偶組件組件完成了復(fù)雜的應(yīng)用程序邏輯
組件封裝一個(gè)react-redux組件封裝介紹使用;
vue組件封裝實(shí)例
需要對(duì)vue的指令有更生的理解:
extend:組件構(gòu)造器;
directive:指令生成器;
slot:組件插槽;
style,class綁定;
組件封裝思想:model層,view層,control層
1. vue組件封裝: message封裝。
已經(jīng)實(shí)現(xiàn):自定義樣式,自定義內(nèi)容,以方法調(diào)用
model層實(shí)現(xiàn)
<template>
<transition name="mei-message-fade">
<div v-if="show" :class="[
'mei-message',
type? `mei-message-${ type }` : '']">
<span class="mei-message-con">{{text}}</span>
</div>
</transition>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class MessageBox extends Vue {
show: boolean = false;
text: string = '';
type: string = '';
}
</script>
<style>
.mei-message {
}
.mei-message-success {
}
.mei-message-error {
}
.mei-message-warning {
}
.mei-message-icon {
}
.mei-message-con {
line-height: 40px;
height: 40px;
display: inline-block;
margin-left: 10px;
}
.mei-message-fade-enter-active {
transition: all 0.3s linear;
}
.mei-message-fade-leave-active {
transition: all 0.3s linear;
}
.mei-message-fade-enter, .mei-message-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */
{
opacity: 0;
}
</style>
show: boolean = false; 控制組件的顯示隱藏
text: string = ''; 組件的顯示文字
type: string = '';組件顯示類型
這是個(gè)典型的木偶組件,依賴三個(gè)參數(shù);它只負(fù)責(zé)頁(yè)面的渲染;給什么渲染什么。
control層實(shí)現(xiàn):
import Vue from 'vue';
import messageVue from '@/components/MessageBox.vue'; // 組件引入
interface Star { ts接口聲明
show?: boolean;
text?: string;
duration?: string;
type?: string;
}
export const messageBox = (options: Star) => {
const defaults = {
show: false,
text: '',
duration: '2000',
type: ''
};
const messageVueConstructor = Vue.extend(messageVue);// 實(shí)現(xiàn)組件構(gòu)造
if (Vue.prototype.$isServer) {
return;
}
options = Object.assign({}, defaults, options); // 配置參數(shù)
const parent = document.body;
const instance = new messageVueConstructor({ // 組件的實(shí)例
el: document.createElement('div'),
data: options
});
parent.appendChild(instance.$el);// 插入頁(yè)面
Vue.nextTick(() => {
instance.show = true; // 修改顯示和隱藏
setTimeout(function () {
// (<any>instance).show=false;
instance.show = false;
}, options.duration);
});
return instance;
};
export default {
install: vue => {
vue.prototype.$message = messageBox; // 將message組件暴露出去,并掛載在Vue的prototype上
}
};
首先需要我們引入組件,然后通過(guò)構(gòu)造實(shí)例來(lái)形成組件,通過(guò)組件的實(shí)例來(lái)控制組件的顯示和隱藏。
最后我們把實(shí)例的方法導(dǎo)出去;同時(shí)掛載導(dǎo)vue的原型;的在main.ts里面引入,通過(guò)use使用。這樣我們就封裝好來(lái)一個(gè)屬于我們自己的$message
import message from './util/message';
Vue.use(message);
最后我們通過(guò)vm.$message()就可以使用了;
view層實(shí)現(xiàn)
vm.$message({type:'success',text:'xxx',duration:3333})
2. vue指令封裝 v-loading
可以實(shí)現(xiàn):添加修飾符,樣式修改,內(nèi)容添加
model層
<template>
<div v-show="visible" class="zh-loading-box" v-bind:class="{full:body}">
<div class="flex-center">
<div>
<h1>加載</h1>
</div>
<p>{{ text }}</p>
</div>
</div>
</template>
<script lang='ts'>
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class Load extends Vue {
text: string = '';
body: boolean = true;
visible: boolean = false;
}
</script>
<style scoped>
.zh-loading-box {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
top: 0;
bottom: 0;
right: 0;
left: 0;
}
</style>
這也是個(gè)木偶組件;對(duì)傳入的參數(shù)進(jìn)行顯示;
control層
import Load from '@/components/Load.vue';
const toggleLoading = (el, binding) => {
if (binding.modifiers.body) {
el.instance.body = true;
} else {
el.instance.body = false;
}
if (binding.value) {
el.instance.visible = true;
} else {
el.instance.visible = false;
}
};
export default {
install: vue => {
vue.directive('loading', {
bind: (el, binding) => {
const defaults = {
visible: false,
body: false,
text: el.getAttribute('loading-text')
};
const options = Object.assign({}, defaults);
const LoadingCounstruct = vue.extend(Load);
const loading = new LoadingCounstruct({
el: document.createElement('div'),
data: options
});
el.style.position = 'relative';
el.appendChild(loading.$el);
el.instance = loading; // el.instance是個(gè)Vue實(shí)例
toggleLoading(el, binding);
},
update: (el, binding) => {
// el.instance.setText(el.getAttribute('loading-text'));
if (binding.oldValue !== binding.value) {
toggleLoading(el, binding);
}
}
});
}
};
指令的實(shí)現(xiàn)是通過(guò) vue.directive來(lái)實(shí)現(xiàn)的
Vue.directive('my-directive', {
bind: function () {},
inserted: function () {},
update: function () {},
componentUpdated: function () {},
unbind: function () {}
})
這個(gè)是它的生命周期;鉤子函數(shù)的參數(shù) ( el、binding、vnode 和 oldVnode)。
bind只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。
update在指令的傳入值更新的時(shí)候?qū)崿F(xiàn)。
在bind的時(shí)候通過(guò)調(diào)用組件的實(shí)例讓組件顯示,同時(shí)獲取綁定標(biāo)簽屬性來(lái)設(shè)置顯示的文字;和設(shè)置標(biāo)簽的樣式讓組件合理顯示,在處理loading顯示的時(shí)候通過(guò)獲取修飾符binding.modifiers.body,來(lái)對(duì)顯示元素實(shí)現(xiàn)不通的顯示效果,
通過(guò)對(duì)update市設(shè)置,讓loading隱藏
if (binding.value) {
el.instance.visible = true;
} else {
el.instance.visible = false;
}
最后export default 出去;
在main.ts里面
import loading from './util/loading';
Vue.use(loading);
view層
<div v-loading='true'></div>