组件封装系列(1)--全局引入和按需引入代码结构设计

序言

写文章总要要个目的性,就简单介绍下自己写这个系列的目的吧,就权当有个备份日志了:
1. 最主要的还是自己的js钻研遇到了瓶颈,看了许许多多的别人写的js深入js系列博客,也确实收获了很多,但是忽然发现实际中使用的机会特别少,基本上都是身边兄弟出去面试反馈回来又问到了某某知识点。
2. 公司前期项目主要基于vue+mintUI/elementUI进行开发的,陆陆续续基于这两个UI框架也封装了50+的组件吧,当时感觉还挺洋洋得意的,毕竟大大提升了项目开发进度,但是后期用react+antDesign的时候发现,仅仅是切换了一个mv*框架,我又要重写一遍那些UI组件,虽然是基于已有的框架二次封装,但是这也是消耗的自己时间做的无用功啊,不过好在antDesign比较强大,需要自己二次封装的不多
3. 最初是打算自己像bootStrap一样,写一个UI组件,不需要依赖mv*框架,直接任何项目都可以使用,后来发现是自己想多了,即使是组件封装,也是为业务服务的,不然就是凭空造无用轮子。
4. 相对react而言,vue更熟练,这个项目的目的主要就是为了深入轮子制造以及js钻研,就首先剔除非主观因素

所以,最终决定从之前刚改版的2.3vue架构版本的项目中剔除最初的UI框架,css文件,参考antDesign进行中后台框架封装。(antDesign确实比elementUI的UI组件全)

前情提要

  1. 因为某些原因,前期整个项目并不打算完全公开,只是进行组件代码和思路以及设计知识点的总结,不过后期等做完了进行优化后会把git地址公开出来,而且不想自己未曾优化的代码污染大家的眼睛。
  2. 首先会进行需要说明,简单介绍下要实现什么功能,会用到的知识点,有的部分会给出参考文章链接;第二部分就是代码实现,有少量的必要备注;第三部分会对用到的知识点进行详细介绍,预计是图文并茂形的,嘿嘿。

正文

需求分析

  1. 方便后期公共组件抽离,scss代码公共函数抽离
  2. 组件既可以全局引入,也可以按需引入

代码实现

部分代码结构

//里面有设计vue的部分,不在描述,请看api文档
shared
    --packages //公共组件
        --row
            --src //单独组件代码
                --row.js
            index.js //组件导出,方便后面package index.js引用
        --col
            --src
                --col.js
            index.js
        --theme-chalk//这里没把组件样式写在组件内主要是为了复用,后期打算抽离处理打成npm包
            --src
                --common
                --mixin
                --col.scss
                --index.scss//所有scss文件导出端口
                --row.scss
        --index.js//组件局部注册并导出
    --index.js
views
    --client
        --compontenTest.vue
main.js
//番外篇有scss公共函数代码展示

row.js

export default {
  name: 'PrRow',//必须,全局组件注册要求的tagName

   render(h) {//番外篇会讲解建议什么时候使用jsx
    return h(this.tag, {
      class: [
        'pr-row',
        this.justify !== 'start' ? `is-justify-${this.justify}` : '',
        this.align !== 'top' ? `is-align-${this.align}` : '',
        {'pr-rol--flex': this.type === 'flex'}
      ],
      style: this.style
    }, this.$slots.default);
  }
}
//后面对于响应式布局会有详细介绍,这里非重点,不再赘述

row index.js

import Row from './src/row';
//组件注册
Row.install = function (Vue) {
  Vue.component(Row.name, Row);
}

export default Row;

package index.js

import Vue from 'vue';

import Row from './row/src/row';
import Col from './col/src/Col';

const components = [
  Row,
  Col
];

//这里主要是为了往Vue原型上绑定一些方法,例如loading,方便调用
const install = function (Vue, opts = {}) {
    //初始化全局组件注册
  components.map(component => {
    Vue.component(component.name, component)
  })
 // Vue.prototype.$loading = Loading.service;
}

if(typeof window !== 'undefined') {
  install(Vue);
}

export default {
  version: '0.0.1',
  Row,
  Col
}

这里是最初版本的loading方法引入(有点low),可以参考下思路

import Loading from 'components/commons/Loading'

let ins = new Vue({
  el: '#component-loading',
  data() {
    return {
      show: false,
      msg: null
    }
  },

  events: {
    open(msg) {
      this.show = true
      this.msg = msg
    },
    close() {
      this.show = false
      this.msg = null
    }
  },
  components: {
    Loading
  }
})

export default {}.install = function(Vue, options) {
  Vue.loading = (msg) => {
    ins.$emit('open', msg)
  }

  Vue.loaded = () => {
    ins.$emit('close')
  }
}

shared index.js

import './packages'

main.js调用

import './shared'
import './shared/packages/theme-chalk/src/index.scss'

知识点总结

1.es6模块加载commonjs模块

CommonJS 模块的输出都定义在module.exports这个属性上面。Node 的import命令加载 CommonJS 模块,Node 会自动将module.exports属性,当作模块的默认输出,即等同于export default xxx

// a.js CommonJS
module.exports = {
  foo: 'hello',
  bar: 'world'
};

// 等同于 ES6
export default {
  foo: 'hello',
  bar: 'world'
};

你可能感兴趣的:(组件开发)