feat: v-scope
It's great! I'd like to migrate it to Vue Macros for early experience.
Deploy Preview for vuejs-coverage failed.
| Name | Link |
|---|---|
| Latest commit | ab4a41571054a7718966e8e84a80df5bea32d291 |
| Latest deploy log | https://app.netlify.com/sites/vuejs-coverage/deploys/63832143f2c6e80009ed5887 |
This is a good idea, but the pure string method is not very friendly.
Maybe we can?
<h1 v-let.a="msg + ` Vue`">{{ a }}</h1>
Shall we align the design with petite-vue (which uses v-scope and an object carrying the local variables)?
Shall we align the design with petite-vue (which uses
v-scopeand an object carrying the local variables)?
Excellent advice. I will try it later.
How is this PR now?
Really really really want to use petite-vue's v-scope in vue3 :)
Is it possible to define v-scope as an user defined directive?
Hi @edison1105, sorry to bug you ~
I want to ask, is there any timeline about when will this PR be merged? I found myself visit this page every day, really like this feature, thanks for your work :)
I care about this feature, because I recently taught a friend frontend programming.
He know a little js, but almost had no experience about html, css and reactive programming.
We used alpinejs for the teaching.
With alpine's x-data, the concept about reactive data is received very well.
But actually, we want to use vue, because alpine has no good component support.
This is why I care about this feature :)
Wish v-scope be supported soon, and we can teach in vue.
@xieyuheng I'm not sure when will merge, sorry~ It needs to be discussed by the core team.
Will the language server be updated to integrate v-scope with TypeScript?
@edison1105
I found that I can use component to do the following:
components/Scope.vue:
<script setup lang="ts">
import { reactive } from 'vue'
defineProps<{ scope: any }>()
</script>
<template>
<slot :scope="reactive(scope)" />
</template>
Example.vue:
<Scope :scope="{ count: 1 }" v-slot="{ scope }">
<div>{{ scope.count }}</div>
<button @click="scope.count++">add1</button>
</Scope>
@edison1105
I found that I can use component to do the following:
components/Scope.vue:<script setup lang="ts"> import { reactive } from 'vue' defineProps<{ scope: any }>() </script> <template> <slot :scope="reactive(scope)" /> </template>
Example.vue:<Scope :scope="{ count: 1 }" v-slot="{ scope }"> <div>{{ scope.count }}</div> <button @click="scope.count++">add1</button> </Scope>
yep, mentioned in https://github.com/vuejs/core/issues/7201#issuecomment-1326222371
Will the language server be updated to integrate
v-scopewith TypeScript?
Not sure
@xieyuheng Based on your example, made a similar component
// Scope/index.vue
<script setup lang="ts">
import { reactive } from 'vue'
</script>
<template>
<slot :="(reactive($attrs) as any)" />
</template>
// ForExampleMemoryStat/index.vue
<script lang="ts" setup>
import Scope from '@/shared/components/Scope/index.vue'
import { MemoryInfo, useMemory } from '@vueuse/core'
const { isSupported, memory } = useMemory()
const getBToMbString = (kb: number) => `${Math.ceil(kb / 1024 / 1024)} MB`
</script>
<template>
<Scope
v-if="isSupported && memory"
:="memory"
v-slot="{
usedJSHeapSize,
jsHeapSizeLimit,
totalJSHeapSize,
}: MemoryInfo"
>
<div class="grid grid-cols-2 grid-gap">
<div>usedJSHeapSize</div>
<div>{{ getBToMbString(usedJSHeapSize) }}</div>
</div>
<div class="grid grid-cols-2 grid-gap">
<div>totalJSHeapSize</div>
<div>{{ getBToMbString(totalJSHeapSize) }}</div>
</div>
<div class="grid grid-cols-2 grid-gap">
<div>jsHeapSizeLimit</div>
<div>{{ getBToMbString(jsHeapSizeLimit) }}</div>
</div>
</Scope>
</template>
Instead of
// ForExampleMemoryStat/index.vue
<script lang="ts" setup>
import { useMemory } from '@vueuse/core'
const { isSupported, memory } = useMemory()
const getBToMbString = (kb: number) => `${Math.ceil(kb / 1024 / 1024)} MB`
</script>
<template>
<template v-if="isSupported && memory">
<div class="grid grid-cols-2 grid-gap">
<div>usedJSHeapSize</div>
<div>{{ getBToMbString(memory.usedJSHeapSize) }}</div>
</div>
<div class="grid grid-cols-2 grid-gap">
<div>totalJSHeapSize</div>
<div>{{ getBToMbString(memory.totalJSHeapSize) }}</div>
</div>
<div class="grid grid-cols-2 grid-gap">
<div>jsHeapSizeLimit</div>
<div>{{ getBToMbString(memory.jsHeapSizeLimit) }}</div>
</div>
</template>
</template>
Of course, I understand that in this example the benefit is dubious in brevity. However, it may be useful to someone and in other scenarios it will be justified.
Size Report
Bundles
| File | Size | Gzip | Brotli |
|---|---|---|---|
| runtime-dom.global.prod.js | 90.2 kB | 34.4 kB | 30.9 kB |
| vue.global.prod.js | 148 kB (+731 B) | 53.8 kB (+255 B) | 48.1 kB (+306 B) |
Usages
| Name | Size | Gzip | Brotli |
|---|---|---|---|
| createApp | 50.3 kB | 19.7 kB | 18 kB |
| createSSRApp | 53.7 kB | 21 kB | 19.1 kB |
| defineCustomElement | 52.6 kB | 20.4 kB | 18.6 kB |
| overall | 64 kB | 24.8 kB | 22.5 kB |
I'm glad this feature is coming
I think v-scope should only be allowed in conditionals and blocks.
Allowing people to use v-scope anywhere will only allow abuse.
For that reason Svelte doesn't allow this.
I have a playground that demonstrates what I mean here.
@louiss0 the current behavior aligns with https://github.com/vuejs/petite-vue#usage There may still be changes before the merge.
@louiss0 the current behavior aligns with https://github.com/vuejs/petite-vue#usage There may still be changes before the merge.
Please consider doing this change there is no point in being able to declare variables in the template with random tags. It makes code soo confusing!
@louiss0 That could be a replacement for computed variables, but the variable is declared close to where it is used to improve readability.