Vue.js 使用现有HTML中的数据加载Vue视图模型

Vue.js 使用现有HTML中的数据加载Vue视图模型,vue.js,vuejs2,Vue.js,Vuejs2,我想将Vue与预呈现的HTML一起使用。从长远来看,我们可能不会这样做,但目前看来,让服务器代码留在原地,使用Vue管理web应用程序的客户端逻辑似乎更容易 我似乎找不到任何描述如何让视图模型从HTML加载数据的内容。我的例子将与相同。尽管这个问题已经解决了(并且解决了?),但我似乎无法在1.x或2.x中实现它 当我设置一些HTML时 <div id="myvue"> <span v-text="message">Hello!</span> </

我想将Vue与预呈现的HTML一起使用。从长远来看,我们可能不会这样做,但目前看来,让服务器代码留在原地,使用Vue管理web应用程序的客户端逻辑似乎更容易

我似乎找不到任何描述如何让视图模型从HTML加载数据的内容。我的例子将与相同。尽管这个问题已经解决了(并且解决了?),但我似乎无法在1.x或2.x中实现它

当我设置一些HTML时

<div id="myvue">
    <span v-text="message">Hello!</span>
</div>
我希望用HTML中的数据对vm对象进行水合处理,以便
vm.message=='Hello!'是真的。但事实并非如此。我只是以一个错误结束,即
消息
未在版本1中定义。对于版本2,我得到一个警告,该警告说,实例上没有定义
属性或方法“message”,但在渲染期间引用。确保在数据选项中声明被动数据属性。

但是当我像这样在vm中声明数据属性时

var myvue = new Vue({
    el: '#myvue',
    data: {
        message: <something>
    }
});
var myvue=new Vue({
el:“#myvue”,
数据:{
信息:
}
});

无论
是什么(null,字符串,未定义),它总是替换HTML元素中的内容。有没有办法让Vue对象从HTML加载数据?

理论上不可能直接从HTML加载状态,因为渲染不是双射函数。两个简单的例子:

  • {{foo}

    呈现到
    2

    foo
    是字符串还是数字
  • {{foo+bar}

    渲染到
    6

    foo
    bar
    的值是多少
最简单的方法是获取用于在服务器上呈现的数据,将其序列化为JSON,并直接在文档中使用
window.hydrationData=…
呈现。这样,您可以在创建Vue实例时将其用于
数据


这种方法出现在官方的Vue演示应用程序中。

它与Vue无关,但与Vue一起使用时可以做到这一点

此组合基本上允许您定义输入或其他内容

<div id="mydiv">
    <input data-bind="init, textInput: content" value="foo"/>
</div>
通过对输入进行
init
绑定,vm内容在绑定时会加载来自输入的值


再说一遍,这不是Vue。如果呈现的HTML不依赖于计算属性,那么一个选项可能是解析生成的HTML以获取数据所需的值(例如使用
jQuery
vanilla js
创建一个数据对象,在实例化时传递给VM):

$(function(){
  var app = '#app';
  var $app = $(app);
  var data = {
    a: 0, // some initial value not present in HTML
    b: $app.find('.foo').text(),
    c: $app.find('input[name=c]').val()
  };
  var vm = new Vue({
    el: app,
    template: '...template...', // if needed
    data: data,
    ...
  });
});
实例化时,数据模型应与呈现的HTML相匹配。如果不是所有模板组件都是呈现的HTML的一部分,则可能需要提供模板。请注意,这很可能会导致应用程序在实例化后重新呈现。您可以添加
server rendered=“true”如果预呈现的HTML与
vm
将呈现的内容相同,请将属性设置为根应用程序元素,以防止出现这种情况

另一个不太自动化的选项是让模板在元素下方生成一个
标记,其中包含数据模型:

<script>
  window.MYSTATE = window.MYSTATE || {};
  window.MYSTATE['#app'] = {
    "a": 0,
    "b": "Some text",
    "c": "Some value"
  };
</script>

只需确保在页面加载后进行实例化(即,将其放置在页面底部的结束
正文
标记之前)

嗨,mzgajner,谢谢你的回答。我还没有从这个角度考虑过,但我可以想象,当html不依赖计算时,我可以从html中提取一些基本的东西。比如将span的所有文本加载到一个模型中。我正在发布一个更详细的关于knockout.js的答案。
$(function(){
  var app = '#app';
  var $app = $(app);
  var data = {
    a: 0, // some initial value not present in HTML
    b: $app.find('.foo').text(),
    c: $app.find('input[name=c]').val()
  };
  var vm = new Vue({
    el: app,
    template: '...template...', // if needed
    data: data,
    ...
  });
});
<script>
  window.MYSTATE = window.MYSTATE || {};
  window.MYSTATE['#app'] = {
    "a": 0,
    "b": "Some text",
    "c": "Some value"
  };
</script>
var vm = new Vue({
  el: '#app',
  template: '...template if needed...',
  data: $.extend(true, {}, window.MYSTATE['#app'])
  ...
});