How do you export default from inside script setup in Vue 3?
Asked Answered
V

6

16

The export default statement does not seem to work inside <script setup>.

If I try to export it in test.vue:

<template>
  <div id="test" class="test">

  </div>
</template>


<script setup>
const x = 5

export default {
    x
}
</script>


<style scoped lang="scss">
</style>

and then importing it into another blog.vue:

<script setup>
import x from './test'
</script>

I am getting this bulk of error:

app.js?id=3b6365f542826af47b926162803b3ef6:37396 Uncaught Error: Module build failed (from ./node_modules/vue-loader/dist/index.js):
TypeError: Cannot read properties of null (reading 'content')
    at selectBlock (:3000/Users/artur/PhpstormProjects/safa-ameedee.com/node_modules/vue-loader/dist/select.js:23:45)
    at Object.loader (:3000/Users/artur/PhpstormProjects/safa-ameedee.com/node_modules/vue-loader/dist/index.js:67:41)
    at Object../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/vue/backend/components/test.vue?vue&type=script&setup=true&lang=js (app.js?id=3b6365f542826af47b926162803b3ef6:37396:7)
    at __webpack_require__ (app.js?id=3b6365f542826af47b926162803b3ef6:64806:42)
    at Module../resources/vue/backend/components/test.vue?vue&type=script&setup=true&lang=js (app.js?id=3b6365f542826af47b926162803b3ef6:60116:217)
    at __webpack_require__ (app.js?id=3b6365f542826af47b926162803b3ef6:64806:42)
    at Module../resources/vue/backend/components/test.vue (app.js?id=3b6365f542826af47b926162803b3ef6:59477:102)
    at __webpack_require__ (app.js?id=3b6365f542826af47b926162803b3ef6:64806:42)
    at Module../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/vue/backend/components/blog.vue?vue&type=script&setup=true&lang=js (app.js?id=3b6365f542826af47b926162803b3ef6:37336:63)
    at __webpack_require__ (app.js?id=3b6365f542826af47b926162803b3ef6:64806:42)
    at Module../resources/vue/backend/components/blog.vue?vue&type=script&setup=true&lang=js (app.js?id=3b6365f542826af47b926162803b3ef6:60084:217)
    at __webpack_require__ (app.js?id=3b6365f542826af47b926162803b3ef6:64806:42)
./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/vue/backend/components/test.vue?vue&type=script&setup=true&lang=js @ app.js?id=3b6365f542826af47b926162803b3ef6:37396
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./resources/vue/backend/components/test.vue?vue&type=script&setup=true&lang=js @ app.js?id=3b6365f542826af47b926162803b3ef6:60116
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./resources/vue/backend/components/test.vue @ app.js?id=3b6365f542826af47b926162803b3ef6:59477
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/vue/backend/components/blog.vue?vue&type=script&setup=true&lang=js @ app.js?id=3b6365f542826af47b926162803b3ef6:37336
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./resources/vue/backend/components/blog.vue?vue&type=script&setup=true&lang=js @ app.js?id=3b6365f542826af47b926162803b3ef6:60084
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./resources/vue/backend/components/blog.vue @ app.js?id=3b6365f542826af47b926162803b3ef6:59328
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./resources/js/router.js @ app.js?id=3b6365f542826af47b926162803b3ef6:39847
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
./resources/js/app.js @ app.js?id=3b6365f542826af47b926162803b3ef6:39770
__webpack_require__ @ app.js?id=3b6365f542826af47b926162803b3ef6:64806
(anonymous) @ app.js?id=3b6365f542826af47b926162803b3ef6:64971
__webpack_require__.O @ app.js?id=3b6365f542826af47b926162803b3ef6:64843
(anonymous) @ app.js?id=3b6365f542826af47b926162803b3ef6:64973
(anonymous) @ app.js?id=3b6365f542826af47b926162803b3ef6:64975
Vodka answered 6/3, 2022 at 7:3 Comment(4)
The purpose of script setup is to skip boilerplate code. This includes 'export default'. It's a component that is expected to be exported from .vue as default. Consider explaining what you want to achieve.Meteorology
I was thinking that there might be a time when I want to export a global js function from a vue component but I understand it being a fringe case.Shimberg
Yes. In case reusable code is needed, .js file is the best place for it, not .vueMeteorology
unsure but maybe this is what you are after: vue defineExposeRectus
B
3

You can maybe use this method.

<script>
import { defineComponent } from 'vue'
import { ref, reactive, computed } from 'vue'
export default defineComponent({
  name: 'xxxComponent',
})
</script>
<script setup>
    const x = ref(5)
    // computed
    const computedVariable = computed(() => {
        return object.variable
    })
    // methods
    const updateModalCookieInitialOpenMethod = (val) => {
        cookies.updateCookieSettings(val)
        cookies.updateModalCookieInitialOpen()
    }
</script>
Burkes answered 18/5, 2022 at 15:55 Comment(2)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Foreandafter
tried, doesn't workKarol
B
3

Create new file *.d.ts like vue.d.ts or paste script below this vite-env.d.ts file (generate by vite)

declare module '*.vue' {
  import type { DefineComponent } from 'vue';
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, any>;
  export default component;
}

and then you can use script setup> without defining two script tags

Beestings answered 9/8, 2022 at 9:21 Comment(1)
Super clean, thanks!Dynamics
C
3

I didn't see this marked as answered so here's what I found dealing with same issue:

You can just use regular block alongside the block and place your export in that.

Here is the relevant documentation: https://vuejs.org/api/sfc-script-setup.html#usage-alongside-normal-script

Charlatanism answered 29/1, 2023 at 23:44 Comment(0)
B
2

The solution is to use defineOPtions I had the a similar problem where without the setup script I would done the following

<script>
import AnotherLayout from "../layouts/Another.vue"
export default {
layout: AnotherLayout
}
</script>

With the setup script, you have to use the following syntax.

<script setup>
import AnotherLayout from "../layouts/Another.vue"
defineOptions({
  layout: Another
})
</script>

See the VueJS Docs for more info https://vuejs.org/api/sfc-script-setup.html#defineoptions

Bolger answered 1/1 at 11:50 Comment(0)
C
1

'Components using script setup are closed by default' - said from their own docs.

You need to expose using defineExpose()

<script setup>

const x = 5;

defineExpose({
  x
})
</script>

https://vuejs.org/api/sfc-script-setup.html#defineexpose

Carbide answered 11/10, 2023 at 2:51 Comment(1)
Almost correct, the correct property to use is defineOptions see my answer for more information https://mcmap.net/q/738234/-how-do-you-export-default-from-inside-script-setup-in-vue-3Bolger
P
-3

Hello i just see from others and it went well for me. Just add name properties next to script setup and it will export your component.

<script setup name="Greet">
</script>

it is the same as

 export const MyComponent = {
 name: "MyComponent" // I'm not 100% set on this part}

So you can just add your code in the parent component like this.

<script setup>
 import Greet from './components/Greet.vue';
</script>

<template>
  <Greet/>
</template>
Pa answered 30/6, 2023 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.