Skip to content

define temporary variables in Vue.js template #1172

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

Closed
mariusa opened this issue May 12, 2020 · 7 comments
Closed

define temporary variables in Vue.js template #1172

mariusa opened this issue May 12, 2020 · 7 comments

Comments

@mariusa
Copy link

mariusa commented May 12, 2020

What problem does this feature solve?

Sometimes we need to compute and reference the same value multiple times in a template.
It would help with readability & performance to be able to define variables in templates.

Somebody asked this here too:
https://stackoverflow.com/questions/43999618/how-to-define-a-temporary-variable-in-vue-js-template

What does the proposed API look like?

There's a suggestion in the answers, but this allows setting only 1 variable:

<li v-for="id in users" :key="id" :set="user = getUser(id)">

maybe like this?

<li v-for="id in users" :key="id" :set="user = getUser(id); var2 = true; var3=getUserPrefs(id)">

@sionzee
Copy link

sionzee commented May 12, 2020

In my opinion the proper way is to create computed array where is this value already fetched.
eg.: (renamed your users to userIds)

const users = computed(() => userIds.map(uId => getUser(uId)))

Everything what you call a variable can be converted to "computed" style. So why make it more complex?

@LinusBorg
Copy link
Member

Change of template syntax is a pretty significant change and will require an RFC.

There's ongoing discussions here: vuejs/rfcs#73

@dima-hx
Copy link

dima-hx commented Feb 10, 2022

You can set multiple properties in :set directive in such way:

                        <div :set="br = {variable1: someCalculation(), variable2: anotherCalculations()}">
                            <pre>{{br}}</pre>
                        </div>

@mariusa
Copy link
Author

mariusa commented Feb 11, 2022

Interesting. Where is :set documented? Can't find it at https://vuejs.org/api/built-in-directives.html
Please add it to vuejs/rfcs#73

@dima-hx
Copy link

dima-hx commented Feb 11, 2022

Interesting. Where is :set documented? Can't find it at https://vuejs.org/api/built-in-directives.html Please add it to vuejs/rfcs#73

It's not an 'undocumented' feature. Vue will evaluate the JavaScript of any bound attributes and I just chose to invent an attribute called :set. .

https://dev.to/pbastowski/comment/7fc9

@neverblued
Copy link

IMHO better be like:

<li v-for="id in users" :key="id" v-set="{ user: getUser(id), var2: true, var3: getUserPrefs(id) }">

@DevilTea
Copy link

I've a solution that is using a component to solve this issue.

Only tested in vue >= 3.3.0

https://www.npmjs.com/package/vue-temp-var

Example

<script setup lang="ts">
import TempVar from 'vue-temp-var'

function getRandomNumber() {
  return Math.random()
}
</script>

<template>
  <div v-for="i in 10" :key="`random-${i}`">
    <!-- cause the return value would be random, we should store it somewhere -->
    <!-- bind a prop 'define' to 'TempVar'. Because it is a prop, it would still be reactive -->
    <TempVar :define="{ randomNum: getRandomNumber() }">
      <!-- Destruct from slot: defined, the type would be kept -->
      <template #defined="{ randomNum }">
        <span>"{{ randomNum }}"</span>
        <span v-if="randomNum > 0.5"> is larger than 0.5</span>
        <span v-else> is smaller than 0.5</span>
      </template>
    </TempVar>
  </div>
</template>

@github-actions github-actions bot locked and limited conversation to collaborators Sep 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants