自定义组件:通用开发流程
通用流程
在 Vue.js 中开发自定义组件的通用流程如下:
-
定义组件模板:
创建一个.vue
文件,里面包含模板、样式和脚本部分。例如:<!-- MyCustomComponent.vue --> <template> <div class="my-custom-component"> <!-- 组件的HTML结构 --> </div> </template> <script> export default { name: 'MyCustomComponent', // 组件的数据属性、计算属性、方法等 props: {}, // 如果有传入属性 data() { return { // 组件内部的状态数据 }; }, computed: {}, methods: {}, // 生命周期钩子函数 created() {}, mounted() {}, updated() {}, beforeDestroy() {}, }; </script> <style scoped> .my-custom-component { /* 组件的CSS样式 */ } </style>
-
定义组件属性(props):
如果组件需要接收外部传递的参数,需要在props
对象中定义。例如:props: { title: { type: String, required: true, }, value: { type: [String, Number], default: '', }, },
-
组件内部状态管理:
在data
函数中定义组件内部需要用到的状态变量,也可以使用ref
或reactive
(Vue 3)来创建响应式数据。 -
计算属性与方法:
根据业务逻辑定义计算属性和方法。计算属性用于根据组件内部状态生成新的值,方法用于处理事件或其他业务逻辑。 -
事件监听与触发:
在组件内部使用@event
监听事件,并使用$emit
触发事件,使得父组件可以捕获并处理子组件的事件。 -
样式设置:
在<style>
标签内编写组件的样式,通常使用scoped
属性确保样式只作用于当前组件。 -
注册组件:
在需要使用自定义组件的父组件或入口文件中,通过components
选项将其注册。// Vue 2 import MyCustomComponent from './MyCustomComponent.vue'; export default { components: { MyCustomComponent, }, // ... }; // Vue 3 import { defineComponent } from 'vue'; import MyCustomComponent from './MyCustomComponent.vue'; export default defineComponent({ components: { MyCustomComponent, }, // ... });
-
在模板中使用组件:
注册完成后,可以在父组件的模板中使用自定义组件标签。<my-custom-component :title="pageTitle" v-model="selectedValue"></my-custom-component>
通过以上步骤,你可以完成一个基础的自定义组件开发。当然,实际开发过程中还可能涉及到更复杂的逻辑,比如 slots(插槽)、异步数据加载、自定义指令等。
一组概念:key,value,label
在Vue中,props传入的对象数组包含key
、value
、label
通常是用于列表展示或者其他需要关联显示和隐藏值的场景,特别是在制作Select、Option、Radio、Checkbox等类型的UI组件时很常见。这三个字段分别代表:
-
key
:通常用于唯一标识数组中的每个选项,它在内部处理和比较时使用,避免直接使用对象进行比较,提高性能。在一些特定场景下(如Vue Router的路由配置等)key
字段是必须的。 -
value
:表示选项的实际值,这个值将会作为最终选定的值绑定到父组件的状态中。例如在Select组件中,当你选择了某一项后,组件将返回value
作为选中的值。 -
label
:表示选项的显示文本,它是用户在界面上看到的内容。在列表中,label
通常用于显示在选项上,便于用户阅读和理解。
下面是一个简单的Vue组件使用示例,展示了如何接收一个包含key
、value
、label
的对象数组,并用它来填充一个下拉列表(Select):
<!-- ParentComponent.vue -->
<template>
<div>
<CustomSelect :options="selectOptions" v-model="selectedValue" />
</div>
</template>
<script>
import CustomSelect from './CustomSelect.vue';
export default {
components: {
CustomSelect,
},
data() {
return {
selectOptions: [
{ key: 'opt1', value: 'value1', label: 'Label One' },
{ key: 'opt2', value: 'value2', label: 'Label Two' },
// 更多选项...
],
selectedValue: '', // 初始化选中的值为空
};
},
};
</script>
<!-- CustomSelect.vue -->
<template>
<el-select v-model="internalValue">
<el-option
v-for="option in options"
:key="option.key"
:label="option.label"
:value="option.value"
></el-option>
</el-select>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true,
default: () => [],
},
modelValue: {
type: [String, Number, Boolean, Object],
default: null,
},
},
emits: ['update:modelValue'],
computed: {
internalValue: {
get() {
return this.modelValue;
},
set(value) {
this.$emit('update:modelValue', value);
},
},
},
};
</script>
在这个例子中:
-
父组件
ParentComponent
定义了一个包含key
、value
、label
的对象数组selectOptions
,并通过v-model
把selectedValue
传递给CustomSelect
组件。 -
子组件
CustomSelect
接收options
作为props
,并在el-select
组件中遍历这些选项,用option.key
作为el-option
的 key,option.label
作为显示文本,option.value
作为选中时返回的值。 -
子组件通过
computed
属性internalValue
与v-model
结合,实现了modelValue
的双向绑定,当用户在下拉列表中选择一个选项时,会触发update:modelValue
事件,从而更新父组件的selectedValue
。
Props:required和default同时存在的必要性
在Vue的props配置中,required
属性和default
属性一起使用是有意义的,尤其是在处理组件库和团队协作时。
-
required: true
表示该prop是必需的,父组件在使用该子组件时必须传递这个prop。如果不传递,Vue会在控制台抛出警告。 -
default
属性则定义了当父组件未传递该prop时,子组件应当使用的默认值。这对于开发者来说是一种友好的提示和保护措施,即使忘记传递该prop,子组件也能正常使用,不会立即导致程序崩溃。
结合两者来看,required: true
强调了开发规范上的要求,提醒开发者必须传递这个prop;而default
则是为可能出现的疏漏提供了兜底方案,确保即使在某些情况下未传递所需prop,组件仍能正常运行。
举个例子,假设我们维护一个大型项目,团队成员众多,要求每个使用CustomSelect
组件的人都必须传递options
,这时我们可以设置required: true
。同时,为了防止由于疏忽未传递options
而导致组件表现异常,我们又提供了一个默认的空数组作为default
值,这样即便忘记传递,组件也不会因为缺少必要数据而无法渲染或报错。
让我们简单梳理一下
首先,当v-model="fatherValue"时,fatherValue的值肯定首先会渲染到子组件中,这也是父传子的第一步。
其次,当我们修改子组件输入框中的内容时,会发起一个事件冒泡,将经过子组件处理后的fatherValue值,打包传入到父组件的监听器处,即靠港。
接着,卸货将其搬运到data本地数据存储区,进行存放,从而实现了贸易往来,也就是父子之间的双绑联动。