6 ms·
I've been a React dev and after a couple of years of being Vue-curious, I banged around with it a little for a work project. My reaction was the opposite of yo
by ergothus 7y ago
I've been a React dev and after a couple of years of being Vue-curious, I banged around with it a little for a work project.
My reaction was the opposite of yours - I found the syntax to be some confusing "not really JS" that follows hard-to-discover rules and scoping. It felt very much like JSP - simple enough if you're just dropping in values, but as soon as something gets even slightly complex, it gets ugly quick. Error messages were also far less informative than React (to be fair, React has done a ton in the past couple of years to improve their error messaging).
Example: In react, if I want a <ui> with a bunch of <li>s, I tend to output a JSX <ul> with a bunch of <li>s from some JS loop. A 1:1 relationship between the tags I produce and the tags that are generated. My loop logic is pure JS, so no surprises there.
In Vue, the syntax is:
<ul id="example-1">
<li v-for="item in items"> {{ item.message }} </li>
</ul>
Which seems perfectly readable, but...The "<li> tag doesn't represent what gets rendered, it's a TEMPLATE of what gets rendered. Can I reference "item" in another "v-" attribute of the <li>? What happens if I wanted to conditionally include/not-include an <li> for the list of items?
A list shouldn't be where "complex" problems start. A list should still be "simple"
My anecdote doesn't beat yours, (and, generally, your anecdote is the more common one), but I wanted to offer an opposing data point, because I expected Vue to be less involved than React, and I found the opposite to be true.
- ratww 7y agoAnother way of rendering lists is like this: <ul id="example-1"> <template v-for="item in items"> <li>{{ item.message }}</li> </template> </ul>
- ergothus 7y agoInteresting. I was taking the example straight from their docs: https://vuejs.org/v2/guide/list.html https://vuejs.org/v2/guide/list.html What you have here does fix the 1:1 issue, but introduces an extra layer of abstraction that still feels unnecessary/less straight-forward compared to the React version.
- ultrarunner 7y agoIt's perfectly possible to refer to the `item` in the loop template: <li v-for="item in items" :title="item.hint"> {{ item.message }} </li> I really don't have a problem thinking of them as templates. In a sense that's all we can do anyway with dynamic lists— I don't know how React works but it seems disadvantageous to be forced to run the loop again rather than be able to do a diff & DOM insert/splice behind the scenes. My only real complaint is that the HTML attribute gets lost a little too easily. I could probably hack up some syntax highlighting augmentations to fix that, but it doesn't really bother me enough. For what it's worth, JSX is supported in Vue as well, although I've found it's not really my thing compared to Vue templates.
- draw_down 7y agoThanks for the reply. My experience with things like this (idiosyncratic, hard to discover syntax and scoping rules) makes my spidey senses tingle when I start hearing about how “clean” something is. As you say, rendering a list shouldn’t be where the problems start.
- Pigo 7y agoThis is the kind of low-down I look for on these frameworks. It can be difficult to get insight from people who've been deep into a framework because they seem to get emotionally attached to their favorite. They ALL start from some well thought out paradigm, and can do what they were designed to do really well. How difficult is it when you start hitting those edge-cases?
- tqkxzugoaupvwqr 7y agoI think OP took a look at Vue but stopped at a very superficial level. Vue’s Getting Started guide mentions how to handle both cases OP complaints about. If you want to display only some items of an array, it is recommended to compute a new array that only includes the items you want to display[1]. A less performant way is to put a v-if into your v-for loop[2]. If you have a v-for loop `item in items` you can access `item` in any attribute. See [3] for an example. [1] https://vuejs.org/v2/guide/list.html#Displaying-Filtered-Sorted-Results https://vuejs.org/v2/guide/list.html#Displaying-Filtered-Sor... [2] https://vuejs.org/v2/guide/list.html#v-for-with-v-if https://vuejs.org/v2/guide/list.html#v-for-with-v-if [3] https://vuejs.org/v2/guide/list.html#v-for-with-a-Component https://vuejs.org/v2/guide/list.html#v-for-with-a-Component
- Jarwain 7y ago> What happens if I wanted to conditionally include/not-include an <li> for the list of items? Depending on the use-case, I wouldn't want to put the conditional in the template. Instead, I'd filter the array of `items`. Maybe using a computed property `filteredItems`. The idea being, you shouldn't be putting Too Much Logic within the template. Idk though, I started off in Vue and am very much enjoying it; I haven't spent a lot of time dabbling with React yet
- ng12 7y agoAgreed completely. My favorite example is the `slot` directive which doesn't exist in React because the pattern comes for free. To take the example from the Vue docs: // Component with a slot <ul> <li v-for="todo in filteredTodos" v-bind:key="todo.id"> <slot name="todo" v-bind:todo="todo"> {{ todo.text }} </slot> </li> </ul> // Consuming component <todo-list v-bind:todos="todos"> <template v-slot:todo="{ todo }"> <span v-if="todo.isComplete">x</span> {{ todo.text }} </template> </todo-list> This can be rewritten in React with much simpler, cleaner code: // Component with a "slot" <ul> {filteredTodos.map(todo => props.renderTodo ? props.renderTodo(todo) : todo.text)} </ul> // Consuming component <TodoList todos={todos} renderTodo={todo => `${todo.isComplete ? "x " : ""}${todo.text}` }/> Simplicity is key. In the React version you don't have to worry about the `slot` syntax, build a mental model of how Vue treats it, or risk running into the limitations of the feature.
- xdanger 7y agoI'm not really sure how can you say that the React code is simpler or cleaner? Where do props come from? Where's the span for x? <li>'s are generated by magic? I just don't like mixing html and js like that, maybe that's why it also seems messy to me. The vue example also isn't the greatest, some cruft could be removed using default slot and shorter syntax.
- ng12 7y agoBoth Vue and React have props. The above code is a snippet; I used the same format as the Vue documentation (which I agree is a little confusing). > Where's the span for x? I assumed Vue was only using the span for v-if, in React we don't need that extra node. > <li>'s are generated by magic? Whoops -- an omission on my part. They should be wrapping the inside of the mapping function. > I just don't like mixing html and js like that, maybe that's why it also seems messy to me. But this is where the magic is. It's exactly why React didn't need to invent a concept for "slots". I admit it's vaguely unfamiliar at first but if it increases both the power and simplicity of your template it's a no-brainer.
- 7y ago