2017-02-07 1 views
0

미리 렌더링 된 HTML로 Vue를 사용하고 싶습니다. 장기적으로는 그렇지 않을 수도 있지만, 지금은 서버 코드를 그대로두고 Vue를 사용하여 웹 앱의 클라이언트 로직을 관리하는 것이 더 쉬워 보입니다.기존 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 없다는 오류와 끝까지 나는 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.

을 말한다 그러나 경고가 버전 2와 버전 1에 정의되어 있지 않은 나는 그렇게

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

같은 VM의 데이터 속성을 선언 할 때 <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와 관련이 없지만 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 태그 앞에 페이지 맨 아래에 배치하여)

관련 문제