Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/prop-defineprops-scope-limitation.md
1---2title: defineProps Cannot Access Variables from script setup3impact: MEDIUM4impactDescription: Variables declared in script setup are not accessible inside defineProps arguments5type: gotcha6tags: [vue3, props, script-setup, defineProps, compiler]7---89# defineProps Cannot Access Variables from script setup1011**Impact: MEDIUM** - Code inside the `defineProps()` argument cannot access other variables declared in `<script setup>`. The entire expression is moved to an outer function scope when compiled, making local variables inaccessible.1213This commonly surprises developers trying to use imported constants or computed validation logic.1415## Task Checklist1617- [ ] Define validation constants outside `<script setup>` or in a separate file18- [ ] Import constants before using them in defineProps19- [ ] Use external type definitions for TypeScript props20- [ ] For dynamic validation, use watchers instead of prop validators2122**Incorrect:**23```vue24<script setup>25import { ref } from 'vue'2627// These are in <script setup> scope28const VALID_SIZES = ['sm', 'md', 'lg']29const maxLength = ref(100)3031defineProps({32size: {33type: String,34// WRONG: VALID_SIZES is not accessible here35validator: (v) => VALID_SIZES.includes(v) // ReferenceError!36},37name: {38type: String,39// WRONG: Cannot access refs40validator: (v) => v.length <= maxLength.value // ReferenceError!41}42})43</script>44```4546**Correct:**47```vue48<script>49// Define constants in regular <script> block (module scope)50export const VALID_SIZES = ['sm', 'md', 'lg']51export const MAX_LENGTH = 10052</script>5354<script setup>55// Now accessible in defineProps56defineProps({57size: {58type: String,59validator: (v) => VALID_SIZES.includes(v) // Works!60},61name: {62type: String,63validator: (v) => v.length <= MAX_LENGTH // Works!64}65})66</script>67```6869## Pattern: Import from External File7071```javascript72// validation.js73export const VALID_SIZES = ['sm', 'md', 'lg']74export const VALID_COLORS = ['red', 'blue', 'green']75export const sizeValidator = (v) => VALID_SIZES.includes(v)76```7778```vue79<script setup>80import { VALID_SIZES, VALID_COLORS, sizeValidator } from './validation'8182// Imported values ARE accessible83defineProps({84size: {85type: String,86validator: sizeValidator87},88color: {89type: String,90validator: (v) => VALID_COLORS.includes(v)91}92})93</script>94```9596## Pattern: Dual Script Blocks9798```vue99<script>100// Regular script for module-level declarations101const options = {102themes: ['light', 'dark', 'system'],103defaults: {104theme: 'light',105size: 'md'106}107}108</script>109110<script setup>111// options is accessible here112const props = defineProps({113theme: {114type: String,115default: options.defaults.theme,116validator: (v) => options.themes.includes(v)117}118})119</script>120```121122## TypeScript: External Type Definitions123124```typescript125// types.ts126export interface UserProps {127name: string128email: string129age?: number130}131```132133```vue134<script setup lang="ts">135import type { UserProps } from './types'136137// Type imports work fine138const props = defineProps<UserProps>()139</script>140```141142## Why This Happens143144Vue's compiler transforms `<script setup>` code. The `defineProps()` call is extracted and moved to component options at compile time, before the setup function runs:145146```javascript147// Your code:148const MY_CONST = 'value'149defineProps({ prop: { default: MY_CONST } })150151// Compiled (simplified):152export default {153props: { prop: { default: MY_CONST } }, // MY_CONST doesn't exist here!154setup() {155const MY_CONST = 'value' // Defined too late156}157}158```159160## Reference161- [Vue.js Script Setup - defineProps](https://vuejs.org/api/sfc-script-setup.html#defineprops-defineemits)162