core icon indicating copy to clipboard operation
core copied to clipboard

feat: v-scope

Open edison1105 opened this issue 3 years ago • 22 comments

rfc: https://github.com/vuejs/rfcs/issues/73 close #7201 playground

edison1105 avatar Nov 26 '22 12:11 edison1105

It's great! I'd like to migrate it to Vue Macros for early experience.

sxzz avatar Nov 26 '22 15:11 sxzz

Deploy Preview for vuejs-coverage failed.

Name Link
Latest commit ab4a41571054a7718966e8e84a80df5bea32d291
Latest deploy log https://app.netlify.com/sites/vuejs-coverage/deploys/63832143f2c6e80009ed5887

netlify[bot] avatar Nov 27 '22 08:11 netlify[bot]

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>

Tyh2001 avatar Dec 02 '22 07:12 Tyh2001

Shall we align the design with petite-vue (which uses v-scope and an object carrying the local variables)?

Justineo avatar Dec 02 '22 07:12 Justineo

Shall we align the design with petite-vue (which uses v-scope and an object carrying the local variables)?

Excellent advice. I will try it later.

edison1105 avatar Dec 02 '22 08:12 edison1105

How is this PR now?

Really really really want to use petite-vue's v-scope in vue3 :)

xieyuheng avatar Feb 10 '23 11:02 xieyuheng

Is it possible to define v-scope as an user defined directive?

xieyuheng avatar Feb 10 '23 11:02 xieyuheng

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 :)

xieyuheng avatar Feb 27 '23 08:02 xieyuheng

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 avatar Feb 27 '23 08:02 xieyuheng

@xieyuheng I'm not sure when will merge, sorry~ It needs to be discussed by the core team.

edison1105 avatar Feb 27 '23 08:02 edison1105

Will the language server be updated to integrate v-scope with TypeScript?

mon-jai avatar Mar 23 '23 01:03 mon-jai

@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>

xieyuheng avatar Mar 25 '23 21:03 xieyuheng

@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

edison1105 avatar Mar 26 '23 00:03 edison1105

Will the language server be updated to integrate v-scope with TypeScript?

Not sure

edison1105 avatar Mar 26 '23 00:03 edison1105

@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.

100100101 avatar May 08 '23 08:05 100100101

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

github-actions[bot] avatar Oct 20 '23 03:10 github-actions[bot]

I'm glad this feature is coming

louiss0 avatar May 23 '24 20:05 louiss0

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. image

I have a playground that demonstrates what I mean here.

louiss0 avatar May 23 '24 20:05 louiss0

@louiss0 the current behavior aligns with https://github.com/vuejs/petite-vue#usage There may still be changes before the merge.

edison1105 avatar May 24 '24 01:05 edison1105

@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 avatar May 24 '24 02:05 louiss0

@louiss0 That could be a replacement for computed variables, but the variable is declared close to where it is used to improve readability.

mon-jai avatar May 24 '24 03:05 mon-jai