美文网首页
vue2模块化开发以及组件封装思想

vue2模块化开发以及组件封装思想

作者: 硅谷干货 | 来源:发表于2022-05-24 23:26 被阅读0次

    模块化开发

    为什么会有模块化开发?

    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>

    相关文章

      网友评论

          本文标题:vue2模块化开发以及组件封装思想

          本文链接:https://www.haomeiwen.com/subject/dlgsprtx.html