js模塊化開發
為什么會有模塊化開發?
- 代碼重用時,引入js文件的數目可能少了,避免來代碼的累贅。
- 代碼復用高,開發效率也會提高。
- 方便后期的維護。
模塊化開發
模塊化封裝(組件封裝)思想
- 智能組件
- 和一切數據打交道,發生各種請求。
- 只接受父組件的參數。返回給父組件需要的值。
- 木偶組件
- 不依賴父組件的實例,不受父組件影響(css)。
- 接受父組件的一切,不返回任何值。
- 渲染確定的結果。
頁面渲染通過智能組件。它們專門做數據相關的應用邏輯,和各種數據打交道、和 Ajax 打交道,然后把數據通過 props 傳遞給木偶組件,它們帶領着 木偶組件組件完成了復雜的應用程序邏輯
組件封裝一個react-redux組件封裝介紹使用;
vue組件封裝實例
需要對vue的指令有更生的理解:
extend:組件構造器; directive:指令生成器; slot:組件插槽; style,class綁定;
組件封裝思想:model層,view層,control層
1. vue組件封裝: message封裝。
已經實現:自定義樣式,自定義內容,以方法調用
model層實現
<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層實現:
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);// 實現組件構造 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層實現
vm.$message({type:'success',text:'xxx',duration:3333})
2. vue指令封裝 v-loading
可以實現:添加修飾符,樣式修改,內容添加
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); } } }); } };
指令的實現是通過 vue.directive來實現的
Vue.directive('my-directive', { bind: function () {}, inserted: function () {}, update: function () {}, componentUpdated: function () {}, unbind: function () {} })
這個是它的生命周期;鈎子函數的參數 ( el、binding、vnode 和 oldVnode)。
bind只調用一次,指令第一次綁定到元素時調用。
update在指令的傳入值更新的時候實現。
在bind的時候通過調用組件的實例讓組件顯示,同時獲取綁定標簽屬性來設置顯示的文字;和設置標簽的樣式讓組件合理顯示,在處理loading顯示的時候通過獲取修飾符binding.modifiers.body
,來對顯示元素實現不通的顯示效果,
通過對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>
作者:熊少年
鏈接:https://www.jianshu.com/p/0662d0a7b4f3