vue.js - vue 3 中范围样式和深度样式的问题

标签 vue.js vue-component vuejs3 vue3-sfc-loader

我在尝试在 vue3 中为父级的子级设置样式时遇到了很多问题。

在这种情况下,我创建了一个具有一些 css 属性的通用按钮,并且我尝试从其他组件自定义此按钮

parent

<template>
  <OwnButton
    class="accept-button"
    @ownButtonClicked="emit('accept')"
  >
    <slot> 
      ACCEPT
    </slot>
  </OwnButton>
</template>

<script setup>
import OwnButton from 'path/to/own-button.vue';

const emit = defineEmits(['accept']);
</script>

<style scoped>
.accept-button :deep(.own-button)
{
  background-color  : #4CAF50 !important;
  outline-color     : green !important;
}
.accept-button :deep(.own-button:hover)
{
  background-color: green !important;
}
</style>

child

<template>
  <button
    class="own-button"
    type="button"
    @click="emit('ownButtonClicked')"
    v-on:keyup.enter="emit('ownButtonClicked')"
  >
    <slot> 
    </slot>
  </button>
</template>

<script setup>

const emit = defineEmits
([
  'ownButtonClicked'
]);
</script>

<style scoped>
.own-button
{
  background-color  : azure;
  outline-color     : lightblue;
  color             : black;
  margin            : 2px;
  padding           : 5px;
  border-radius     : 15px;
  border            : 0;
  box-shadow        : 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  outline-style     : solid;
  min-width         : 100px;
  max-width         : 150px;
}
.own-button:hover
{
  cursor: pointer;
}
</style>

我尝试了所有我能想到的方法,包括在父级中使用 :deep(button)

最佳答案

这是 Vue 3 在处理多根节点时的设计限制

我在我的文章 Scoped styles and multi-root nodes don't work well together 中写过这个.

了解问题

在 Vue 3 中,我们终于可以拥有不止“一个根节点”的组件。这很好,但是这样做有一个设计限制。假设我们有一个子组件:

<template>
  <p class="my-p">First p</p>
  <p class="my-p">Second p</p>
</template>

还有一个父组件:

<template>
    <h1>My awesome component</h1>
    <MyChildComponent />
</template>

<style scoped>
// There is no way to style the p tags of MyChildComponent
.my-p { color: red; }
:deep(.my-p) { color: red; }
</style>

无法从多根父组件的作用域样式设置子组件的 p 标签的样式。

简而言之,一个多根组件,不能使用作用域样式来定位多根子组件的样式。

解决方案

👉 💡 解决这个问题的最佳方法是包装父组件或子组件(或两者),这样我们就只有一个根元素。

但是如果你绝对需要两者都具有多根节点,你可以:

  1. 使用非作用域样式
<style>
.my-p { color: red; }
</style>
  1. 使用 CSS 模块
<template>
    <h1>My awesome component</h1>
    <MyChildComponent :class="$style.trick" />
</template>

<style module>
.trick {
    color: red;
}
</style>

既然我们在这里指定了一个类,那么多根子组件就得显式指定属性fallthrough behavior。



如果你想要我的意见,除非你绝对需要一个多根节点组件,否则请使用单个根节点并且根本不要处理这个设计限制。

关于vue.js - vue 3 中范围样式和深度样式的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73798668/

相关文章:

javascript - 在 VueJS 上使用领导线

vue.js - Vue 3 : Why is my composable not reactive?

vue.js - Vue 路由器使用 keep-alive 来缓存某些组件?

vue.js - 如何在 Vue3 v-for Array Refs 中传递索引

javascript - 如何在 Vue 3/Nuxt 3 中为表单提交添加动态输入字段?

checkbox - 拦截 VueJS 中的复选框更改事件

vue.js - Vue组件动态添加属性

vue.js - 在 VueJS 组件中导入使用 getElementById 的模块

vue.js - [Vue警告] : Property "$primevue" was accessed during render but is not defined on instance

vue.js - 唯一电子邮件地址的 Vee 验证