首页 > 解决方案 > 使用 v-html 从 textarea 添加 CSS 规则

问题描述

我正在构建一个所见即所得类型的应用程序,其中用户可以在文本区域中编写 CSS,并且 CSS 规则将应用于页面上的 HTML 我在模板中尝试过类似的操作

<textarea v-bind="css"></textarea>
<style v-html="css"></style>

VueCompilerError:在客户端组件模板中忽略带有副作用 ( 和 ) 的标签。

标签: javascriptcssvue.jswysiwyg

解决方案


老答案,下面是更好的一个

使用 v-model 添加 textarea:

<textarea v-model="css" />

您可以在 onMounted 挂钩中创建样式标签:

onMounted(() => {
  const style = document.createElement("style");
  style.type = "text/css";
  updateCss(style, css.value);

  document.getElementsByTagName("head")[0].appendChild(style);

  el.value = style;
});

您以后必须能够访问此元素,因此将样式分配给 el.value。

然后在输入值上添加监视:

watch(css, () => {
  updateCss(el.value, css.value);
});

其中 updateCss 是一个函数:

const updateCss = (el, css) => {
  if (el.styleSheet) {
    el.styleSheet.cssText = css.value;
  } else {
    el.innerHTML = "";
    el.appendChild(document.createTextNode(css));
  }
};

演示:

https://codesandbox.io/s/cocky-mestorf-uqz6f?file=/src/App.vue:246-463

编辑

我找到了更好的解决方案:

<template>
  <textarea v-model="css" />
  <component :is="'style'" type="text/css" v-text="css"></component>
</template>

<script>
import { ref } from "vue";
export default {
  setup() {
    const css = ref("body { background-color: blue; }");
    return { css };
  },
};
</script>

组件不会抛出关于样式标签的错误:

<component :is="'style'">

请注意,这里有 v-text 而不是 v-html。V-html 可能不安全。

演示: https ://codesandbox.io/s/festive-germain-q9tg3?file=/src/App.vue:122-281


推荐阅读