2017-02-07 53 views
0

我想將Vue與預先呈現的HTML一起使用。從長遠來看,我們可能不會,但現在離開服務器代碼並使用Vue管理Web應用程序的客戶端邏輯似乎更容易。使用現有HTML中的數據加載Vue視圖模型

我似乎無法找到任何描述如何讓視圖模型從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' 
}); 

我希望能有來自HTML數據水合VM對象,使vm.message == 'Hello!'是正確的。但是這並沒有發生。我剛剛結束了一個錯誤,指出message不與1版定義的2.0版本,我得到的是說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.

但警告,當我宣佈data屬性在VM像這樣

var myvue = new Vue({ 
    el: '#myvue', 
    data: { 
     message: <something> 
    } 
}); 

無論<something>是什麼(null,一個字符串,未定義),它總是替換HTML元素中的內容。有什麼辦法讓Vue對象從HTML中加載數據?

回答

0

理論上不可能直接從HTML中提取狀態,因爲渲染不是雙射函數。兩個簡單的例子:

  • <p>{{ foo }}</p>呈現爲<p>2</p>foo是字符串還是數字?
  • <p>{{ foo + bar }}</p>呈現爲<p>6</p>foobar的值是多少?

保溼狀態的最簡單方法是將您用於在服務器上呈現的數據,序列化爲JSON並直接在文檔中使用<script>window.hydrationData = ...</script>。這樣,您可以在創建Vue實例時將其用於data

這種方法是在官方Vue演示程序中的also used

+0

嗨mzgajner,謝謝你的回答,我沒有從這個角度考慮它,但我可以想象,當他們不依賴於計算時,我可以從html中提取一些基本的東西,比如將所有跨度的文本加載到模型中,我發佈了一個引用knockout.js的答案,更多詳情。 – skagzilla

0

這與Vue無關,但當與ErikSchierboom's knockout-pre-rendered custom binding一起使用時,Knockout.js可能會這樣做。

這個組合基本上可以讓你定義的輸入或東西

<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。但是我認爲我會把它放在有助於某人的事情上。

0

如果您的呈現HTML不依賴於計算屬性,一個選項可能是解析生成的HTML以獲取您的數據所需的值(例如使用jQueryvanilla-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"屬性添加到您的根應用程序元素,以防止此if預呈現的HTML與vm呈現的內容完全相同。

另外,不那麼自動選擇是有你的模板生成只是你的元素下一個<script>標籤,它在它的數據模型:

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

確保您的數據正確逃進JSON格式。然後,在你實例您的應用程序,使用window.MYSTATE [「#應用程序」]作爲數據對象的頁面腳本(做深克隆,以防止window.MYSTATE情況的變化影響到你的模型。

var vm = new Vue({ 
    el: '#app', 
    template: '...template if needed...', 
    data: $.extend(true, {}, window.MYSTATE['#app']) 
    ... 
}); 

只是確保你在頁面加載後進行實例化(即通過在頁面底部放置body標籤之前進行實例化)

相關問題