简体   繁体   English

Vue.js:如何使动态创建的 HTML 使用范围为 CSS?

[英]Vue.js: How can I make dynamically created HTML use scoped CSS?

Short version:简洁版本:

I'm generating a string with HTML in a component's method, and I can't figure out how to style that HTML with scoped CSS, because it's missing the data attribute for scoping.我在组件的方法中生成一个带有 HTML 的字符串,但我无法弄清楚如何使用范围为 CSS 的 HTML 设置样式,因为它缺少用于范围界定的数据属性。

Slightly longer version:稍微长一点的版本:

I have a function called highlight which takes a string and returns an HTML string with all occurrences of a search term highlighted, meaning surrounded by a <span class="match"> .我有一个名为 highlight 的 function,它接受一个字符串并返回一个 HTML 字符串,其中突出显示所有出现的搜索词,意思是被<span class="match">包围。 However, since I'm doing this manually in a string, that span doesn't get the special data attribute that the scoped CSS in my Vue component needs to work, so the only way for me to style those matches is to make my CSS not scoped, which I'd like to not have to do.但是,由于我是在一个字符串中手动执行此操作,因此该跨度没有获得我的 Vue 组件中的作用域 CSS 需要工作的特殊数据属性,因此我设置这些匹配样式的唯一方法是使我的 CSS没有范围,我不想这样做。 Is there a more Vue-specific way for me to do this?有没有更特定于 Vue 的方法让我做到这一点? The function looks like this: function 看起来像这样:

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

(preg_quote is just a function that escapes things that need to be escaped) (preg_quote 只是一个 function 转义了需要转义的东西)

Thanks!谢谢!

Dynamically Generated Content DOM content created with v-html are not affected by scoped styles, but you can still style them using deep selectors.动态生成的内容使用 v-html 创建的 DOM 内容不受范围样式的影响,但您仍然可以使用深度选择器设置它们的样式。

There doesn't appear to be a VueJS specific way of doing it.似乎没有 VueJS 特定的方法。 It sounds like your best option is to either style in-line in your highlight function's output, or use a global class.听起来你最好的选择是在高亮函数的输出中内嵌样式,或者使用全局类。

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


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

or或者

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

You can also try deep selectors, but I am not very familiar with them myself.你也可以尝试深度选择器,但我自己对它们不是很熟悉。

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

This is an interesting one.这是一个有趣的。

Not sure how to approach this with scoped styles alone but I think we can hack around it with an additional <style> element using css modules (which are also scoped).不知道如何单独使用scoped样式来解决这个问题,但我认为我们可以使用 css 模块(也是作用域的)通过一个额外的<style>元素来解决它。

I was thinking like:我在想:

<style scoped>
  ...
</style>

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

Then, in your replace function you can do:然后,在您的替换功能中,您可以执行以下操作:

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

You can read more about vue-loader's CSS module support here:您可以在此处阅读有关 vue-loader 的 CSS 模块支持的更多信息:

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

Just ran into something similar.刚刚遇到类似的事情。 The easiest way around it, don't scope it.解决它的最简单方法,不要限定范围。 Just namespace your markup and CSS classes so they don't get inherited from some other module and you're done.只需命名您的标记和 CSS 类,这样它们就不会从其他模块继承,您就完成了。 Messing around with JavaScript to pull this off is overkill.用 JavaScript 来解决这个问题是矫枉过正的。

Good question.好问题。 I had the same problem and solved it in an elegant way.我遇到了同样的问题并以优雅的方式解决了它。 Can't wait to share!等不及要分享了!

Suppose your template looks like this假设你的模板看起来像这样

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

Just change只是改变

<style scoped>
.match span {
    color: yellow;
}
</style>

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

to

<style scoped>
.match >>> span {
    color: yellow;
}
</style>

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

Look at the difference between the two outputs.查看两个输出之间的差异。 You should know what I mean.你应该明白我的意思。 See more on the Vue Loader Document .Vue Loader 文档中查看更多信息。

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

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