purpose
The purpose of on-demand import is to introduce only the components used to reduce the size of the project.
Realize the principle of
For example: babel-plugin-component
practice
The toast component is special. Other components are usually used with labels after registration. Whereas toast needs to be used in the project through this.xxx.toast.show() or similar methods.
Developing the TOAST component
File structure:
// main.vue <template> <! --> <transition name=" toasts-from-top "> <div class="my-toast" v-show="show"> <div Class =" my-toasts-content "> This is a toast ~ </div> </div> </transition> </template> <script> export default {name: 'MyToast', data () {return {time: 2000, // toast display timer: null, // show: false // toast display}}, watch: { show (val) { if (val) { this.timer = setTimeout(() => { this.show = false this.timer = null }, this.time) } } } } </script> <style scoped> .my-toast { position: fixed; top: 25%; width: 100%; text-align: center; } .my-toast-content { display: inline-block; max-width: 80%; box-sizing: border-box; padding: 10px; background-color: hsla(0, 0%, 7%, .7); color: #fff; border-radius: 3px; } .toast-from-top-enter-active, .toast-from-top-leave-active { transition: all .5s; } .toast-from-top-enter, .toast-from-top-leave-to { transform: translateY(-100%); opacity: 0; } </style>Copy the code
// index.js
import main from './src/main'
let instance
const plugin = {
// vue. use will call this method
install (Vue) {
const Toast = Vue.extend(main)
if(! instance) {// Create toast component instance
instance = new Toast({
el: document.createElement('div')})// Add toast dom to the body
document.body.appendChild(instance.$el)
}
const toast = {
show (options = {}) {
if (instance.timer) {
return
}
let defaults = {}
for (let key in instance.$options.props) {
defaults[key] = instance.$options.props[key].default
}
Object.assign(instance, defaults, options)
/ / show the toast
instance.show = true}}if(! Vue.$myui) { Vue.$myui = { toast } }else {
Vue.$myui.toast = toast
}
$myUI = this.$myui.toast.show(...); $myui.toast.show(...); Shows the
Vue.mixin({
created () {
this.$myui = Vue.$myui
}
})
}
}
export default plugin
Copy the code
SRC index.js will also need to be modified, because this file is imported globally.
// src/index.js
'use strict'
import MyButton from './components/my-button'
import MyToast from './components/my-toast'
const components = [
MyButton
]
const plugins = [
MyToast
]
const install = function (Vue) {
components.forEach(component= > {
Vue.component(component.name, component)
})
plugins.forEach(plugin= > {
Use calls the install method in plugin
Vue.use(plugin)
})
}
export default {
install
}
Copy the code
At this point, you can write examples in Example and add the necessary routes.
</my-button @click="clickFunc"> </my-button> </div> </template> <script> export default { name: 'example-button', methods: { clickFunc () { this.$myui.toast.show({ text: 'This is a Toast'})}}} </script> <style scoped> </style>Copy the code
Effect:
Configuration Webpack
The idea is to configure multiple entries using the index.js entry in each component folder, and then package each component into the Lib folder.
Create a new build-components.js file
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'publish'
const ora = require('ora')
const rm = require('rimraf')
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
let webpackConfig = require('./webpack.publish.conf')
let config = require('.. /config')
function getFolders (dir) {
return fs.readdirSync(dir).filter(function (file) {
return fs.statSync(path.join(dir, file)).isDirectory()
})
}
const spinner = ora('building for production... ')
spinner.start()
rm(path.join(config.publish.distRoot, 'lib'), err => {
if (err) throw err
})
// Get the list of component folder names
const folders = getFolders(path.join(__dirname, '.. /src/components'))
const originEntry = Object.assign(webpackConfig.entry)
const originOutput = Object.assign(webpackConfig.output)
// Iterate over the number group and add it to the entry
webpackConfig.entry = {}
for (let i = 0; i < folders.length; i++) {
let componentName = folders[i]
if(! webpackConfig.entry[componentName]) { webpackConfig.entry[componentName] =`./src/components/${componentName}/index.js`
}
}
webpackConfig.output.path = path.join(config.publish.distRoot, 'lib')
webpackConfig.output.filename = '[name].js'
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true.modules: false.children: false.chunks: false.chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red('Build failed with errors.\n'))
process.exit(1)}console.log(chalk.greenBright(`$Build components successfully! \n`))
webpackConfig.entry = originEntry
webpackConfig.output = originOutput
})
Copy the code
test
To test the effects of the component, create a new project: TestMyComponent. Initialize the project as before.
Then I installed the developed and packaged component library. I put the component library on my Github and used the Github link to install it.
npm install https://github.com/NicholasCui/MyComponent.git -S
Copy the code
Introducing component libraries in main.js:
// ...
import MyComponent from 'my-component'
Vue.use(MyComponent)
// ...
Copy the code
Using component libraries in app.vue:
<template> <div id="app"> <my-button @click="clickFunc"> button </my-button> <my-button @click="toastFunc"> toast </my-button> </div> </template> <script> export default { name: 'App', methods: { clickFunc () { alert('click') }, toastFunc () { this.$myui.toast.show({ text: </script> <style> </style>Copy the code
The effect is as follows:
TestMyComponent
babel-plugin-component
npm i babel-plugin-component -D
Copy the code
Add configuration to. Babelrc, see babel-plugin-Component for more configuration
{/ /... "plugins": [ // ... [ "component", { "libraryName": "my-component", "libDir": "lib", "style": false }, "my-component" ] ] }Copy the code
Modify the main js
// All comments are introduced
// import MyComponents from 'my-component'
// Vue.use(MyComponents)
/ / only introducing the toast, without introducing button, my - button labels complains
import {
// MyButton,
MyToast
} from 'my-component'
// Vue.use(MyButton)
Vue.use(MyToast)
Copy the code
Effect:
we-button
toast
toast
we-button
conclusion
What impressed me most was that there was still a lot to learn.