vue自定义组件的实例讲解

719 阅读6分钟

VUE自定义组件

现在基于vue的UI组件库有很多,比如vant,element-ui等。但有时候这些组件库满足不了我们的开发需求,这时候我们就需要自己写一个插件。

首先我们来了解一下组件:

  • 为什么用组件:因为一个项目里有很多高度相似的区域,或者说功能,每个页面都写一次,甚至一个页面写两次,会造成大量代码重复,并且维护困难,组件就是把这些代码进行封装,把不一样的地方植入插槽,这样需要用到的地方,只需要一行代码,就能实现,并且维护的时候只需要修改组件文件,不需要每个页面修改
  • 插槽的含义:用到组件的页面通过向组件传值,达到控制组件展示不同效果,例如组件中有一个控制是否展示一个盒子的插槽,代码是v-if=“isShow”,父组件传值isShow=false;那么这个盒子就不会在父组件中展示
  • 组件的使用:
    • 首先,创建组件文件,并且完成组件代码,预留可控制插槽
    • 其次,在运用组件的页面进行挂载,
    • 最后在运用组件的页面,向组件传入控制插槽的参数,并且在页面中引入使用

第一个步骤:创建存放插件的文件夹

  • 我们创建一个components文件夹下面创建你要写的插件的文件夹,里面有两个文件,一个VUE组件文件,一个js注册组件文件
img
img

第二部,写组件代码,我们这里是一个弹框样式的模板

<template>
  <div>
    <!-- v-model="show" 这里控制是否展示   @close="changeShow"是否展示 popHeight控制高度-->
    <van-popup
      v-model="show"
      class="model_box"
      @close="changeShow"
      :style="{ height: popHeight }"
    >
      <div class="modelHeader">
        <!-- 第一个插槽,头部标题 -->
        <div class="modelTitle">
          {{ title }}
          <span></span>
        </div>
      </div>
      <!-- 第二个插槽,内容展示用哪种2方法,通过type值来控制 -->
      <div class="model_content" :class="{ resightShow: resightShow }">
        <div class="content_info" v-if="type == 1" v-html="content"></div>
        <div class="content_info" v-else-if="type == 2">{{ content }}</div>
        <div class="content_info" v-else-if="type == 3">
          <ul>
            <li
              v-for="(item, index) in content.orders"
              :key="index"
              class="order_lists"
            >
              <span>{{ index + 1 }}</span>
              <div>
                <p>{{ item.joinMoney }}</p>
                <p class="times">{{ getCurrentDateTime(item.createTime) }}</p>
              </div>
            </li>
          </ul>
        </div>
      </div>
      <!-- 这是注册页特有的地步点击确认插槽,通过resightShow控制 -->
      <div v-if="resightShow" class="resight_box">
        <slot></slot>
      </div>
      <van-icon name="clear" size="25" @click="changeShow" class="iconClose" />
    </van-popup>
  </div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import moment from "moment";
const options = Vue.extend({
  // 这里接受父组件的参数,来控制这遍展示的样式
  props: ["popHeight""title""content""type""modelShow""resightShow"],
});

@Component
export default class Page extends options {
  show = true;
  changeShow() {
    this.show = true;
    this.$emit("changeShowNow"false);
  }
  getCurrentDateTime(date) {
    return moment(date).format("MMMM DD YYYY, HH:mm:ss");
  }
}
</script>
<style scoped>
.model_box {
  width90%;
  border-radius8px;
  padding20px;
  box-sizing: border-box;
  overflow: visible;
}
.modelHeader {
  width200px;
  height30px;
  position: absolute;
  top0;
  left50%;
  transformtranslate(-50%, -50%);
}
.modelTitle {
  width100%;
  height100%;
  background#118557;
  display: flex;
  justify-content: center;
  align-items: center;
  color#fff;
  font-size14px;
  position: relative;
  border-radius3px;
}
.modelTitle span {
  position: absolute;
  left0;
  top0;
  transformtranslateY(196%);
  width0;
  height0;
  border-left100px solid transparent;
  border-right100px solid transparent;
  border-top15px solid #118557;
}
.model_content {
  margin-top15px;
  height90%;
  overflow-x: hidden;
  overflow-y: scroll;
  word-break: normal;
  word-wrap: break-word;
  font-size14px;
}
.resightShow {
  height70%;
}
.content_info {
  word-break: normal;
  word-wrap: break-word;
}
.iconClose {
  position: absolute;
  left50%;
  bottom0;
  transformtranslate(-50%130%);
  color#fff;
}
.order_lists {
  border-bottom1px solid #f8f8f8;
  margin-top8px;
  display: flex;
  flex-direction: row;
}
.order_lists span {
  margin-right10px;
}
.order_lists p {
  line-height25px;
  font-size12px;
}
.order_lists .times {
  color#ccc;
}
.resight_box {
  margin-top15px;
}
</style>

小结:当你在使用组件那个页面引入这个组件时候,通过向组件传参,获取满足你当前页面需要用到的样式

总结:组件的使用就是,写组件,留插槽,给组件传参,用到页面上,大致用法就和上例一样,如果有不懂的地方可以留言,谢谢大家