提起魅族手机,对很多人而言,并不陌生。从2009年的魅族M8手机诞生,到2016年的魅族PRO 6手机,这些年就是魅族手机的辉煌时期,在2015和20...
2025-07-27 0
一开始写 Vue 的时候,谁不是觉得:“哇,组件好优雅!”三年后再回头一看,组件目录像垃圾堆,维护一处改三处,props 乱飞、事件满天飞,复用全靠 copy paste。于是我终于明白 —— 组件设计,才是 Vue 项目的重灾区 。
很多初学 Vue 的人对“组件化”的理解就是:“页面上出现重复的 UI?好,抽个组件。”
于是你会看到这样的组件:
<template><input :value="value" @input="$emit('update:value', $event.target.value)" /></template> #技术分享
接着你又遇到需要加图标的输入框,于是复制一份:
<template><div class="icon-text-input"><i class="icon" :class="icon" /><input :value="value" @input="$emit('update:value', $event.target.value)" /></div></template>
再后来你需要加验证、loading、tooltip……结果就变成了:
组件爆炸式增长,但每一个都只是“刚好凑合”,共用不了。
比如下面这个场景:
你封装了一个超级复杂的表格组件:
<CustomTable :columns="columns" :data="tableData" :show-expand="true" :enable-pagination="true" :custom-actions="['edit', 'delete']"/>
你美其名曰“通用组件”,但别人拿去一用就发现:
最后大家的做法就是 —— 不用你这套“通用组件”,自己抄一份改改 。
Vue 的单向数据流原则说得很清楚:
父组件通过 props 向下传数据,子组件通过 emit 通知父组件。
但现实是:
举个例子:
<template><PageWrapper><ChildComponent :formData="form" @submit="handleSubmit" /></PageWrapper></template><template><Form :model="formData" /><button @click="$emit('submit', formData)">提交</button></template>
看上去还好?但当 ChildComponent 再包一层 FormWrapper 、再嵌套 InputList ,你就发现:
组件目录看似整齐,但大部分组件都有如下特征:
于是你只能选择 —— 拷贝再新建一个组件,给它加个 V2 后缀,然后老的你也不敢删。
项目后期的结构大概就是:
components/├── Input.vue├── InputV2.vue├── InputWithTooltip.vue├── InputWithValidation.vue├── InputWithValidationV2.vue└── ...
“为了让别人能维护我的代码,我决定不动它。”
我用三年才悟到一个道理:
Vue 组件设计的难点,不是语法、也不是封装,而是你有没有 抽象问题的能力 。
你需要设计一个“搜索区域”组件,包含输入框 + 日期范围 + 搜索按钮。
新手写法:
<SearchHeader :keyword="keyword" :startDate="start" :endDate="end" @search="handleSearch"/>
页面需求一改,换成了下拉框 + 单选框怎么办?又封一个组件?
更好的设计是 —— 提供 slots 插槽 + 作用域插槽 :
<template><div class="search-header"><slot name="form" /><button @click="$emit('search')">搜索</button></div></template><SearchHeader @search="search"><template #form><el-input v-model="keyword" placeholder="请输入关键词" /><el-date-picker v-model="range" type="daterange" /></template></SearchHeader>
把结构交给组件,把行为交给页面。组件不掌控一切,而是协作。
我总结出 3 条简单但有效的建议:
别让一个组件又画 UI 又写逻辑还请求接口。
如果你发现你组件 props 变成这样:
<SuperButton :label="'提交'" :icon="'plus'" :iconPosition="'left'" :styleType="'primary'" :loading="true"/>
那它该用 slot 了:
<SuperButton><template #icon><PlusIcon /></template>提交 </SuperButton>
三年前我以为组件化是 Vue 最简单的部分,三年后我才意识到,它是最深、最难、最容易出坑的部分。
如果你也踩过以下这些坑:
别再让组件成为项目的“技术债”。你们也有遇到吗?
相关文章
提起魅族手机,对很多人而言,并不陌生。从2009年的魅族M8手机诞生,到2016年的魅族PRO 6手机,这些年就是魅族手机的辉煌时期,在2015和20...
2025-07-27 0
真激动,我们又见证了历史!5月7日,中国歼-10C战机划破长空,在印巴边境初次“亮剑”,一战成名!那一刻,世界见证了中国航空工业硬实力的崛起!多少人的...
2025-07-27 0
连日来,南通科技职业学院“智梯先锋”社会实践团队深入南通、苏州、淮安等地,聚焦智慧电梯运行现状与推广难题,通过调研宣传、参与智能维保、举办科普活动等方...
2025-07-27 0
一开始写 Vue 的时候,谁不是觉得:“哇,组件好优雅!”三年后再回头一看,组件目录像垃圾堆,维护一处改三处,props 乱飞、事件满天飞,复用全靠...
2025-07-27 0
2025年7月3号,上海积塔半导体的IT经理徐泽伟从浦东机场飞意大利度蜜月,刚落地米兰就被意大利警察带走。美国说他参与黑入新冠疫苗研究机构,偷资料。这...
2025-07-27 0
物美集团在丰台、通州、西城、东城、石景山5区同时开出“物美超值”硬折扣店,6家门店齐发,当天折扣超市开业后被挤爆!物美超值依托供应链,“好货不贵,天天...
2025-07-27 0
现在人们打棋牌麻将谁不想赢?手机微乐麻将必赢神器但是手机棋牌麻将是这么好赢的吗?在手机上打棋牌麻将想赢,不仅需要运气,也需要技巧。掌握的棋牌麻将技巧就...
2025-07-27 10
现在人们打棋牌麻将谁不想赢?手机微乐麻将必赢神器但是手机棋牌麻将是这么好赢的吗?在手机上打棋牌麻将想赢,不仅需要运气,也需要技巧。掌握的棋牌麻将技巧就...
2025-07-27 8
发表评论