🐕

【Vue3・Nuxt3】最新のVue3で、`<script setup>`で単に値をexportする(defineExposeではない)

に公開2

結論

下記のように、先に<script><script setup>でない)でexportすればよいです。

GoodExportValue.vue
<template>
  <p>dummy</p>
</template>

<script lang="ts">
import { a } from '../utils/a'
import { b } from '../utils/b'

/**
 * このように、通常のscriptでexportすることによって、正しくexportできる。
 */
export const value = 42
</script>

<script setup lang="ts">
// eslintのimport/firstルールを有効にしていると、eslint --fixしたときに、上述の`export const value`をここ(<script setup>)に持ってこられるので、importはsetupでないscriptで行う。
// その場合も、importしたものは<script setup>内で使えるので、安心してください。
// import { b } from '../utils/b' // <script>でimportするようにする

const { foo = 42 } = defineProps<{
  foo: number
}>()
</script>

逆に、下記のように<script setup>でexportすることはできません。

NoGoodExportValue.vue
<template>
  <p>{{ foo }}</p>
</template>

<script setup lang="ts">
/**
 * defineExposeでインスタンスの下に生やしたいわけではなく、
 * 通常のモジュールと同様に、
 * モジュール内の変数として単に公開したい。
 * しかしこれはエラーになる。
 * ```
 * [@vue/compiler-sfc] <script setup> cannot contain ES module exports. If you are using a previous version of <script setup>, please consult the updated RFC at https://github.com/vuejs/rfcs/pull/227.
 * ```
 */
export const value = 42

const { foo = 42 } = defineProps<{
  foo: number
}>()
</script>

defineExposeは?

defineExposeはコンポーネントのインスタンスの下に生やすためのものです。
単なる値をexportするためのものではありません。

これは割と勘違いされているのではないかと思います。
わかる~。

Parent.vue
<template>
  <ChildComponent ref="child" />
  <button @click="check">Call Child Method</button>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const child = useTemplateRef<InstanceType<typeof ChildComponent>>('child')

function check() {
  if (child.value) {
    // defineExposeされたものが、インスタンスに生えている
    child.value.sayHello()
    console.log('Count:', child.value.count)
  }
}
</script>
Child.vue
<template>
  <div>Child</div>
</template>

<script setup lang="ts">
const count = ref(0)

function sayHello() {
  console.log('Hello from child component!')
}

defineExpose({
  sayHello,
  count,
})
</script>

結論

<script setup>ではなく<script>でexportせよ。

GoodExportValue.vue
<template>
  <p>dummy</p>
</template>

<script lang="ts">
export const value = 42
</script>

<script setup lang="ts">
const { foo = 42 } = defineProps<{
  foo: number
}>()
</script>

Discussion

junerjuner

逆に、下記のように<script setup>でexportすることはできません。

許容されているのは type / interface の export のみですね。