vue3中setup语法糖和setup函数的区别?

初步打印

曾几何时,我也以为这两种写法是一模一样的。直接深究到编译层面才会发现区别,先列出两种写法:

js 复制代码
// 组件一:setup函数方式
<template>
    <div>
        <h1>{{ msg }}</h1>
        <button @click="increase">count:{{count}}</button>
    </div>
</template>

<script>
import { ref } from 'vue';

export default {
    setup(){
        const msg = 'Foo Setup'
        const count = ref(0)
        function increase(){
            count.value++
        }
        
        return {
            msg,
            count,
            increase
        }
    }
}
</script>
js 复制代码
// 组件二:setup语法糖方式
<template>
    <div>
        <h1>{{ msg }}</h1>
        <button @click="increase">count:{{count}}</button>
    </div>
</template>

<script setup>
import { ref } from 'vue';

const msg = 'Foo Script Setup'
const count = ref(0)
function increase(){
    count.value++
}
</script>

当在父组件中引用两个组件并通过ref分别把两个组件的实例打印出来时,会看到两个Proxy,但是会发现在setup函数 实现的组件中可以拿到定义的msg、count、increase,而setup语法糖 实现的组件中却是空的

对比编译结果

在vite打包的项目中,可以用这个插件vite-plugin-inspect 配置到vite.config.js中重新启动工程就会看到有一个新的链接:http://localhost:5173/__inspect/可以查看编译结果,它会展示当前程序目前用到的所有组件。分别点入两个组件中查看:

左边展示的是原始代码,右边展示的是编译结果。像template在编译结果中是不存在的,它会被转化成render函数、h1变成了虚拟节点h1。主要区别在script的部分:在setup语法糖组件中,多了一个expose()

expose函数

作用:暴露指定的实例成员

像在上方的打印结果处,看到setup函数实现的组件 打印的实例中有msg、count、increase这些成员被暴露出来。那暴露出成员好不好呢,其实它给了使用组件者一个机会通过实例内的成员去主动改动这些信息 ,一旦真的去改动了 其实就打破了单项数据流

其实上面描述的就是vue2的时候一个很明显的问题,因此在vue3中它引入了expose函数来解决这个问题。可以用它来控制我们想暴露的成员。

setup函数中如何暴露成员

js 复制代码
<script>
import { ref } from 'vue';

export default {
    setup(_,{ expose }){ //第二个参数中有expose函数
        const msg = 'Foo Setup'
        const count = ref(0)
        function increase(){
            count.value++
        }
        
        // expose()则什么都不暴露,可以按需暴露
        expose({
            msg
        })
        
        return {
            msg,
            count,
            increase
        }
    }
}
</script>

setup语法糖中如何暴露成员

js 复制代码
<script setup>
import { ref } from 'vue';

const msg = 'Foo Script Setup'
const count = ref(0)
function increase(){
    count.value++
}

// defineExpose 它是一个宏
// 宏:仅存在于编译时态
defineExpose({
    msg
})
</script>
相关推荐
xlp666hub2 分钟前
C进阶之内存对齐,硬件总线和高并发伪共享的底层原理
面试·代码规范
栀秋6667 分钟前
深入浅出链表操作:从Dummy节点到快慢指针的实战精要
前端·javascript·算法
狗哥哥23 分钟前
Vue 3 动态菜单渲染优化实战:从白屏到“零延迟”体验
前端·vue.js
青青很轻_25 分钟前
Vue自定义拖拽指令架构解析:从零到一实现元素自由拖拽
前端·javascript·vue.js
xhxxx25 分钟前
从被追问到被点赞:我靠“哨兵+快慢指针”展示了面试官真正想看的代码思维
javascript·算法·面试
树下水月32 分钟前
纯HTML 调用摄像头 获取拍照后的图片的base64
前端·javascript·html
蜗牛攻城狮36 分钟前
Vue 中 `scoped` 样式的实现原理详解
前端·javascript·vue.js
yaoh.wang38 分钟前
力扣(LeetCode) 14: 最长公共前缀 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
豆苗学前端41 分钟前
前端工程化终极指南(Webpack + Gulp + Vite + 实战项目)
前端·javascript
比老马还六42 分钟前
Bipes项目二次开发/海龟编程(六)
前端·javascript