文章
问答
冒泡
vue系列之封装组件

开个系列的文章记录一下自己封装vue组件的经历,就以弹窗组件为例:
1.局部封装(基础组件):
新建一个vue的基础组件,把公用的数据和方法提取出来,弹窗要注意阴影遮罩层

//html结构
<template>
    <div class="dialog">
        <div class="dialog-cover back" v-show="show"></div>
            <div class="modal-container" v-show="show">
                <div class="modal-header">{{ title }}</div>
                <div class="modal-main">
                <!-- 预留一个插槽位置 -->
                <slot></slot>
                </div>
            <div class="modal-footer">
                <button @click="cancelClick">取消</button>
                <button @click="confirmClick">确认</button>
            </div>
        </div>
    </div>
</template>

如上图所示html部分,遮罩层必须必须有v-show属性,组件根div和modal-container两者选其一控制隐藏就可以了,视具体情况和业务逻辑而定,modal-heade就是抽出来的公共部分,仅做个示例,具体情况可能会有许多公用的部分,<slot></slot>是插槽,组件的封装调用最灵活的就是插槽的使用

//js部分
export default {
name: "dialoga",
props: {
    show: {
    type: Boolean,
    default: false
           },
    title: {
    type: String,
    default: ""
    }
    },
methods: {
cancelClick() {
    this.$emit("hideModal");
    },

confirmClick() {
    this.$emit("submit");
    }
}

父子组件通信的点击事件,需要在子组件中通过$emit派发一个方法出去,这个方法在父组件中监听回,可以写回调的逻辑,然后我们在页面中调用该子组件,那么此页面就是父组件了,子组件接收来自父组件的值,需要用props接收,这是单向流数据传递,要注意的是,自组件porp是定义的是变量的类型

<template>
    <div>
        <button @click="showD">点击展示弹窗</button>
        <Dialog :show="show" :title="title" @hideModal="cancel" @submit="confirm">
            <span>使用插槽</span>
        </Dialog>
    </div>
</template>
<script>
import Dialog from "../components/DialogA.vue";
export default {
    data() {
    return {
        title: "弹窗标题",
        show: false
        };
    },
components: { Dialog },
methods: {
    showD() {
        this.show = true;
        },
    cancel() {
    // 取消弹窗回调
        this.show = false;
    },

    confirm() {
        // 确认弹窗回调
        this.show = false;
        }
    }
   };
</script>
<style scoped>
</style>

上述代码中:在vue中是v-bind的语法糖写法,我们在自组件中抽出来的公用部分,需要在父组件中绑定,回调的事件需要在父组件绑定,用v-on绑定,语法糖写法是@,给绑定的事件一个方法,就可以在父组件的方法中写当前逻辑了。
奉上该组件的css部分:

<style lang="stylus" scoped>
.dialog {
    position: relative;
    color: #2e2c2d;
    font-size: 16px;
    }

.dialog-cover {
    background: rgba(0, 0, 0, 0.8);
    position: fixed;
    z-index: 200;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    }

.modal-container {
    position: fixed;
    top: 35%;
    left: 30%;
    z-index: 300;
    background-color: #ffffff;
}
</style>



2.全局组件封装
全局组件封装我们从简单的例子开始入手,以全局封装一个button按钮为例,第一步也是需要一个基础的组件

<template>
  <button class="btn">
    <slot/> <!-- 插槽 -->
  </button>
</template>
 
<script>
export default {
  // 传入子组件的参数写到props
  props: {

  }
}
</script>
 
<style scoped>
  .btn {
    width: 100px;
    height: 50px;
    color:red;
    border: none;
    font-size: 14px;
  }
</style>

全局组件要让全局都能调用他,就需要注册一个js文件,让基础组件在js中注册,然后导出:

import xxxxxxx from 'xxxxxxx' //引入刚才的基础vue组件
 
// 添加install方法
const Button = {
  install: function (Vue) {
    Vue.component("Button", ButtonComponent);//注册组件
  }
}
 
// 导出
export default Button

最后,需要在vue的入口js文件,也就是main.js文件中来引入注册的js文件,然后使用vue.use方法使封装的组件成为vue的一个实例,能在全局中使用:

import Button from 'xxxxxx'//引用全局组件Button

Vue.use(Button);//使用全局组件Button

想要在页面中使用该全局组件,如下:

<template>
  <div id="app">
    <!-- 使用Button组件 -->
    <Button>全局按钮</Button>
  </div>
</template>

这一期就先到这里,全局组件的封装不局限与这一种方法,而且全局组件的公用部分的抽取封和使用稍复杂一下,我们放到下期再讲

Vue

关于作者

lightsadness
一起学习 一起成长
获得点赞
文章被阅读