0%

Vue3.x + Vite2.x 入门实战 03:二次封装el-input组件

element-plus 提供了非常多通用的组件,但要满足特定产品需求效果还是略有差异,所以需再次封装。

概要内容

  • 怎么封装成子组件?
  • 怎么使用封装组件?

效果对比

  • 原始效果

  • 封装后效果

怎么封装成子组件?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<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) {
// 绑定控件的值
const value = ref("");

// 监听属性,给 value 赋值
watch(
() => props.modelValue,
(v1, v2) => {
value.value = v1;
}
);
return {
value,
props,
};
},
methods: {
getIconName() {
return "iconfont " + this.iconName;
},
/** 向父组件提交事件更新数据 */
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>

怎么使用封装组件?

  • 引入

    1
    2
    3
    4
    5
    6
    import CustomInput from "/@/components/CustomInput/index.vue";

    export default defineComponent({
    components: { CustomInput },
    ...
    });
  • 使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <template>
    ...
    <CustomInput
    class="input-tel"
    v-model="tel"
    placeholder="请输入手机号码"
    iconName="iconshoujihaoma"
    oninput="`(value = value.replace(/[^\d]/g, ''))`"
    :tips="telTips"
    @onChange="telTips = ''"
    >
    </CustomInput>
    ...
    </template>

总结

  1. 子组件需watch值变化,然后通过emit 事件上抛值,否则子组件value值变化,上层组件还是原来的值
  2. 更改子组件默认样式,需要将style 标签中的scoped 去掉,否则会导致怎么也无法覆盖子组件样式情况

参考文献


以上: 如发现有问题,欢迎留言指出,我及时更正

如何文章对你有益,请给我买杯豆浆喝