Vue.js:如何使动态创建的 HTML 使用作用域 CSS?

Posted

技术标签:

【中文标题】Vue.js:如何使动态创建的 HTML 使用作用域 CSS?【英文标题】:Vue.js: How can I make dynamically created HTML use scoped CSS? 【发布时间】:2017-08-20 12:17:44 【问题描述】:

短版:

我在组件的方法中使用 html 生成一个字符串,但我不知道如何使用作用域 CSS 设置该 HTML 的样式,因为它缺少用于作用域的数据属性。

略长的版本:

我有一个名为 highlight 的函数,它接受一个字符串并返回一个 HTML 字符串,其中突出显示所有出现的搜索词,意思是被 <span class="match"> 包围。但是,由于我在字符串中手动执行此操作,因此该跨度没有获得我的 Vue 组件中的作用域 CSS 需要工作的特殊数据属性,因此我设置这些匹配样式的唯一方法是使我的 CSS没有范围,我不想这样做。是否有更特定于 Vue 的方式来执行此操作? 函数如下所示:

// Source: http://***.com/a/280805/2874789
function highlight(data, search) 
    return data.replace(
      new RegExp("(" + preg_quote(search) + ")", 'gi'),
      "<span class=match>$1</span>"
    );

(preg_quote只是一个函数,用来转义需要转义的东西)

谢谢!

【问题讨论】:

【参考方案1】:

动态生成的内容 使用 v-html 创建的 DOM 内容不是 受范围样式影响,但您仍然可以使用 deep 选择器。

似乎没有 VueJS 特定的方式来做这件事。听起来您最好的选择是在突出显示函数的输出中内嵌样式,或者使用全局类。

function highlight(data, search) 
  return data.replace(
    new RegExp("(" + preg_quote(search) + ")", 'gi'),
     "<span class=match>$1</span>"
    );



<style>
  .match 
    color: yellow;
  
</style>

function highlight(data, search) 
  return data.replace(
    new RegExp("(" + preg_quote(search) + ")", 'gi'),
     "<span style=" color: yellow ">$1</span>"
    );

你也可以试试深度选择器,不过我自己不是很熟悉。

https://vue-loader.vuejs.org/en/features/scoped-css.html

【讨论】:

【参考方案2】:

这很有趣。

不知道如何单独使用 scoped 样式来解决这个问题,但我认为我们可以使用 css 模块(也是作用域)通过额外的 &lt;style&gt; 元素来解决它。

我在想:

<style scoped>
  ...
</style>

<style module>
  .match 
    color: red;
  
</style>

然后,在你的替换功能中,你可以这样做:

`<span class="$this.$style.match">...</span>`

您可以在此处阅读有关 vue-loader 的 CSS 模块支持的更多信息:

http://vue-loader.vuejs.org/en/features/css-modules.html

【讨论】:

scoped 标签现在被认为已弃用,不推荐 与 CSS 标准不一样。这是 Vue 特有的东西。 @TabsNotSpaces 你有关于scoped 被弃用的来源吗?我想阅读更多关于使用什么的信息。谢谢! 它没有被弃用。他们在谈论 CSS 标准。【参考方案3】:

刚刚遇到类似的事情。最简单的解决方法,不要范围。只需命名您的标记和 CSS 类,这样它们就不会从其他模块继承,您就完成了。使用 javascript 来解决这个问题是大材小用。

【讨论】:

【参考方案4】:

好问题!我遇到了同样的问题,并以一种优雅的方式解决了它。迫不及待想分享!

假设您的模板如下所示

<template>
  <div class="match">
    <div v-html="<span>hello world</span>"></div>
  </div>
</template>

只是改变

<style scoped>
.match span 
    color: yellow;

</style>

compiled output: `.match span[data-v-f3f3eg9]  color: yellow; `

<style scoped>
.match >>> span 
    color: yellow;

</style>

compiled output: `.match[data-v-f3f3eg9] span  color: yellow; `

查看两个输出之间的差异。你应该知道我的意思。在Vue Loader Document 上查看更多信息。

【讨论】:

以上是关于Vue.js:如何使动态创建的 HTML 使用作用域 CSS?的主要内容,如果未能解决你的问题,请参考以下文章

Vue js在列表中添加动态字段,删除和排序不起作用

如何动态地将 id 提供给我的输入字段,就像我在 vue js html 中的音译 id 一样?

如何显示和隐藏在 vue js 中动态创建的 div(多格式选项卡结构)

使用 Vue.js 跨浏览器选项卡的反应式 localStorage 对象

如何在 Nuxt 中使路由区分大小写

使用 vue.js 动态向表中添加行