2017-02-07 6 views
0

事前レンダリングされたHTMLでVueを使用したいと思います。長期的にはそうではないかもしれませんが、サーバーコードをそのまま残し、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!'がtrueです。しかし、それは起こりません。私はちょうど私が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.

を言う警告を受けるmessageが、バージョン2では、バージョン1で定義されていないというエラーになってしまう。しかし、私はそう

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

のように、VM内のデータプロパティを宣言するとき<something>が何であっても(null、文字列、未定義)、HTML要素の内容は常に置き換えられます。 VueオブジェクトにHTMLからデータをロードする方法はありますか?

答えて

0

HTMLから状態を直接水和することは理論的に不可能です。なぜなら、レンダリングは単射関数ではないからです。 2つの簡単な例:

  • <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から取り出すことができるいくつかの基本的なことがあると想像することができます。もっと詳しく。 – skagzilla

0

これはVueとは関係ありませんが、Knockout.jsErikSchierboom's knockout-pre-rendered custom bindingと一緒に使用するとこれを行うことができます。このコンボは、本質的にあなたが

<div id="mydiv"> 
    <input data-bind="init, textInput: content" value="foo"/> 
</div> 

入力または何か

を定義し、それへの入力に結合 init

function ViewModel() { 
    this.content = ko.observable(); 
} 

var vm = new ViewModel(); 
ko.applyBindings(vm, $('#mydiv')[0]) 

をモデルオブジェクトをバインドすることができます

、VMのコンテンツはでロードされますバインドされたときの入力値。

また、Vueではありません。しかし、誰かを助けるために私はそれを置くと思った。

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

あなたのデータが適切にJSON形式にエスケープされていることを確認してください:

もう、いないので、自動化されたオプションは、あなたのテンプレートはその中のデータモデルは、ちょうどあなたの要素の下<script>タグを生成させることです。その後、アプリをインスタンス化、ページのスクリプトで、あなたのモデルに影響を与えるwindow.MYSTATEインスタンスの変化を防ぐために、深いクローンをやって(データオブジェクトとしてwindow.MYSTATE [「#アプリ」]を使用します。

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

ページがロードされた後にインスタンシエーションを実行することを確認してください(つまり、ページの最後にこれを配置することによって、bodyタグが閉じます)。

関連する問題