如何将 Vue.js 范围样式应用于通过视图路由器加载的组件?

Posted

技术标签:

【中文标题】如何将 Vue.js 范围样式应用于通过视图路由器加载的组件?【英文标题】:How to apply Vue.js scoped styles to components loaded via view-router? 【发布时间】:2018-02-18 18:32:04 【问题描述】:

如何将 Vue.js 范围样式应用于通过 <view-router> 加载的组件。

这是我的代码:

<template>
  <div id="admin">
    <router-view></router-view>
  </div>
</template>

<style lang="scss" scoped>
#admin 
  .actions 
    display: none;
    span 
      cursor: pointer;
    
  

</style>

当我访问/posts时,会加载一个名为Posts的组件,在这个组件里面我有一个

<div class="actions">
  some content
</div>

问题是#admin 中定义的样式不适用于.action 元素。如果没有范围,这可以正常工作。当#admin 组件样式为scoped 时,问题就来了。

有什么方法可以做到这一点,同时将.actions 样式保留在admin 组件范围样式标记内?

【问题讨论】:

【参考方案1】:

router-view 标签不会将样式传递给其子标签的原因是因为router-view 本身不是可样式化的 html 标签,因此您不能对其应用任何样式。您可以尝试,但它不会渲染。

原因:router-view 本质上是一个模板标签,或者是 Vue 的占位符,用于锚定并插入该路由调用的 componentView。因此,router-view 标签不会出现在编译的标记中,您只会看到正在加载的 ViewComponent

它的工作方式与将 Vue 应用程序的应用程序入口点工作到 index.html 文件中的方式相同。至少这是我的经验和知识。

另外,@Antonio Trapani 很好的答案,我想补充一点,您甚至可以拥有一个包含所有全局样式或跨多个组件所需样式的 scss 文件,然后只需将样式 @import 到 App.vue这将使您可以访问整个应用程序。还有,IME。

希望这会有所帮助。 干杯。

【讨论】:

【参考方案2】:

这可能就是你想要的https://vue-loader.vuejs.org/en/features/scoped-css.html#deep-selectors

由于您的代码 sn-p 专门使用 SCSS,您必须使用 /deep/ 组合器。


如果您希望范围样式中的选择器“深”,即影响子组件,您可以使用 >>> 组合器:

<style scoped>
.a >>> .b  /* ... */ 
</style>

上面会编译成:

.a[data-v-f3f3eg9] .b  /* ... */ 

某些预处理器,例如 SASS,可能无法正确解析 >>>。在这些情况下,您可以改用 /deep/ 组合器 - 它是 >>> 的别名,并且工作方式完全相同。


所以你最终会得到:

<style lang="scss" scoped>
  #admin 
    some-property: some-style;

    /deep/ .actions 
      some-property: some-style;
    
  
</style>

【讨论】:

Webpack 对我来说只是按原样吐出&gt;&gt;&gt;。我在webpack.config.js 有什么特别的事情要做吗? @333 你用的是什么预处理器? (如果有的话) 冒着听起来像个孩子的风险,我不知道...我的vue-loader 选项如下所示: loaders: scss: "vue-style-loader!css-loader!sass-loader" @333 不用担心!所以看起来你正在使用 Sass(可能特别是 SCSS)所以在你的 Vue 文件中如果你有 &lt;style lang="scss"&gt; 你必须使用 /deep/ 组合器,如我的第二个代码示例中所示,而不是 @987654331 @例子。 它仍在为我逐字逐句吐出。【参考方案3】:

您可以将样式放在单独的文件中,并从所有需要它的组件中引用它:

&lt;style src="path/to/your/styles" lang="scss" scoped&gt;&lt;/style&gt;

【讨论】:

谢谢!那是一个很好的答案。不知道为什么其他人不喜欢它! 这不是一个好的解决方案,它会在head 上创建多个style 标签,并且您不能在此样式中添加任何规则。 在开发模式下你可能有多个style 标签。在生产中,这取决于你如何使用 Webpack 配置块。 tks,太好了

以上是关于如何将 Vue.js 范围样式应用于通过视图路由器加载的组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Vue.js 中的子路由在页面刷新时丢失样式

vue.js路由

如何将样式应用于超越其他元素边界的文本范围?

Vue 路由的基本使用

从 Vue.js 中的某些路由中排除 Bootstrap 样式

Vue JS:如何在路由器链接中设置活动 <a> 标记的样式?