preface

How to make a Vuejs UI component library? Recently, I was itching for something to do, and then I had the idea to imitate gourd gourd gourd gourd gourd gourd gourd (standing on the shoulders of giants copy), and summarize and record the process of this construction myself

The premise

  1. You have to at least know vUE
  2. Simply encapsulate some components
  3. They brag
  4. Would give me a thumbs up

All right, four points. That’s enough

Create a vUE project

If vue-CLI doesn’t quite fit your needs, you can create your own

We will use vue-CLI directly here

// Create a cli vue create laoyan-uiCopy the code

Manual selection configuration

Just choose Babel and CSS preprocessors

Select the node – sass

Select package. Json

Does it feel like going back to when you first learned vUE? Right! It’s the teaching of pure hands

Good nonsense not to say, create good, together to make it

Changing the file name

Well, we entered the project directory just created, first do not worry about the start of the project, we have to learn to plan big orange 🍊, and then pay action

New packages

Create a new folder called Packages to store the components where most of our component development work will be done

Modify the SRC

Change the SRC folder to examples, examples we use for testing

New vue. Config. Js

module.exports = {
    pages: {
      index: {
        // Modify the entry
        entry: 'examples/main.js'.template: 'public/index.html'.filename: 'index.html'}},chainWebpack: config= > {
        config.module
          .rule('js')
          .include
            .add('/packages')
            .end()
          .use('babel')
            .loader('babel-loader')
            .tap(options= > {
              return options
          })
     }
}
Copy the code

Clean up what you don’t need

Delete logo. PNG from the Examples/Assets folder

Remove the examples Components directory

Delete the examples app.vue as follows

<template>
  <div id="app">
    app.vue
  </div>
</template>

<script>

export default {
    name: 'App',}</script>
Copy the code

Directory Structure Screenshot

Start the project

yarn serve
Copy the code

When the startup is complete, open the browser

At this point, you’re almost done preparing for the component library

Began to work

All of our components are in the Packages directory, so the directory structure must look like this

|packages
|--- aComponent
|--- bComponent
|--- cComponent
Copy the code

So we need an index.js file to import these components and then expose them

Let’s write a component (a text link) to ensure that the component can be used normally

Write a text link

Let’s call the component ly-link for a moment

|packages
|--- aComponent
|---|--- index.vue
Copy the code

Write index.vue like this bird

<template>
    <! -- use href to jump to --> <! -- Change the color with the type passed --> 
    <a :href="href || undefined" :class="[`ly-link-${type}`]" >
        <! -- Use default slot to fill text -->
        <slot/>
    </a>
</template>

<script>
    export default {
        // we'll use it in index.js
        name:"lyLink".props: {
            // Restrict the type
            href: String.type: {
                type: String.default: 'default'}}}</script>

<style lang="scss" scoped>// Define the link font color.ly-link-default {
        color: # 606266;
    }
    .ly-link-primary {
        color: #409eff;
    }
</style>
Copy the code

Then let’s test it out in examples/ app.vue

<template>
  <div id="app">
    <ly-link type="primary">Old strict link</ly-link>
  </div>
</template>

<script>
import lyLink from '.. /packages/lyLink/src'
export default {
    name: 'App'.components: { lyLink }
}
</script>
Copy the code

See the effect

It doesn’t seem to be a problem, but let’s take a closer look at it. We should have imported it globally from main

Create index. Js

Okay, so let’s go back to index.js, where we use index.js as the main exposure

// Import components
import lyLink from './lyLink/src'
// An array of components
const components = [
    lyLink
]

// Define the install method that accepts Vue as an argument.
const install = function (Vue) {
    // Determine whether to install it
    if (install.installed) return
    // Iterate through the Components array for global registration
    components.map(component= > {
        Vue.component(component.name, component)
    })
}

export default {
    // Exported objects must have install to be installed by vue.use ()
    install,
    lyLink
}
Copy the code

Then we go to main.js and import the index.js file we just wrote

import Vue from 'vue'
import laoyanUi from '.. /packages';
Vue.use(laoyanUi)
Copy the code

Remove the import and registration components from app.vue

<template>
  <div id="app">
    <ly-link type="primary">Old strict test</ly-link>
  </div>
</template>

<script>
export default {
    name: 'App'
}
</script>
Copy the code

That’s still okay, right?!

So the requirement comes in, the user now needs to import components on demand, how do you do that?

What on demand? Call me

According to the need to introduce

Components are introduced here on demand

Thanks to @qingyang big guy for pointing out the bug of on-demand import, you can skip ahead and view today’s updated component on-demand import point here

Ok, so we come to the introduction on demand

We usually use a lot of UI component libraries in the market, usually there is an on demand introduction

Such as element – the UI

import { Button, Select } from 'element-ui'
Copy the code

So how do you achieve on-demand import?

In the corresponding component folder, add another index.js

// Import components
import lyLink from './src';

// Provide the install installation method, which can be imported on demand
lyLink.install = function (Vue) {
    // Register the component
    Vue.component(lyLink.name, lyLink)
}
// Expose the component
export default lyLink
Copy the code

Your packages should look like this

Then we go outside to packages\index.js

Change the imported vue file to import index.js and expose install by default

+ import lyLink from './lyLink'Const Components = [lyLink] // Define the install method that accepts Vue as an argument. If you use use to register your plug-in, Const install = function (Vue,opt = {}) {if (install.installed) return // iterate through registered global components components.map(component => { Vue.component(component.name, component) }) }+ export default install

+ export {// The exported object must have install in order to be installed by vue.use ().Copy the code

Try it on demand

import { lyLink } from '.. /packages';
Vue.use(lyLink)
Copy the code

The effect is also ok

Introduced the CDN

Every time we do project optimization, there is a CDN optimization, so how should we configure this CDN introduction?

Import lyLink from './lyLink' const components = [lyLink] // Define the install method that accepts Vue as an argument. If you use use to register your plug-in, Const install = function (Vue,opt = {}) {if (install.installed) return // iterate through registered global components components.map(component => { Vue.component(component.name, component) }) }+ // Check whether the file is imported directly
+ if (typeof window ! == 'undefined' && window.Vue) {
+ install(window.Vue)
+}Export default install export {// The exported object must have install to be installed by vue.use () method, // The following is the list of specific components lyLink}Copy the code

Add this layer of judgment can be, Yan Lao shi how we upload CDN? We’ll talk about how to use this later, right

Packaged component library

How to pack it? yarn build? I thought that was a package project

We need to add a new command to package.json

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
+ "lib": "vue-cli-service build --target lib --name index --dest lib packages/index.js"
},
Copy the code

Perform packaging

This command will package our components into a lib folder

yarn lib
Copy the code

Once packaged, let’s try importing components from the lib folder

Try the effect

Introduced in main.js

import Vue from 'vue'
import App from './App.vue'
import { lyLink } from '.. /lib/index.umd.min.js';
Vue.use(lyLink)
Vue.config.productionTip = false

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

Start the project

yarn serve
Copy the code

We have successfully parsed the component. But we found a problem, we don’t seem to have a style

Because we haven’t introduced styles yet

  import Vue from 'vue'
+ import App from './App.vue'import { lyLink } from '.. /lib/index.umd.min.js'; import '.. /lib/index.css' Vue.use(lyLink) Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')Copy the code

I think we’re done

Release the component

Publishing components we typically publish to NPM

Create npmignore.

But we need to create a.npmignore file to ignore uploading part of the file

# omit examples/ packages/ public/ dist/ common/ # omit the specified file vue.config.js babel.config.js *.mapCopy the code

Ok, now we can upload the NPM package

Landing NPM

npm login
Copy the code

We landed successfully! So the next thing

Publish a package

There’s one more thing you need to do before you release the package

Change the private in your package.json to false, which indicates whether the package is private

- "private": true,
+ "private": false,
Copy the code

Change the entry file to js under lib, otherwise download dependencies will not find your component

"main": "lib/index.umd.min.js".Copy the code

Perform publish

npm publish
Copy the code

There are many difficult and complicated problems in the release package, I hope you can smoothly Baidu Google to, here I will not say

Install dependencies

You can re-create a VUe-CLI to download your dependency packages

yarn add laoyan-ui
Copy the code

The introduction of

Once the download is complete, import it in main.js

import { lyLink } from 'laoyan-ui'
import 'laoyan-ui/lib/index.css'
Vue.use(lyLink)
Copy the code

The effect

Test it out on any page

<ly-link type="primary" href="//lovemysoul.vip/votre-dieu">test link</ly-link>
Copy the code

At this point we have completed most of the flow of the UI component library

But what about the introduction of CDN that we talked about earlier?

Use the CDN

Let’s create a new index. HTML, https://unpkg.com, which you can understand as NPM’s built-in CDN

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>test laoyan-ui</title>
    <! Vue -->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.6/vue.min.js"></script>
    <! -- Introducing laoyan-UI components -->
    <script src="https://unpkg.com/laoyan-ui/lib/index.umd.min.js"></script>
    <! -- Introduce laoyan-UI style -->
    <link rel="stylesheet" href="https://unpkg.com/laoyan-ui/lib/index.css">
</head>
<body>
    <div id="app">  
        <ly-link type="primary"> test laoyan-ui </ly-link> 
    </div>
    <script>
        let vm = new Vue({
            el:"#app"
        })
    </script>
</body>
</html>
Copy the code

Note: In production environment, it is recommended to add the version number when importing CDN, such as: //unpkg.com/[email protected]@0.1.0 is the locked version number, which can lock the version you imported to ensure stability

The last

That’s all for today’s lesson. It’s nearly one o ‘clock in the morning and it’s time to go to bed

If you think this is a good article, give me a thumbs up

If there are any mistakes in this article, please don’t hesitate to mention them, and Lao Yan will correct them in time

The current GitHub project is at github.com/votre-dieu/…

Welcome PR, Star, Fock