-
Notifications
You must be signed in to change notification settings - Fork 545
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
In-template variable definition #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It was proposed in the past: vuejs/vue#7325 |
Probably you already know, but if you use JSX you could do this: export default {
render() {
const b = this.item && this.item.a && this.item.a.b;
return (
<div class="container">
<p class="row">{b && b.hello}</p>
<p class="row">{b && b.world}</p>
<p class="row">{b && b.goodbye}</p>
</div>
)
}
} |
You can also create a method that accepts a parameter, so you can use it in |
The issue with methods is that they aren't cached, so a bit less performatic. |
I see, and a local variable could serve as an in-loop cache for method results where computed props can't be used. |
Whenever I hear someone say that, I think "this is a perfect situation for creating a component for that item!". That would give you the ability to use simple computed getters that can be cached. A component should always have exactly one reason to exist and one mission to execute. This parent components mission is not knowing how to render the child items. |
Well, component instantiations come at a price (memory-footprint & render performance), so sometimes it's better to render i list's items in the parent for that reason. There shuold be ways to keep these situations performant, an this RFC aims to address it. |
Forgive my ignorance, I'm new to the vue community. Could the above be done with optional chaining as well? e.g. <template>
<div class="container">
<p class="row">{{ item?.a?.b?.hello }}</p>
<p class="row">{{ item?.a?.b?.world }}</p>
<p class="row">{{ item?.a?.b?.goodbye }}</p>
</div>
</template> it's stage 3 and has a babel plugin |
Not right now, as vue-es2015-template compiler doesn't aupport >es6 features But that can be solved. |
I was dealing with a similar concern recently in my work so wanted to add 2 cents... (My day job is in Ember so I'll pseudo-code the concepts) Generally I want to pass a data model to my components.. like pass a user to a component for showing the user's badge or pass a meeting to a component for showing when and where and who's attending that meeting... it's just simpler to do I've also recently come to appreciate that this allows me to flatten out deeply nested data and to add logic around data that's not directly suited to my use case. So I recently did something like this: // Component receives `model`
name = model.model_name
date = computed(() => (model.date && date_from_format(model.date, 'YYYY-MM-DD')) || undefined)
instructions = computed(() => (model.location && model.location.meeting_instructions) || undefined) The same can be done for lists... if I need to display a list of users = computed(() => {
return model.users.map((user) => {
const spouse = model.spouse || {};
return {
name: user.name,
spouseName: spouse.name
};
});
}); Now the template can iterate |
Will this make the code much less clear? In my opinion, if you have a large component, it will be difficult to understand what the variable is, where it comes from if it is not in the Much simpler code that doesn't have any "magic" variables: <template>
<div class="container" v-if="item && item.a && item.a.b">
<p class="row">{{item.a.b.hello}}</p>
<p class="row">{{item.a.b.world}}</p>
<p class="row">{{item.a.b.goodbye}}</p>
</div>
</template> |
Computed can also solve v-for performance problem, as items could be mapped to have additional keys for display purposes + you can use object destructuring. Btw. most of times proper Item structurizing can solve this issue. |
I think I found some kind of way to accomplish in-template variables in vue 3. Here is an example where I create the "in-template variable" inside of a v-for. Basically declare an inline array and iterate over the single item. <div v-for='item in items'>
<div v-for="record of [cache.find(item.otherId).value]">
<span v-if="record">{{ record.name }}</span>
</div>
</div> In this case I feel like it's its kinda hacky, and I'm not really sure the performance impact. |
Looking at Angular template, their *ngIf directive supports local scoping <div *ngIf="condition as value">{{value}}</div> |
Which is why there are computed functions that do cache results. :-) |
|
It's great how this approach can be used to cache cross-referenced (calculated) item when I have two v-for for matching correct item from big list. This way I don't need to re-evaluate fetching of correct item for each action separately, but can simply fetch item only once and refer to it. It looks like this works correctly, even with events. I would hope to see this implement in more readable manner and without using v-for in hackish-way. Please consider implementing this as built-in-feature. |
There is also a way to set multiple variables in
|
Svelte implements this feature and has good Typescript support. |
I can't find any documentation on |
It was just a suggestion for the syntax, I believe. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Sometimes you will encounter such a situation:
These code with the same logic need to be written many times.
I hope there is a way to define local variables in the template, then the above code can be abbreviated as:
or
Q: Why not computed?
A: The
item
in the above code may come fromv-for
, socomputed
is not a feasible solution.The text was updated successfully, but these errors were encountered: