Most of the time we don’t need to build our own wheels, but there may be special cases where we want to have custom UI components. Here I make a basic Button component with VUE and publish it to NPM, then try using the UI component.
Need to pre –
- vue-cl3
- NPM account password
npm install -g @vue/cli
# OR
yarn global add @vue/cli
Copy the code
Create a project
Run the vue curete bkyz-UI Manually select features command
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
( ) Router
( ) Vuex
(*) CSS Pre-processors
(*) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
Copy the code
Press space to select, enter to enter the next step.
Of the remaining options, my choice is:
Code style — ESLint + Standard Config format detection — Lint on Save Configuration file generation — In package.json Whether to Save preconfiguration — No
Configuration depends on personal preference, then press Enter to generate a complete project.
Create a packages directory in the root directory to hold the UI components we want to develop; Create a local directory in the root directory to test the effect of referencing our own UI components. Since we changed the directory structure of the original project, the corresponding directory could not be found for the local operation and packaging of the system. Therefore, we need to create a vue.config.js folder in the root directory of the project to manually modify the Webpack configuration and make the local operation and packaging of the system normal.
// vue.config.js const path = require('path'); module.exports = { pages: { index: { entry: 'local/main.js', template: 'public/index.html', filename: 'index.html' } }, chainWebpack: config => { config.module .rule('js') .include.add(path.resolve(__dirname, 'packages')).end() .use('babel') .loader('babel-loader') .tap(options => { return options; }}})Copy the code
Production of components
Create two new folders, Button, Fonts and an index.js file in the Packages folder. Edit packages/index. Js
// packages/index.js import Button from './ Button 'import './fonts/ font-scss' // store component list const Components = [Button] // Define the install method that accepts Vue as an argument. If you use use to register your plug-in, Const install = function (Vue) {forEach(component => {Vue.component(component.name, Component)})} // Check whether the file is imported directly if (typeof window! == 'undefined' && window.vue) {install(window.vue)} export default {// The exported object must have install, Use () method to install, Button}Copy the code
Create index.js in the button folder to export the component
Import Button from './ SRC /button.vue' Install = function (Vue) {Vue.component(button.name, Button)} export default ButtonCopy the code
Edit packages/button/SRC/button. Vue
<template> <button class="mc-button"> <! <span v-if="$slots.default"><slot></slot></span> </button> </template> export default {name: 'McButton', props: {} }Copy the code
Then create a new SRC folder and put the Button component, which is just a normal Vue file and will continue to add properties to improve the component.
button type
The common types are: primary/SUCCESS/warning/danger/info/text
We use an array of dynamically typed bindings
<template> <button class="mc-button" :class="[ `mc-button--${type}` ]"> ... </button> </template> <script> export default { ... props: { type: { type: String, default: 'default' } } } </script> <style lang="scss'> .mc-button { display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: #fff; border: 1px solid #dcdfe6; color: #606266; -webkit-appearance: none; text-align: center; box-sizing: border-box; outline: none; margin: 0; The transition: 0.1 s; font-weight: 500; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; padding: 12px 20px; font-size: 14px; border-radius: 4px; &:hover, &:focus { color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff; } &--primary {} &--success {} &--warning {} &--info {} &--danger {} } </style>Copy the code
This enables different types of button styles
Add rounded corners
<button
class="mc-button"
:class="[
`mc-button--${type}`,
{
...
'is-round': round
}
]">
...
</button>
Copy the code
Add a round parameter, which is skipped here, and add a rounded corner
&.is-round {
border-radius: 20px;
padding: 12px 23px;
}
Copy the code
Similarly, circular buttons can be implemented, whether to disable, add ICONS, I will not write in detail here.
<template> <button class="mc-button" :disabled="disabled" @click="handleClick" :class="[ `mc-button--${type}`, { 'is-plain': plain, 'is-round': round, 'is-circle': circle, 'is-disabled': disabled } ]"> <i :class="icon" v-if="icon"></i> <! <span v-if="$slots.default"><slot></slot></span> </button> </template>Copy the code
Run the project
Now run local and see what happens. Improve the previous local folder content, add app. vue, man.js, testButton. vue three files. App.vue takes the McButton component from testButton and shows it
// local/App.vue
<template>
<div id="app">
<test-buttons></test-buttons>
</div>
</template>
<script>
import TestButtons from './TestButton'
export default {
name: 'app',
components: {
TestButtons
}
}
</script>
<style lang="scss">
</style>
Copy the code
Main.js is the entry file
// local/main.js import Vue from 'Vue' import App from './ app. Vue 'import BkyzUI from '.. /packages' Vue.config.productionTip = false Vue.use(BkyzUI) new Vue({ render: h => h(App) }).$mount('#app')Copy the code
With the introduction of packages component libraries, TestButton.vue can use Mc-button directly
<template> <div class="app"> <div class="row"> < Mc-button type="primary"> </ Mc-button > < Mc-button type="success"> < Mc-button type="info"> </ Mc-button > < Mc-button type="warning"> / /... </div> </div> </template> <script> export default { name: 'TestButtons' methods: { } } </script> <style lang="scss" scoped> .app { width: 600px; height: 200px; display: flex; flex-direction: column; justify-content: center; align-items: center; margin-top: 100px; } .row { padding: 10px 0; } .mc-button { margin-left: 10px; } </style>Copy the code
After executing NPM Run serve, open the page and you can see that the external custom components are available in the project.
packaging
In the official documentation of VUE-CLI3 there is a build objective that clearly states how to package it as an application or a library! At this point, we need to add a package command to package.json
Vue-cli-service build --target lib Specifies the package fileCopy the code
The console then executes yarn Lib to package the external component libraries, including font ICONS, to create a dist folder.
Since we develop component libraries for others to use, we don’t have to publish all of our code to NPM. So we need to create a.npmignore file in the root directory of the project and ignore those file uploads
//.npmignore # ignores directory local/ packages/ public/ # ignores the specified file vue.config.js babel.config.js *.map.editorconfig.jsCopy the code
Edit package.json and add main to make it easier for others to find the packaged file when downloading it
{
"main": "dist/bkyz-ui.umd.min.js",
...
}
Copy the code
My Git repository click
Note:
- When uploading to NPM, change the private property in package.json to false
- During package iteration, modify the version number in package.json before executing the publish command
Published to the NPM
Note: because we want to upload NPM, so the local NPM source should use the original source, not taobao source or other sources
NPM config get registry / / view the NPM mirror current source NPM config set registry / / set to NPM source at https://registry.npmjs.org/Copy the code
Execute NPM login on the console and NPM publish after login. Publish.
Use our custom component library
Once published, you can try it out. Again, try vue’s Web project here. Create a new vue101 project, skip the process, and reference it in main.js
import Vue from 'vue'
import App from './App.vue'
import BkyzUI from 'bkyz-ui'
Vue.config.productionTip = false
Vue.use(BkyzUI)
new Vue({
render: h => h(App),
}).$mount('#app')
Copy the code
Modify the helloWorld.vue file
<template> <div class="hello"> < Mc-button plain @click="handleClick"> font </ Mc-button > < Mc-button </ button> < Mc-button icon=" Mc-icon-check "circle plain type="primary"></ Mc-button ></ div> </template> <script> import 'bkyz-ui/dist/bkyz-ui.css' import Bkyz from 'bkyz-ui' export default { name: 'HelloWorld', methods: { handleClick() { console.log('click'); } }, props: { msg: String } } </script>Copy the code
If it is quoted on demand:
<template> <div class="hello"> < Mc-button plain @click="handleClick"> font </ Mc-button > < Mc-button </ button> < Mc-button icon=" Mc-icon-check "circle plain type="primary"></ Mc-button ></ div> </template> <script> import 'bkyz-ui/dist/bkyz-ui.css' import Bkyz from 'bkyz-ui' export default { name: 'HelloWorld', components: { McButton: Bkyz.Button }, methods: { handleClick() { console.log('click'); } }, props: { msg: String } } </script>Copy the code
Take a look at the page
reference
- Build your own UI framework from scratch – publish to NPM
- Vue components publish NPM best practices