Vue.js从模板中分离样式

Hug*_*o H 7 javascript vue.js

我使用带有<style>块的模板,出于CMS原因,该块必须靠近它的div.

当我运行Vue.js时,它似乎删除了样式块,说...

- Templates should only be responsible for mapping the state to the UI.     
  Avoid placing tags with side-effects in your templates, such as <style>, 
  as they will not be parsed.
Run Code Online (Sandbox Code Playgroud)

我能做什么?

var app = new Vue({
  el: '#app'
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.0/vue.js"></script>

<div id="app">
  <style>
    #div_123 {
      background: http://placehold.it/850x150;
    }

    @media screen and (max-width: 640px) {
      #div_123 {
         background: http://placehold.it/350x150;
      }
    }
  </style>
  <div id="div_123">
    Test
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

Fus*_*sty 5

问题

在 Vue 2 中,根实例比在 Vue 1 中更像是一个组件。

这意味着当您将 Vue 实例绑定到 #app 时,它会将 #app 中的所有内容消化为 vue 模板。这意味着标签无效,它们将从模板中删除。这就是 Vue 2 中的工作方式。

娱乐

我在这里的代码笔中重新创建了这个问题

https://codepen.io/Fusty/pen/gqXavm?editors=1010

<style>嵌套的标签Vue公司内标签势必。它应该将背景设置为红色,将文本颜色设置为绿色。然而,我们只看到了这一点(取决于你的浏览器启动 Vue 的速度),最终 vue 删除这些样式标签,因为它会将 #app 作为模板消化,然后用它认为应该存在的内容更新 DOM(没有<style>标签) )。

更好的娱乐

感谢 Vue-Land discord 上的用户 @joestrouth1#6053,我们也有这个问题的分支。

https://codepen.io/joesrouth1/pen/WPXrbg?editors=1011

查看控制台。它读。. .

"[Vue warn]: Error compiling template:

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <style>, as they will not be parsed.

1  |  <div>
2  |      <style>
   |      ^^^^^^^
... etc ...
Run Code Online (Sandbox Code Playgroud)

抱怨模板中的样式标签。

这归结于实际问题。值得注意的是,这在 Vue 1 中没有发生。可能是因为它比组件更独特地对待根实例,但我对这个主题不是 100% 确定。

解决方案(黑客,不是最佳实践或特别推荐)

<style>标签仍然在过程中DOMcreated的生命周期挂钩的Vue的实例,它们由时间删除mounted生命周期挂钩火灾。让我们查询 #app 元素中的所有样式标签,保存它们,然后在 Vue 消化模板后将它们附加回 #app 元素。

将以下内容添加到您的根 Vue 实例将获取<style>您的 Vue 实例绑定到的任何元素中的任何标签 (via el: 'someSelector') 并将它们附加(可能重新定位它们)到您的 Vue 实例绑定到的元素。

  created: function() {
    this.styleTagNodeList = document.querySelector(this.$options.el).querySelectorAll('style');
  },
  mounted: function() {
    for(var i = 0; i < this.styleTagNodeList.length; ++i)
      this.$el.appendChild(this.styleTagNodeList[i]);
  }
Run Code Online (Sandbox Code Playgroud)

注意:这绝对是一个 hack,它可能会产生意想不到的后果,我还没有遇到过,也不能明确否认。使用风险自负。


bac*_*nck 1

这适用于我的特定情况,我允许用户存储 CSS 字符串,然后我需要在特定页面上呈现它 - ei:预览页面。

这里的上下文css 以字符串形式保存在数据库中,在 Vue 组件中获取和渲染。

# html
<html>
  <head>
    <style id="app_style"></style>
  </head>
  <body>

    <div id="app"></div>

  </body>
</html>
Run Code Online (Sandbox Code Playgroud)
# app.vue

data() {
  return {
    dynamic_css: ''
  }
},

created() {
  // fetch css from database, set as `this.dynamic_css`
},

watch {
  dynamic_css: function(newValue) {
    document.getElementById('app_style').innerHTML = newValue
  }
}
Run Code Online (Sandbox Code Playgroud)