理解script setup语法糖,defineProps使用不会再报这个错啦(vue3查漏补缺系列)

791 阅读1分钟

前两天在撸代码的时候,在script setup里面定义一个prop,这个prop默认值是一个有很多属性的对象,我定义了一个对象变量并在defineProps中引入,然后就报错了

//精简代码
<script setup>
const obj = {
    name:'xxx'
}
defineProps({
    nameType:{
        type:Object,d
        default:obj
    }
})
</script>

image.png 看了下vue关于script setup的文档,理解了下setup语法糖的相关使用,这个问题也就瞬间理解了

关于setup语法糖

<script setup>是vue3组合式Api的编译时语法糖。相比普通的<script>这个语法糖具有更多的优势

普通 script

<script>
export default {
   setup(props){
       const wordArr = [1,2,3]
       const sayHello = ()=>{
           console.log('hello')
       }
       return {
           sayHello,
           wordArr
       }
   }
}
</script>

<script setup> 语法糖

<script setup>
const wordArr = [1,2,3]
const sayHello = ()=>{
   console.log('hello')
}
</script>

上面代码可以很明显的看出来,<script setup>语法糖使用后,代码内容更少,更简洁明了, 实现的功能是一样的,script setup里面的代码会被编译成组件setup()函数的内容,定义在里面的属性、方法会自动暴露出来给模版使用,不需要手动return出来

script setup中的编译器宏

vue3 script setup中,defineProps和defineEmits可以直接使用,他们会随着script setup的处理过程一起被编译掉

值得注意的是,传入到defineProps和defineEmits的选项会从setup中提升到模块的作用域。所以,传入的选项不能引用在setup作用域中声明的局部变量。这个是什么意思呢,什么场景会出现? 回到文章开头出现的代码【图1】

<script setup>
const obj = {
    name:'xxx'
}
defineProps({
    nameType:{
        type:Object,d
        default:obj
    }
})
</script>

义在defineProps里的变量,最终会提升到大的模块下,而这个大的模块里面却引用了setup()函数局部作用域里的变量,所以会报错,上面的代码等同于下图

//普通script模块
<script>
//变量提升到模块下面,props引用了setup里面定义的变量
props:{
    obj:obj
},
setup(){
    //script setup模块的内容会编译到这里
    const obj = {
        name:'lr'
    }
    return {
        obj
    }
}
</script>

正常场景

<script setup>
import {obj} from "@/utils/utils"
defineProps({
    nameType:{
        type:Object,d
        default:obj
    }
})
</script>

同样是引入变量,但是这种情况不会报错,通过import 导入的信息,变量会提升到模块作用域下面,而defineProps提升到的作用域也是模块下,引用同一个作用域下面的变量,不会报错。上面的代码等同于:

<script>
import {obj} from "@/utils/utils"
export default {
    props:{
        nameType:{
            type:Object,d
            default:obj
        }
    }
}
</script>

所以在使用script setup时,要注意变量提升的问题,注意区分模块作用域与setup局部作用域