Reputation: 386
I have the following code generated by my server :
<div id="app-4" data-server-rendered="true">
<ul>
<li>Article 1 test1</li>
<li>Article 2 test2</li>
</ul>
</div>
Now with Vue.js, I would like to generate again this code if data changes. Is that possible ?
I tried to do something but it doesn't work :
var app4 = new Vue({
el: '#app-4',
props: ["todo"],
template: ' <ul>\n' +
' <li v-for="todo in todos">\n' +
' {{ todo.title }} {{ todo.text }}' +
' </li>\n' +
' </ul>',
data: {
todos: [
{ title: 'Article 3', text:"test1" },
{ title: 'Article 4', text:"test2" },
{ title: 'Article 5', text:"test3" }
]
}
})
Theoritically, as I put a data.todos value which is not the same than in output generated by the server, it should change. But it stays with my 2 li. If I remove data-server-rendered="true", it will display my 3 li.
Upvotes: 0
Views: 1598
Reputation: 386
My problem was due to \n
My html has to be like this
<ul id="app-5" data-server-rendered="true"><li>Learn JavaScript test1</li><li>Learn Vue test2</li><li>Build something awesome test3</li></ul>
And my js :
var app5 = new Vue({
el: '#app-5',
template: '<ul id="app-5"><li v-for="todo in todos">{{ todo.title }} {{ todo.text }}</li></ul>',
data: {
todos: [
{ title: 'Learn JavaScript', text:"test1" },
{ title: 'Learn Vue', text:"test2" },
{ title: 'Build something awesome', text:"test3" },
]
}
})
I guess it would have worked without problem if I would have used a template for both rendering. This is what I will do.
Upvotes: 0
Reputation: 43881
I think the problem is that you are trying to have Vue overwrite the tag that includes the data-server-rendered
. You want to put your hydration inside that. If I set el: '#app-4'
(as you do), I get an error:
The client-side rendered virtual DOM tree is not matching server-rendered content.
If I set id="app-5"
in the ul
and use el: '#app-5'
in my Vue spec, I don't get that error, and everything renders ok.
var app4 = new Vue({
el: '#app-5',
template: ' <ul>\n' +
' <li v-for="todo in todos">\n' +
' {{ todo.title }} {{ todo.text }}' +
' </li>\n' +
' </ul>',
data: {
todos: [
{ title: 'Article 3', text:"test1" },
{ title: 'Article 4', text:"test2" },
{ title: 'Article 5', text:"test3" }
]
}
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app-4" data-server-rendered="true">
<ul id="app-5">
<li>Article 1 test1</li>
<li>Article 2 test2</li>
</ul>
</div>
Upvotes: 1
Reputation: 1370
on your js page can you declare the template using components.
Vue.component('todo',{
template:`<ul><slot></slot></ul>`,
});
and on your html page
<todo>
<li v-for="todo in todos">{{todo.title}}</li>
</todo>
Upvotes: 0