zoukankan      html  css  js  c++  java
  • vue封装组件的正确方式-封装类似elementui的组件

    最近读了下element的源码,仿照他封装了两种不同的组件。

    第一种:通过组件来调用显示的

    <template>
    <!--src/component/custom/main.vue-->
        <div class = "contine">
            <p class = "title">
                {{title}}
            </p>
            <slot class = "contine" name = "contine">
    
            </slot>
        </div>
    </template>
    
    <script>
    export default {
        name:"test-component",
        props:{
            title:{
                type : String,
                default:"组件标题"
            }
        }
    }
    </script>
    
    <style lang="scss" scoped>
        $black : #333;
        $mainSize : 16px;
        $mainLineHeight:30px;
        $lineCenter:center;
        .extendStyle {
            border-radius:$mainSize;
            box-shadow: 3px 3px 3px 3px #333;
        }
        .contine{
            50%;
            height:130px;
            color:$black;
            font-size:$mainSize;
            @extend .extendStyle;
            .title,.contine{
                color:$black;
                font-size:$mainSize;
                text-align:$lineCenter;
                line-height:$mainLineHeight;
    
            }
        }
    </style>

    组件说明:只是一个简单的组件 显示一个标题和一段自定义slot内容(仅用作展示);我想通过以下方式引入

    import TestModel from "./testComponent/index";
    Vue.use(TestModel);

    并且调用方法为:

    <test-conponent title = "123">
            <div slot = "contine">
              2222
            </div>
        </test-conponent>

    这么做,像不像element?是有点这个意思对吧,但是怎么实现呢,在这先说明下use的作用,其实就是相当于执行他的install方法,明白这个 之后 开始动工,思路:执行他的install方法,声明一个vue组件,组件内容就是上面写的,从而达到全局组件的目的,来看看我的js怎么写的:

    import main from "./main";
    main.install = (Vue) => {
        Vue.component("test-conponent",main);
    }
    export default main;

    没错就是这么一句,第一种的简单组件就写完了,一次引入 全局通用。

    第二种、通过指令调用,比如element的loading组件等

    <template>
        <div class = "loading-container" v-show = "show">
            <div class = "loading-mask"></div>
            <div class="loading-content">
                <div class="loading-animate"></div>
                <div class="loading-text">
                    {{text}}
                </div>
            </div>
        </div>
    </template>
    
    <script>
    export default {
        props:{
            show:{
                type:Boolean,
            },
            text:{
                type:String,
                default:"加载中...",
            }
        }
    }
    </script>
    
    <style>
        .loading-container {
            position: relative;
            text-align: center;
        }
        .loading-mask {
            position:fixed;
            top:0;
            bottom:0;
            left: 0;
            right: 0;
            background-color: rgba(0,0,0,.7);
        }
        .loading-content{
            position:fixed;
            left:50%;
            top:45%;
            z-index:999;
            transform: translate(-50%,-45%);
            text-align:center;
            color:#fff;
    
        }
        .loading-content .loading-animate{
            display:inline-block;
            40px;
            height:40px;
            vertical-align: baseline;
            margin:25px 0 10px;
            vertical-align: middle;
            animation:cricleLoading 1s steps(12,end) infinite;
            background: transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=") no-repeat;
            background-size: 100%;
    
        }
        .loading-content .loading-text{
            font-size: 16px;
        }
        @-webkit-keyframes cricleLoading{
            0%{
                transform: rotate3d(0,0,1,0deg);
            }
            100%{
                transform: rotate3d(0,0,1,360deg);
            }
        }
         @keyframes cricleLoading{
            0%{
                transform: rotate3d(0,0,1,0deg);
            }
            100%{
                transform: rotate3d(0,0,1,360deg);
            }
        }
    </style>

    以上是loading组件的内容,要通过这种方式引入:

    import loading from "./toolTip";
    Vue.use(loading);

    并且通过指令方式调用

    this.$loading.show({
            text:"拼命加载中"
          });

    有的朋友可能会说了,这怎么可能啊,没有节点怎么放进去?对 没错 确实,没有节点是没办法进去的,但是没有节点就声明节点 对么?

    import LoadingComponent from "./loading";
    import Vue from "vue";
    let instance;
    const loadingConstructor = Vue.extend(LoadingComponent); 
    instance = new loadingConstructor({
        el:document.createElement("div")
    });
    instance.show = false;
    const loading = {
        show(options = {}){
            instance.show = true;
            document.body.appendChild(instance.$el);
            instance.text = options.text;
            setTimeout(()=>{
                loading.hide();
            },5000)
        },
        hide() {
            instance.show = false;
        }
    }
    export default {
        install(){
            if(!Vue.loading){
                Vue.$loading = loading;
            }
            Vue.mixin({
                created(){
                    this.$loading = Vue.$loading;
                }
            })
        }
    }

    实际上就是变相的利用install方法 吧loading指令挂到页面中,这样不管在哪里都可以直接用this.$loading调用。

    以上就是本文所有分享

  • 相关阅读:
    2-5 Flutter开发环境与Android开发环境设置详解(Windows)
    2-3 Flutter开发环境与iOS开发环境设置(Mac)
    2-1 本章作业&2-2 开发系统与工具选择
    ASP.NET Core会议管理平台实战_4、参数校验、操作结果封装,注册参数配置
    ASP.NET Core会议管理平台实战_3、认证、授权表迁移
    29.镜像容器与仓库
    27.集成EFCore配置Client和API
    26.OpenIdConnect获取用户信息的两种方式
    25.ProfileService实现(调试)
    24.集成ASP.NETCore Identity
  • 原文地址:https://www.cnblogs.com/jinzhenzong/p/9894634.html
Copyright © 2011-2022 走看看