even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在vue2的环境下封装自己的组件库

a、初始化项目 

vue环境的安装 

npm i @vue/cli -g
vue create yutest-ui --也可以通过vue ui创建,创建一个默认的vue2库即可

因为需要开发组件库,那么就需要对原有的目录结构作些调整

---将src目录变更为examples文件夹

---在examples的同级目录下新建文件夹packages文件夹

---添加vue.config.js文件,需要对原有的配置作一些调整具体调整如下

 vue.config.js的内容如下

module.exports = {
    pages: {
        index: {
            entry: 'examples/main.js',
            template: 'public/index.html',
            filename: 'index.html'
        }
    },
    // 扩展 webpack 配置,使 packages 加入编译
    chainWebpack: config => {
        config.module
            .rule('js')
            .include
            .add('/packages')
            .end()
            .use('babel')
            .loader('babel-loader')
            .tap(options => options)
    }
}

 注意:以上内容把编译的入口作了调整,由原来的src变为examples,声明template的路径,同时把packages加入编译

b、编写组件

packages/Button/src/index.vue

<template>
<div class="x-button">
    <slot></slot>
</div>
</template>

<script>
export default {
    name: 'XButton',  //注意,这里需要用的驼峰命名,尽量不要使用-拼接,方便后面组件的调用
    props: {
        type: String
    }
}
</script>

<style scoped>
.x-button {
    display: inline-block;
    padding: 3px 6px;
    background: #000;
    color: #fff;
}
</style>

packages/Button/index.js

// 导入组件,组件必须声明 name
import XButton from './src'

// 为组件提供 install 安装方法,供按需引入
XButton.install = function (Vue) {
    Vue.component(XButton.name, XButton)
}

// 导出组件
export default XButton

注意:在组件中packages/Button/index.js可以省略,如果是组件库,直接是Button / index.vue即可, 这样一个简单的组件就开发完成了

c、实现组件的入口文件

package/index.js

// 导入button组件
import XButton from './Button'

// 组件列表
const components = [
    XButton
]

// 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,那么所有的组件都会被注册
const install = function (Vue) {
    // 判断是否安装
    if (install.installed) return
    // 遍历注册全局组件
    components.forEach(component => Vue.component(component.name, component))
    install.installed = true;
}

// 判断是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue)
}

export {
    XButton  //局部引用
}

export default install //全局引用

d、测试代码

在examples/main.js

import Vue from 'vue'
import App from './App.vue'
import yutest_ui from '../packages'

Vue.config.productionTip = false

Vue.use(yutest_ui)

new Vue({
  render: h => h(App),
}).$mount('#app')

进行全局引入后就可以进行使用测试了,也可以不用全局引入进行局部引入  import { XButton } from '../../packages' 然后组件注册后进行使用

 e、配置package.json文件

vue-cli-service build --target lib --name myLib [entry]

 注意:需要添加main字段

f、添加.npmignore文件

这个文件相当是忽略指定的文件,不上传到npm上,写法类似.gitignore

examples/
node_modules/
packages/
public/
.gitignore
babel.config.js
vue.config.js
*.map

g、后续工作

npm run lib  //进行构建项目
npm login
npm publish

注意:在npm login的时候需要的源从淘宝镜像切换到npm上,并且使用已有的npm账号,这个账号是已经用邮箱验证过了的,否则发布会失败

 

vue3环境下的插件的编写

在vue3环境下的插件编写与vue2的插件编写大体一致,但是vue3对use这个方法做了一些微调整,所以上面插件的写法只需要调整packages里的index.js的入口文件即可

<script>

const myPlugin = {
    install(app, options) { // 这样就可以通过这个方法进行组件的注册
        console.log(app, options)
        app.provide('info', options)  //可以对所有的组件注入对象

        // app.directive('focus')    //可以进行扩展指令

        // app.mixin()  //可以对全局进行混入

        app.config.globalProperties.$say = () => {  // 对vue的全局属性进行扩展
            console.log('say')
        }
    }
}

//当然myPlugin也可以是一个函数

// const myPlugin = (app, options) => {
//     // ...以上的方法
// }


const app = Vue.createApp({
    template: `<div>name---{{info.name}}, age---{{info.age}}</div>`,
    // inject: ['info'],
    inject: {
        'info': {
            from: 'info',
            default: () => ({})
        }
    },
    created() {
        console.log(this)
        this.$say()
    }

})

app.use(myPlugin, {name: 'bill', age: 30})  //第二个参数将会以option的形式传递给install这个方法,以第二个参数的形式存在

app.mount('#root')
</script>

 应用示例,利用以上方法实现一个较验器

const myPlugin = (app, options) => {
   app.mixin({
        created() {
            this.ruleValidate()
        },
        methods: {
            ruleValidate() {
                if(!this.$options.rules) return;
                Object.keys(this.$options.rules).forEach((val) => {
                    this.$watch(val, current => {
                        let result = this.$options.rules[val].validate(current);
                        !result && console.log(this.$options.rules[val].message)
                    })
                })
            }
        }
   })
}


const app = Vue.createApp({
    template: `<div>name---{{name}}, age---{{age}}</div>`,
    data() {
        return {
            name: 'bill',
            age: 30
        }
    },
    rules: {
        age: {
            validate: age => age < 20,
            message: "年龄不能超过20"
        },
        name: {
            validate: name => name.length > 3,
            message: '名字太短'
        }
    }

})

app.use(myPlugin)  //第二个参数将会以option的形式传递给install这个方法,以第二个参数的形式存在

const vm = app.mount('#root')

 

posted on 2021-05-16 21:13  even_blogs  阅读(137)  评论(0编辑  收藏  举报