ここでいうdefineXXXX関数は以下のような関数(?)です。
- defineProps
- defineModel
初っ端からの結論
結論を言いましょう。defineXXXXの関数はマクロなのでデリケートだからです!
マクロとは
このマクロは、.vueファイルとかからコンパイル(Vite等)するときにdefinePropsから別形態に変化します。
Vue SFC Playgroundで見ると分かるでしょう。
JSタブにするとコンパイルされたファイルが見れます。
App.vue
<script setup>
import {ref} from "vue"
const a = defineProps()
const msg = ref("hello!")
</script>
<template>
<h2>{{msg}}</h2>
</template>
JS
/* Analyzed bindings: {
"ref": "setup-const",
"a": "setup-reactive-const",
"msg": "setup-ref"
} */
import {ref} from "vue"
const __sfc__ = {
__name: 'App',
setup(__props, { expose: __expose }) {
__expose();
const a = __props
const msg = ref("hello!")
const __returned__ = { a, msg, ref }
Object.defineProperty(__returned__, '__isScriptSetup', { enumerable: false, value: true })
return __returned__
}
};
//~以下略~
App.vueとJSを比較すると、const msg = ref("hello!")
はそのままなのに対し、const a = defineProps()
はconst a = __props
になっています!
これがマクロというものです。
バグる原因
ではこうしてみましょう(自分が引っ掛かった実例の再現)
App.vue
<script setup>
import {ref} from "vue"
const a = defineProps(["data"]).data
const msg = ref("hello!")
</script>
<template>
<h2>{{msg}}</h2>
</template>
defineProps
の後に付け足すと...
JS(抜粋)
const a = defineProps(["data"]).data
__props
に変換されなくなってしまった!
このように、これに何か付け足されたりするとうまくコンパイルされずにエラーになってしまいます。
結論
- defineXXXXはマクロと言って関数が変数に変換される
- defineXXXXの関数は本当はない
- コンパイラは繊細なので、defineXXXXに何か付け足されるとうまくコンパイルできなくなって正常に動作しなくなる
これはよく引っ掛かります。ぜひご参考に。