前端学习笔记(四)自定义组件控制自己的css

1、前言及背景

自己写的一个组件有至少3个页面在使用,组件中的部分文字颜色需要统一修改需要根据一个状态字段来显示不同颜色且不希望受父组件影响

注意:博主学习vue截止目前也就半年,如有知识错误之处还请指出不胜感激,祝学习开心快乐哈哈

2、deepseek查询

提问:vue3中使用插槽时如果通过子组件统一设置父组件中的插槽的class

答案:

方案有2个

一、插槽包裹层样式穿透

通过在子组件中为插槽‌添加包裹容器‌并设置class,利用CSS作用域穿透特性控制插槽内容样式

html 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <div class="child-wrapper">
    <div class="slot-container"> <!-- 定义插槽容器 -->
      <slot></slot>
    </div>
  </div>
</template>

<style scoped>
.slot-container :deep(div) { /* 穿透父组件插槽内容 */
  color: red;
  padding: 12px;
}
</style>

二、作用域插槽传递参数

通过‌作用域插槽‌将class参数传递给父组件,父组件动态绑定插槽元素的class

html 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <slot :slotClass="'custom-class'"></slot> <!-- 传递class参数 -->
</template>
html 复制代码
<!-- 父组件 ParentComponent.vue -->
<child-component>
  <template #default="{ slotClass }">
    <div :class="slotClass"> <!-- 动态绑定接收的class -->
      插槽内容
    </div>
  </template>
</child-component>

方案对比

选择方案时,若需‌完全由子组件控制样式‌,优先使用包裹层穿透方案;若需‌保留父组件样式调整灵活性‌,则采用作用域插槽传递参数。

3、具体实现方案

1)给插槽外面包装一个div

2)通过动态计算来设置slot外面div的class名字

3)不同的class里面通过deep选择到父组件可能用到的span和a并控制颜色

4、具体代码

html 复制代码
<!--代码片段-->
<template v-if="$slots.edit || $slots.view || $slots.publish">
    <div :class="classStatusColor">
      <slot v-if="!!$slots.edit" name="edit" :model="modelEdit"></slot>
    </div>
<template>
ts 复制代码
  const statusColor = ref(getStatusColor());
  const classStatusColor = computed(() => ({
    'slot-edit-container-draft': statusColor.value === STATUS_DRAFT,
    'slot-edit-container-waiting-approve': statusColor.value === STATUS_WAITING_APPROVE,
    'slot-edit-container-reject': statusColor.value === STATUS_REJECT,
    'slot-edit-container-publish': statusColor.value === STATUS_PUBLISH,
  }));
ts 复制代码
// 代码片段按照优先级设置颜色STATUS_REJECT > STATUS_DRAFT > STATUS_WAITING_APPROVE > STATUS_WAITING_APPROVE > STATUS_PUBLISH
function getStatusColor() {
    let values: DataValue[];
    //values = ............//自己处理逻辑

    // 空值处理
    if (values === undefined) {
      return STATUS_UNKNOWN;
    }
    let statusList: number[] = [];
    for (let i of values) {
      if (i.value.status === undefined) {
        statusList.push(STATUS_UNKNOWN);
      } else {
        statusList.push(i.value.status);
      }
    }

    if (statusList.includes(STATUS_REJECT)) {
      return STATUS_REJECT;
    }
    if (statusList.includes(STATUS_DRAFT)) {
      return STATUS_DRAFT;
    }
    if (statusList.includes(STATUS_WAITING_APPROVE)) {
      return STATUS_WAITING_APPROVE;
    }
    if (statusList.includes(STATUS_PUBLISH)) {
      return STATUS_PUBLISH;
    }
    return STATUS_UNKNOWN;
  }
html 复制代码
<style lang="less" scoped>
  // 红色是草稿状态
  .slot-edit-container-draft :deep(a) {
    color: rgb(238 102 102);
  }

  // 蓝色是待审核状态
  .slot-edit-container-waiting-approve :deep(a) {
    color: rgb(84 112 198);
  }

  // 橙色是驳回状态
  .slot-edit-container-reject :deep(a) {
    color: rgb(250 200 88);
  }

  // 黑色是已发布状态
  .slot-edit-container-publish :deep(a) {
    font-weight: black;
  }
</style>
相关推荐
不简说2 分钟前
JS 代码技巧 vol.8 — 20 个函数式编程实战,把 if/else 拍扁的骚操作
前端·javascript·面试
头茬韭菜18 分钟前
4.9 SSRF 防护 — Web 工具的出站安全与私有 IP 拦截
前端·tcp/ip·安全
Cobyte27 分钟前
模板 DSL 解析器中的状态机设计
前端·javascript·vue.js
颜酱30 分钟前
# 02 | 搭骨架:用 LangGraph 编排 12 步工作流(思路)
前端·人工智能·后端
颜酱31 分钟前
02 | 搭骨架:用 LangGraph 编排 12 步工作流
前端·人工智能·后端
殷忆枫41 分钟前
AI笔记三十七:AI边缘端道桥安全监测系统:YOLOv8n推理与Web监控全解析
笔记·yolo
逸模1 小时前
轻加盟模式,稳住品牌统一调性的思路
笔记·建模·公装·翻模·交底
刘卓航众创芯云服务部2 小时前
Kimi K3复杂任务实测:我把团队最头疼的三个场景全跑了一遍
前端
cll_8692418912 小时前
一个好看的Wordpress博客文字css样式
前端·css·ui
武子康2 小时前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端