js模塊化開發(fā)
為什么會有模塊化開發(fā)涣雕?
- 代碼重用時,引入js文件的數目可能少了装处,避免來代碼的累贅误债。
- 代碼復用高,開發(fā)效率也會提高妄迁。
- 方便后期的維護寝蹈。
模塊化開發(fā)
模塊化封裝(組件封裝)思想
- 智能組件
- 和一切數據打交道,發(fā)生各種請求登淘。
- 只接受父組件的參數箫老。返回給父組件需要的值。
- 木偶組件
- 不依賴父組件的實例形帮,不受父組件影響(css)槽惫。
- 接受父組件的一切,不返回任何值辩撑。
- 渲染確定的結果界斜。
頁面渲染通過智能組件。它們專門做數據相關的應用邏輯合冀,和各種數據打交道各薇、和 Ajax 打交道,然后把數據通過 props 傳遞給木偶組件,它們帶領著 木偶組件組件完成了復雜的應用程序邏輯
組件封裝一個react-redux組件封裝介紹使用峭判;
vue組件封裝實例
需要對vue的指令有更生的理解:
extend:組件構造器开缎;
directive:指令生成器;
slot:組件插槽林螃;
style,class綁定奕删;
組件封裝思想:model層,view層疗认,control層
1. vue組件封裝: message封裝完残。
已經實現(xiàn):自定義樣式,自定義內容横漏,以方法調用
model層實現(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 = '';組件顯示類型
這是個典型的木偶組件谨设,依賴三個參數;它只負責頁面的渲染缎浇;給什么渲染什么扎拣。
control層實現(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);// 實現(xiàn)組件構造
if (Vue.prototype.$isServer) {
return;
}
options = Object.assign({}, defaults, options); // 配置參數
const parent = document.body;
const instance = new messageVueConstructor({ // 組件的實例
el: document.createElement('div'),
data: options
});
parent.appendChild(instance.$el);// 插入頁面
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上
}
};
首先需要我們引入組件素跺,然后通過構造實例來形成組件二蓝,通過組件的實例來控制組件的顯示和隱藏。
最后我們把實例的方法導出去亡笑;同時掛載導vue的原型侣夷;的在main.ts里面引入,通過use使用横朋。這樣我們就封裝好來一個屬于我們自己的$message
import message from './util/message';
Vue.use(message);
最后我們通過vm.$message()就可以使用了仑乌;
view層實現(xiàn)
vm.$message({type:'success',text:'xxx',duration:3333})
2. vue指令封裝 v-loading
可以實現(xiàn):添加修飾符,樣式修改琴锭,內容添加
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>
這也是個木偶組件;對傳入的參數進行顯示晰甚;
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是個Vue實例
toggleLoading(el, binding);
},
update: (el, binding) => {
// el.instance.setText(el.getAttribute('loading-text'));
if (binding.oldValue !== binding.value) {
toggleLoading(el, binding);
}
}
});
}
};
指令的實現(xiàn)是通過 vue.directive來實現(xiàn)的
Vue.directive('my-directive', {
bind: function () {},
inserted: function () {},
update: function () {},
componentUpdated: function () {},
unbind: function () {}
})
這個是它的生命周期;鉤子函數的參數 ( el决帖、binding厕九、vnode 和 oldVnode)。
bind只調用一次地回,指令第一次綁定到元素時調用扁远。
update在指令的傳入值更新的時候實現(xiàn)。
在bind的時候通過調用組件的實例讓組件顯示刻像,同時獲取綁定標簽屬性來設置顯示的文字畅买;和設置標簽的樣式讓組件合理顯示,在處理loading顯示的時候通過獲取修飾符binding.modifiers.body
细睡,來對顯示元素實現(xiàn)不通的顯示效果谷羞,
通過對update市設置,讓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>