最近在研究 muse-ui 的实现,发现网上很少有关于 vue 插件具体实现的文章,官方的文档也只是一笔带过,对于新手来说并不算友好。

笔者结合官方文档,与自己的摸索总结,以最简单的 FlexBox 组件为例子,带大家入门 vue 的插件编写,如果您是大牛,不喜勿喷~

项目结构

| src
| ---| plugin
| ---| ---| flexbox # 组件文件夹
| ---| ---| ---| flexbox.vue # flex 布局的父组件
| ---| ---| ---| flexboxItem.vue # flex 布局的子组件
| ---| ---| ---| flexbox.scss # 样式文件,我使用的是 sass
| ---| ---| ---| index.js # 组件的出口
| ---| ---| styles # 公用的 css 样式文件
| ---| ---| index.js # 插件的出口
| ---| App.vue
| ---| main.js

<一> 让项目装载插件

首先,我们不去理会组件的具体实现,先让我们的项目能够正常装载一个我们自定义的插件

现在,我们的目标,是让项目能够正常显示这两个组件,能显示文本 flexbox demo 就可以啦!

./src/plugin/flexbox/flexbox.vue

<template>
<div>flexbox demo</div>
</template> <script>
export default {
// 这是该组件的自定义名称,
// 之后引用组件时就会用到这个名称。
name: 'my-flexbox'
}
</script>

./src/plugin/flexbox/flexboxItem.vue

<template>
<div>flexboxItem demo</div>
</template> <script>
export default {
name: 'my-flexbox-item'
}
</script>

./src/plugin/flexbox/index.js

这是整个 flexbox 组件的出口文件。\
因为这个组件有两个子组件,所以我们将引入的 default 改名为该组件的名称。{ default as flexbox }

// 引用 scss 文件
import './flexbox.scss' // 引用组件
export { default as flexbox } from './flexbox.vue'
export { default as flexboxItem } from './flexboxItem.vue'

./src/plugin/index.js

现在,我们来到插件的出口文件。

// ----- 1
import * as flexbox from './flexbox' // ----- 2
const components = {
...flexbox
} // ----- 3
const install = function (Vue, Option) {
// ----- 4
Object.keys(components).forEach((key) => {
Vue.component(components[key].name, components[key])
})
} // ----- 5
export default {
install
}
  1. 引入组件

  2. 定义 components 变量

  3. 这里是重点,vue 为编写插件提供了一个 install(Vue, Option) 方法,该方法为 vue 添加全局功能;

    该方法有两个参数,第一个是 Vue构造器,第二个是可选的参数;

  4. 使用 vue 的全局方法 Vue.component(Name, Object) 定义组件,第一个参数是组件名,第二参数是组件对象;

  5. 最后将组件默认导出。

./src/main.js

我们来到 main.js,在这里,我们将进行插件的最后配置啦。

使用 vue 的全局方法 Vue.use(PluginName, Options),第一个参数是插件的名字,第二个是可选的参数。

import plugin from './plugin'
Vue.use(plugin)

./src/App.vue

终于,我们可以在项目中引用我们定义的组件啦!

<template>
<my-flexbox></my-flexbox>
<my-flexbox-item></my-flexbox-item>
</template>

<二> Flexbox 组件的实现

组件的具体实现,就和平时自己写组件的方法是一样的了。

这里先贴出代码,我会将具体原理写在代码注释里面。

./src/plugin/flexbox/flexbox.vue

<template>
<!-- 为组件绑定一个类,这个类的值通过计算属性来得出 -->
<div class="my-flexbox"
:class="classObj">
<!-- slot 用来装载子组件,my-flexbox-item -->
<slot></slot>
</div>
</template> <script>
export default {
name: 'my-flexbox',
props: {
// 子组件 my-flexbox-item 之间是否存在间隙,
// 默认,8px 的间隙。
gutter: {
type: Number,
default: 8
},
// 子组件的排列方式,水平,或垂直排列。
orient: {
type: String,
default: 'horizontal'
},
justify: {
type: String
},
align: {
type: String
},
wrap: {
type: String,
default: 'nowrap'
}
},
computed: {
// 我们通过父级传递过来的参数,
// 来判断该组件需要应用哪些样式
// 如:<my-flexbox orient="vertical" justify="flex-start"></my-flexbox>
classObj () {
let classObj = {}; // orient
if (this.orient === 'vertical') classObj['flex-vertical'] = true; // wrap
if (this.wrap === 'wrap') {
classObj['flex-wrap'] = true
} else {
classObj['flex-nowrap'] = true
} // justify
switch (this.justify) {
case 'flex-start':
classObj['justify-start'] = true;
break;
case 'flex-end':
classObj['justify-end'] = true;
break;
case 'center':
classObj['justify-center'] = true;
break;
case 'space-between':
classObj['justify-space-between'] = true;
break;
case 'space-around':
classObj['justify-space-around'] = true;
break
}; // align
switch (this.align) {
case 'flex-start':
classObj['align-start'] = true;
break;
case 'flex-end':
classObj['align-end'] = true;
break;
case 'center':
classObj['align-center'] = true;
break;
case 'baseline':
classObj['align-baseline'] = true;
break;
case 'stretch':
classObj['align-stretch'] = true;
break;
}; return classObj;
}
}
}
</script>

./src/plugin/flexbox/flexbox.scss

scss 中定义需要使用到的样式

.my-flexbox {
width: 100%;
display: flex;
}
.flex-vertical {
flex-direction: column;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-nowrap {
flex-wrap: nowrap;
} /* justify */
.justify-start {
justify-content: flex-start
}
.justify-end {
justify-content: flex-end
}
.justify-center {
justify-content: center
}
.justify-space-between {
justify-content: space-between
}
.justify-space-around {
justify-content: space-around
} /* align */
.align-start {
align-items: flex-start
}
.align-end {
align-items: flex-end
}
.align-center {
align-items: center
}
.align-baseline {
align-items: baseline
}
.align-stretch {
align-items: stretch
}

./src/App.vue

好了!我们可以在项目中用到这个组件了!

<template>
<div id="app">
<my-flexbox>
<p>demo</p>
<p>demo</p>
</my-flexbox>
</div>
</template>

你也可以让他们垂直排列!

<template>
<div id="app">
<my-flexbox orient="vertical">
<p>demo</p>
<p>demo</p>
</my-flexbox>
</div>
</template>

<三> FlexboxItem 组件的实现

flexbox-item 组件和 flexbox 组件实现原理大同小异,直接贴代码了!

./src/plugin/flexbox/flexbox.vue

<template>
<div class="my-flexbox-item"
:style="styleObj">
<slot></slot>
</div>
</template> <script>
export default {
name: 'my-flexbox-item',
props: {
grow: {
type: [String, Number],
default: 0
},
shrink: {
type: [String, Number],
default: 1
},
basis: {
type: [String, Number],
default: 'auto'
},
order: {
type: [String, Number],
default: 0
}
},
computed: {
styleObj () {
let styleObj = {}; // gutter
let gutter = this.$parent.gutter,
orient = this.$parent.orient; let marginName = orient === 'horizontal'?'marginLeft':'marginTop';
styleObj[marginName] = gutter + 'px'; // grow
styleObj['flex-grow'] = this.grow; // shrink
styleObj['flex-shrink'] = this.shrink; // basis
styleObj['flex-basis'] = this.basis; // order
styleObj['order'] = this.order; return styleObj;
}
}
}
</script>

./src/App.vue

<template>
<div id="app">
<my-flexbox>
<my-flexbox-item grow="1">
demo
</my-flexbox-item>
<my-flexbox-item>
demo
</my-flexbox-item>
</my-flexbox>
</div>
</template>

总结

这只是 vue 中编写插件的其中一个方法,还有更多的,例如:

  1. 使用 Vue.directive(Name, [Define]),自定义指令,添加全局资源,如 vue-touch可以看我总结的这篇文章

  2. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。

  3. 添加全局方法或者属性,如: vue-element

  4. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router

手把手教你写 Vue UI 组件库的更多相关文章

  1. 16款优秀的Vue UI组件库推荐

    16款优秀的Vue UI组件库推荐 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基 ...

  2. 为公司架构一套高质量的 Vue UI 组件库

    有没有曾遇过,产品要我们实现一个功能,但是 iview 或者 elementui 不支持,我们然后义正言辞的说,不好意思,组件库不支持,没法做到. 有没有曾和设计师争论得面红耳赤,其实也是因为组件库暂 ...

  3. 强烈推荐优秀的Vue UI组件库

    Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基于Vue的UI组件框架开发,并投入正 ...

  4. 【转】优秀的Vue UI组件库

    原文来源:https://www.leixuesong.com/3342 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司 ...

  5. Vue UI组件库

    1. iView UI组件库  iView官网:https://www.iviewui.com/ 2.Vux UI组件库   Vux官网:https://vux.li/ 3.Element UI组件库 ...

  6. 前端如何搭建vue UI组件库/封装插件(从零到有)

    需求 因之前是做外包项目居多,经常用到相同的组件,之前的办法是在一个项目中写一个组件,其他项目直接将compents下的组件复制,粘贴到项目中使用,缺点是维护起来,改一个项目,其他项目也需要修改,所以 ...

  7. 创建一个自己的Vue UI组件库,并将它发布在npm上

    本文仅限于入门级,没有成规模制作,希望能对你有所帮助. 因为在开发多个项目中可能会用到同一个组件,那么我们通过复制粘贴的形式更新,无异于是笨拙的,我们可以通过上传到npm后,不断迭代npm包来实现更新 ...

  8. 手把手教你写vue插件并发布(一)

    vue的插件开发 这篇文章较长,需要一定的阅读时间.这里有一份改善版本的插件笔记,在一个项目下完成开发.测试.发布的全过程.https://www.cnblogs.com/adouwt/p/96555 ...

  9. 仿写vue UI 组件总结 (自己练习,仿照现有的UI组件)

    UI组件 Vue开发插件流程 本来是昨天要写总结的,感觉自己写不好,就放弃了.今天看到了iview和element有一些摩擦,是关于代码借鉴的问题(哈哈),不做评价.谁下生会写组件,我仿(chao)写 ...

随机推荐

  1. 前端基础 之css

    css 介绍 css(层叠样式表)定义如何显示html 元素 当浏览器读到一个样式表, 他就会按照这个表对文档进行格式化(渲染) css语法 css实例 css 注释 注释是代码之母 /* 这是注释* ...

  2. msql 初识数据库

    一 数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中, 毫无疑问, 一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题, 并且假设程序所有 ...

  3. 1079 Total Sales of Supply Chain (25 分)

    A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...

  4. Cannot set headers after they are sent to the client

    D:\le\node_modules\mysql\lib\protocol\Parser.js: throw err; // Rethrow non-MySQL errors ^ Error [ERR ...

  5. C++ STL map使用

    Map是c++的一个标准容器,它提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作!1. map构造函数:map<string , in ...

  6. NITACMOJ144稳定串

    点我>>题目链接 稳定串 Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java ...

  7. 打包时,指定war包的名称

    在pom.xml中修改finalName节点的值即可,如下: <build> <plugins> <plugin> <groupId>org.sprin ...

  8. OPENGL3_基本图元

    类型 说明 GL_POINTS 单个顶点集 GL_LINES 多组双顶点线段 GL_POLYGON 单个简单填充凸多边形 GL_TRAINGLES 多组独立填充三角形 GL_QUADS 多组独立填充四 ...

  9. 3d工具收集

    Poser 是Metacreations公司推出的一款三维动物.人体造型和三维人体动画制作的极品软件.用过Poser 2与Poser 3的朋友一定能感受到Poser的人体设计和动画制作是那么的轻松自如 ...

  10. [Xcode 实际操作]七、文件与数据-(21)ARKit增强现实框架的使用

    目录:[Swift]Xcode实际操作 本文将演示ARKit增强现实框架的使用. 创建一个新的项目:[Create a new Xcode project] ->在打开的模板选择中,选择增强现实 ...