0

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.

1
  • 1
    Get rid of props on that. Commented Jan 30, 2018 at 18:52

3 Answers 3

1

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>

Sign up to request clarification or add additional context in comments.

7 Comments

The problem is now that if I don't set todos array, there will be an error saying that todos is undefined. I have the felling it always wants to re-create datas even if I need to keep Article 1 and Article 2
Yes, it is going to overwrite anything in there. Your todos should include everything you want to display. If Article 1 isn't in your todos data, it doesn't belong in the list. Otherwise, you're saying that server-rendered data is permanent.
All right. What I need to do is that server renders my list, then when I click on a button, data changes (i know how to do this, it's not a problem). As I understand, when my page loads, I need to set my todos with the exact same values than the html list already contains. But will Vue.js overwrite even if data is the same ? In such case, it's not really optimal.
If it overwrites but the data is the same, is it really overwriting?
You may want to ask a new question so you can describe in more detail the behavior you're trying to get.
|
0

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>

1 Comment

I don't really understand why I should add this on my html page. When I do it, something not very beautiful appears : {{todo.title}} and my data is not updated.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.