自定义vue.js全局组件库(仿MintUI)

在项目开发中,我们总会引入很多别人封装好的组件模板,使用时仅仅三步,第一步就是install,第二步在main.js里面引入,第三步Vue.use这个组件。例如MintUI,试想我们是否可以自己仿照MintUI写一个自己的组件同样让别人使用,设置成全局组件呢?下面就依照MintUI编写自己的组件库。

1. 创建组件模板

image

如上图,创建了两个组件模板Loading和MyButton,组件模板代码以Loading为 :

//Loading组件模板

  <template>
    <transition name="mint-indicator">
      <div class="mint-indicator" v-show="visible">
        <div class="mint-indicator-wrapper" :style="{ 'padding': text ? '20px' : '15px' }">
          <div class="loader">
            <div class="loader-inner ball-spin-fade-loader">
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
            </div>
          </div>
          <!--<spinner class="mint-indicator-spin" :type="convertedSpinnerType" :size="32"></spinner>-->
          <span class="mint-indicator-text" v-show="text">{{ text }}</span>
        </div>
        <div class="mint-indicator-mask" @touchmove.stop.prevent></div>
      </div>
    </transition>
  </template>
<script>
  export default {
    name: 'Loading',
    data(){
      return{
        visible:true,
        text:'加载中'
      }
    }
  }
</script>

<style scoped>
  .mint-indicator {
     -webkit-transition: opacity .2s linear;
    transition: opacity .2s linear;
  }
  .mint-indicator-wrapper {
    top: 50%;
    left: 50%;
    position: fixed;
     -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    border-radius: 5px;
    background: rgba(0, 0, 0, 0.4);
    color: lightgray;
    box-sizing: border-box;
    text-align: center;
    border: 1px solid lightgray;
  }
  .mint-indicator-text {
    display: block;
    color: white;
    text-align: center;
    font-size: 16px;
  }
  .mint-indicator-spin {
    display: inline-block;
    text-align: center;
  }
  .mint-indicator-mask {
    top: 0;
    left: 0;
    position: fixed;
    width: 100%;
    height: 100%;
    opacity: 0;
    background: transparent;
  }
  .mint-indicator-enter, .mint-indicator-leave-active {
    opacity: 0;
  }
  .loader{
    width:30px;
    height: 30px;
    margin-left: 20px;
  }
  @keyframes ball-spin-fade-loader {
    50% {
      opacity: 0.3;
      -webkit-transform: scale(0.4);
      transform: scale(0.4); }

    100% {
      opacity: 1;
      -webkit-transform: scale(1);
      transform: scale(1); } }

  .ball-spin-fade-loader {
    position: relative; }
  .ball-spin-fade-loader > div:nth-child(1) {
    top: 10px;
    left: 0;
    -webkit-animation: ball-spin-fade-loader 1s 0s infinite linear;
    animation: ball-spin-fade-loader 1s 0s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(2) {
    top: 7.04545px;
    left: 7.04545px;
    -webkit-animation: ball-spin-fade-loader 1s 0.12s infinite linear;
    animation: ball-spin-fade-loader 1s 0.12s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(3) {
    top: 0;
    left: 10px;
    -webkit-animation: ball-spin-fade-loader 1s 0.24s infinite linear;
    animation: ball-spin-fade-loader 1s 0.24s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(4) {
    top: -7.04545px;
    left: 7.04545px;
    -webkit-animation: ball-spin-fade-loader 1s 0.36s infinite linear;
    animation: ball-spin-fade-loader 1s 0.36s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(5) {
    top: -10px;
    left: 0;
    -webkit-animation: ball-spin-fade-loader 1s 0.48s infinite linear;
    animation: ball-spin-fade-loader 1s 0.48s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(6) {
    top: -7.04545px;
    left: -7.04545px;
    -webkit-animation: ball-spin-fade-loader 1s 0.6s infinite linear;
    animation: ball-spin-fade-loader 1s 0.6s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(7) {
    top: 0;
    left: -10px;
    -webkit-animation: ball-spin-fade-loader 1s 0.72s infinite linear;
    animation: ball-spin-fade-loader 1s 0.72s infinite linear; }
  .ball-spin-fade-loader > div:nth-child(8) {
    top: 7.04545px;
    left: -7.04545px;
    -webkit-animation: ball-spin-fade-loader 1s 0.84s infinite linear;
    animation: ball-spin-fade-loader 1s 0.84s infinite linear; }
  .ball-spin-fade-loader > div {
    background-color: white;
    width: 7px;
    height: 7px;
    border-radius: 100%;
    margin: 2px;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    position: absolute; }
</style>

2. 在组件加载入口的index.js文件里面添加install方法

import LoadingComponent from './Loading'
import myButton from './MyButton'
const Loading = {
  install: function (Vue) {
    Vue.component('Loading', LoadingComponent)
  }
}
const MyButton = {
  install: function (Vue) {
    Vue.component('MyButton', myButton)
  }
}

// 导出组件
export {
  Loading,
  MyButton
}

注:上面我引入了两个组件,也可以引入更多组件,如果只有一个组件时,我们用export default,两个或多个时用export {}的方法。

3. webpack首先会加载main.js,所以在main的js里面引入

import MintUI from 'mint-ui'
Vue.use(MintUI)

import {Loading,MyButton} from "./components/loading/index"
Vue.use(Loading)
Vue.use(MyButton)

注:用export default引入时,只需要用上面import MintUI from 'mint-ui'方式,如果用export引入,只能时import {Loading,MyButton}的形式。

4. 使用组件

<template>
  <div>
    <Loading></Loading>
    <MyButton></MyButton>
  </div>
</template>

5. 渲染后的效果图:

image

在此提醒注意引入路径问题,./表示当前目录 ../表示父级目录。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券