Vue开发日志:自定义组件:通用开发流程
自定义组件:通用开发流程
- 通用流程
- 一组概念:key,value,label
- Props:required和default同时存在的必要性
- 让我们简单梳理一下
通用流程
在 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-optionv-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本地数据存储区,进行存放,从而实现了贸易往来,也就是父子之间的双绑联动。