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>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容