我想将Vue与预呈现的HTML一起使用。从长远来看,我们可能没有,但是现在似乎更容易保留服务器代码并使用Vue来管理Web应用程序的客户端逻辑。
我似乎找不到任何描述如何让视图模型从HTML加载数据的内容。我的例子与https://github.com/vuejs/Discussion/issues/56相同。即使该问题已经关闭(并且已修复?),我似乎也无法在1.x或2.x中工作。
当我设置一些HTML
时<div id="myvue">
<span v-text="message">Hello!</span>
</div>
然后为它创建一个视图模型
var vm = new Vue({
el: '#myvue'
});
我希望让vm对象与来自HTML的数据保持一致,以便vm.message == 'Hello!'
成立。但这不会发生。我最后得到的错误是message
未定义版本1.对于版本2,我收到一条警告Property or method "message" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
但是当我在vm中声明数据属性时就像这样
var myvue = new Vue({
el: '#myvue',
data: {
message: <something>
}
});
无论<something>
是什么(null,一个字符串,未定义),它总是替换HTML元素中的内容。有没有办法让Vue对象从HTML加载数据?
答案 0 :(得分:0)
理论上不可能直接从HTML中保存你的状态,因为渲染不是一个双射函数。两个简单的例子:
<p>{{ foo }}</p>
呈现给<p>2</p>
。 foo
是字符串还是数字?<p>{{ foo + bar }}</p>
呈现给<p>6</p>
。 foo
和bar
的价值是什么?补充状态的最简单方法是获取用于在服务器上呈现的数据,将其序列化为JSON并直接在文档中使用<script>window.hydrationData = ...</script>
呈现它。这样,您可以在创建Vue实例时将其用于data
。
此方法在官方Vue演示应用中为also used。
答案 1 :(得分:0)
与Vue无关,但与Knockout.js一起使用时,ErikSchierboom's knockout-pre-rendered custom binding可以执行此操作。
这个组合本质上允许您定义输入或其他东西
<div id="mydiv">
<input data-bind="init, textInput: content" value="foo"/>
</div>
然后将模型对象绑定到它
function ViewModel() {
this.content = ko.observable();
}
var vm = new ViewModel();
ko.applyBindings(vm, $('#mydiv')[0])
在输入上使用init
绑定时,vm内容会在绑定时从输入中加载值。
同样,这不是Vue。但是我想我会把它放在一边帮助别人。
答案 2 :(得分:0)
如果渲染的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>
标记,其中包含数据模型:
<script>
window.MYSTATE = window.MYSTATE || {};
window.MYSTATE['#app'] = {
"a": 0,
"b": "Some text",
"c": "Some value"
};
</script>
确保您的数据已正确转义为JSON格式。然后在您实例化应用程序的页面脚本中,使用window.MYSTATE [&#39;#app&#39;]作为数据对象(执行深度克隆以防止window.MYSTATE实例中的更改影响您的模型。< / p>
var vm = new Vue({
el: '#app',
template: '...template if needed...',
data: $.extend(true, {}, window.MYSTATE['#app'])
...
});
只需确保在页面加载后进行实例化(即在关闭body
标记之前将其放在页面底部)