简体   繁体   English

如何根据 Svelte 中的“use”指令为类更改的组件设置样式?

[英]How can I style a component whose class changes based on a `use` directive in Svelte?

I am creating a directive which adjusts the class of the element that it is applied to.我正在创建一个指令来调整它所应用到的元素的类。 However, the styles for that class do not apply when the class changes.但是,当类更改时,该类的样式不适用。 For instance:例如:

Form.svelte表单.svelte

<form id='sign-in' use:delayed={ handleSubmit }>
  <label for='sign-in-name'>Your Name</label>
  <input required id='sign-in-name' type='text' />

  <input type='submit' value='Sign In' />
</form>

<style>
  form {
    display: block;
  }

  form.submitting {
    display: none;
  }
</style>

Delayed.js延迟.js

export default function(node, action) {
  node.addEventListener('submit', async function(event) {
    event.preventDefault()
    const originalClass = node.className

    node.className = `${ originalClass } submitting`
    await action()
    node.className = originalClass
  })
}

In this case, the class will change successfully in the DOM, but the form will still display.在这种情况下,类将在 DOM 中成功更改,但表单仍将显示。 The form.submitting style doesn't even make it into the CSS generated by Svelte. form.submitting样式甚至没有包含在 Svelte 生成的 CSS 中。

I know that I can work around this using a global stylesheet, but I'm curious why the scoped styles don't apply and if there's a way to make it work that way.我知道我可以使用全局样式表来解决这个问题,但我很好奇为什么范围样式不适用,以及是否有办法让它以这种方式工作。

This works, but it feels hacky.这有效,但感觉很糟糕。

<style>
  form {
    display: block;
  }

  :global(form.submitting) {
    display: none;
  }
</style>

Svelte compiler removes unused CSS rules, that is rules with selectors that do not match in the markup of the component. Svelte 编译器删除未使用的 CSS 规则,即带有与组件标记不匹配的选择器的规则。 You should have a compiler warning "Unused CSS selector" about that.你应该有一个关于这个的编译器警告“未使用的 CSS 选择器”。 And since the compiler can't see dynamically added classes, your form.submitting selector is removed.并且由于编译器无法看到动态添加的类,因此您的form.submitting选择器被删除。

The solution is indeed to make your dynamic selector :global(...) .解决方案确实是使您的动态选择器:global(...)

If you want your style to only apply in the scope of this component and its children, you need a wrapping element that you can reference like such:如果您希望您的样式仅适用于该组件及其子组件的范围,您需要一个可以像这样引用的包装元素:

<div>
  <form>...</form>
</div>

<style>
  div :global(form.submitting) { ... }
</style>

Svelte will scope the div part of the selector to the current component, effectively meaning that the :global(...) part will only apply to the form inside a <div> inside this component. Svelte 会将选择器的div部分范围限定为当前组件,这实际上意味着:global(...)部分将仅应用于此组件内<div>内的表单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM