使用Vuejs进行渐进增强 - 解析现有HTML

时间:2017-11-24 15:58:45

标签: vue.js vuejs2

我想使用Vue(v2)来管理HTML页面的各个部分,但是如果用户没有javscript,他们仍然会得到一个不错的页面。

e.g。服务器可能会输出:

<div id="rootAppContainer">
  ...
  <article is="foo" >
     <h1>Something cool</h1>
     <p>Here's a great article.</p>
  </article>
  ...
</div>

作为后备,这很好。但是我希望Vue能够装上这篇文章并用更好的东西代替它,例如。

<article>
   <p v-show="showTeaser" >{{teaser}}</p>
   <div v-show="!showTeaser" >
      <h1>{{title}}</h1>
      <p>Here you go:</p>
      <p>{{body}}</p>
   </div>
</article>

为此,我希望能够解析要加载的元素的pre-vue内容,以提取视图模型data然后按其模板格式化。

我以为我可以使用生命周期钩子或组件的数据方法来做到这一点,但是我找不到任何方法来获得对即将安装的节点的引用;直到它为时已晚(即mounted已被替换时)。

https://codepen.io/artfulrobot/pen/GOGBWQ?editors=1010

1 个答案:

答案 0 :(得分:2)

首先,我应该说你应该研究server side rendering

但是,如果您在没有SSR的情况下陷入困境,则可以在创建Vue之前解析DOM,并将文章替换为组件。

这是一个例子。

&#13;
&#13;
console.clear()

let root = document.querySelector("#rootAppContainer")
for (let article of root.querySelectorAll('article')){
  let title = article.querySelector("h1").textContent
  let body = article.querySelector("p").textContent
  let foo = document.createElement("foo")
  foo.setAttribute("title", title)
  foo.setAttribute("body", body)
  root.replaceChild(foo, article)
}

const app = new Vue({
  el: '#rootAppContainer',
  components: {
    foo: {
      props:["title", "body"],
      data: function() {
        return {
          showTeaser: true,
        };
      },
      computed: {
        teaser: function() {
          return "ooh, you won't believe this..." + this.title;
        }
      },
      template: `
        <article>
           <p v-show="showTeaser" >{{teaser}}</p>
           <div v-show="!showTeaser" >
              <h1>{{title}}</h1>
              <p>Here you go:</p>
              <p>{{body}}</p>
           </div>
        </article>
      `,
    }
  }
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="rootAppContainer">
  <h2>some content before articles</h2>
  <article>
    <h1>Something cool</h1>
    <p>Here's a great article.</p>
  </article>
  <h2>some content between articles</h2>
  <article>
    <h1>Another cool thing</h1>
    <p>Here's a great article.</p>
  </article>
  <article>
    <h1>And lastly something cool</h1>
    <p>Here's a great article.</p>
  </article>
  <h2>some content after articles</h2>

</div>
&#13;
&#13;
&#13;