Element-plus offers a wide range of generic components, but they vary slightly to meet specific product needs, so they need to be packaged again.

Summary of the content

  • How to encapsulate into child components?
  • How to use encapsulated components?

Effect of contrast

  • Effect of the original

  • Effect after encapsulation

How to encapsulate into child components?

<template>
  <div class="contain">
    <el-input
      class="input"
      :class="{ 'red-border': tips.length > 0 }"
      v-model="value"
      @input="onInput"
      @change="$emit('onChange')"
      :placeholder="placeholder"
    >
      <template #prefix>
        <i :class="['iconfont', iconName]"></i>
      </template>
    </el-input>

    <div class="tips" v-if="tips.length > 0">
      {{ tips }}
    </div>
  </div>
</template>

<script>
import { defineComponent, reactive, ref, watch, toRefs } from "vue";
import { ElInput } from "element-plus";

export default defineComponent({
  name: "CustomInput".components: { ElInput },
  props: {
    modelValue: {
      type: [String.Number].default: "",},placeholder: { type: String.default: "" },
    oninput: { type: String.default: "" },
    iconName: { type: String.default: "" },
    tips: { type: String.default: ""}},emits: ["input"."update:modelValue"."onChange"].setup(props, context) {
    // Bind the value of the control
    const value = ref("");

    // Listen on the property and assign value to it
    watch(
      () = > props.modelValue,
      (v1, v2) = >{ value.value = v1; });return {
      value,
      props,
    };
  },
  methods: {
    getIconName() {
      return "iconfont " + this.iconName;
    },
    /** Submit event update data to the parent component */
    onInput(e) {
      this.$emit("update:modelValue", e);
      this.$emit("input", e); ,}}});</script>

<style lang="scss">
.input {
  height: 50px;
  text-align: left;

  .iconfont {
    font-size: 22px;
    color: #127ffc;
    display: inline-block;
    margin-right: 14px; }}.red-border .el-input__inner {
  border: 1px solid #ff6666;
}

.tips {
  font-size: 14px;
  color: #ff6666;
  text-align: left;
  margin: 5px auto 20px;
}
</style>
Copy the code

How to use encapsulated components?

  • The introduction of

    import CustomInput from "/@/components/CustomInput/index.vue";
    
    export default defineComponent({
      components: { CustomInput },
    	...
    });
    Copy the code
  • use

    <template>.<CustomInput
                class="input-tel"
                v-model="tel"
                placeholder="Please enter your mobile phone number."
                iconName="iconshoujihaoma"
                oninput="`(value = value.replace(/[^\d]/g, ''))`"
                :tips="telTips"
                @onChange="telTips = ''"
              >
              </CustomInput>.</template>
    Copy the code

conclusion

  1. The subcomponent needs to change its watch value, and then throw the value through the EMIT event, otherwise the subcomponent value changes and the upper component remains the same
  2. To change the default style of the child component, remove scoped from the style tag. Otherwise, the child component style will not be overwritten at all

reference

  • Vue 3-V-Model and Components
  • Vue3 Components (3) Take someone else’s components and encapsulate them
  • How to override scoped styles in Vue components?

Above: If you find any problems, welcome to point out the message, I timely correction