vue模块化开发以及组件、指令封装思想


js模块化开发

为什么会有模块化开发?

  1. 代码重用时,引入js文件的数目可能少了,避免来代码的累赘。
  2. 代码复用高,开发效率也会提高。
  3. 方便后期的维护。
    模块化开发

模块化封装(组件封装)思想

  1. 智能组件
  • 和一切数据打交道,发生各种请求。
  • 只接受父组件的参数。返回给父组件需要的值。
  1. 木偶组件
  • 不依赖父组件的实例,不受父组件影响(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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM