Vue3 语法进阶:从<script setup>语法糖 到 <script>传统方式的平滑过渡指南

目录

前言

一、最直观的对比:结构差异

1、语法糖写法(你熟悉的)

2、传统写法(公司项目常见)

二、响应式数据的定义

三、方法的定义与使用

四、生命周期钩子

[五、Props 与 Emits](#五、Props 与 Emits)

1、语法糖写法

2、传统写法

六、完整示例对比

1、你习惯的写法(语法糖)

2、公司项目的写法(传统)

七、快速转换口诀

八、常见错误与解决

九、总结

写在最后


前言

在 Vue3 开发中,<script setup> 语法糖凭借其简洁、直观的写法,已经成为大多数开发者的首选。但当你加入一个新团队,或者维护一个老项目时,可能会遇到使用传统 <script> 写法的代码。

面对 export default { setup() { ... } } 这样的结构,很多习惯了语法糖的同学会感到困惑:为什么还要手动 return?props 怎么定义?生命周期还能用吗?

本文将用对比学习 的方式,帮你快速掌握传统 <script> 的核心写法,让你无缝切换两种开发模式。


一、最直观的对比:结构差异

1、语法糖写法(你熟悉的)

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

const count = ref(0)
const increment = () => count.value++

// 自动暴露给模板,无需 return
</script>

2、传统写法(公司项目常见)

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

export default {
  setup() {
    const count = ref(0)
    const increment = () => count.value++
    
    // 必须手动 return,模板才能使用
    return { count, increment }
  }
}
</script>

核心差异:语法糖自动 return 所有顶层绑定,传统写法需要你手动 return。


二、响应式数据的定义

场景 <script setup> 传统 <script>
ref 定义 const num = ref(0) 同上,但要 return
reactive 定义 const state = reactive({}) 同上,但要 return
模板中使用 直接 {``{ num }} 直接 {``{ num }}

示例代码:

javascript 复制代码
<!-- 传统写法 -->
<script>
import { ref, reactive } from 'vue'

export default {
  setup() {
    const count = ref(10)
    const user = reactive({ name: 'Alice', age: 18 })
    
    return { count, user }
  }
}
</script>

<template>
  <p>{{ count }}</p>
  <p>{{ user.name }}</p>
</template>
复制代码

三、方法的定义与使用

异步方法、普通方法写法完全一致,唯一区别仍然是 return

javascript 复制代码
<script>
import { ref } from 'vue'
import { getUserInfo } from '@/api/user'

export default {
  setup() {
    const data = ref(null)
    const loading = ref(false)

    const fetchData = async () => {
      loading.value = true
      const res = await getUserInfo()
      data.value = res.data
      loading.value = false
    }

    // 方法也需要 return
    return { data, loading, fetchData }
  }
}
</script>
复制代码

四、生命周期钩子

生命周期钩子的用法完全一致 ,因为都是在 setup() 函数内部调用。

javascript 复制代码
<script>
import { onMounted, onUnmounted } from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('组件已挂载')
    })

    onUnmounted(() => {
      console.log('组件即将卸载')
    })
    
    return {}
  }
}
</script>
复制代码

五、Props 与 Emits

这是最容易混淆的地方,对比来看更清晰。

1、语法糖写法

javascript 复制代码
<script setup>
const props = defineProps(['title', 'id'])
const emit = defineEmits(['update', 'close'])

emit('update', 'new value')
</script>

2、传统写法

javascript 复制代码
<script>
export default {
  props: ['title', 'id'],
  emits: ['update', 'close'],
  setup(props, { emit }) {
    emit('update', 'new value')
    
    return {}
  }
}
</script>

注意props 是响应式对象,不要解构它,否则会失去响应性。


六、完整示例对比

1、你习惯的写法(语法糖)

javascript 复制代码
<script setup>
import { ref, onMounted } from 'vue'
import { getArticleList } from '@/api/article'

const articles = ref([])
const loading = ref(false)

const loadArticles = async () => {
  loading.value = true
  const res = await getArticleList()
  articles.value = res.data
  loading.value = false
}

onMounted(() => {
  loadArticles()
})
</script>
复制代码

2、公司项目的写法(传统)

javascript 复制代码
<script>
import { ref, onMounted } from 'vue'
import { getArticleList } from '@/api/article'

export default {
  setup() {
    const articles = ref([])
    const loading = ref(false)

    const loadArticles = async () => {
      loading.value = true
      const res = await getArticleList()
      articles.value = res.data
      loading.value = false
    }

    onMounted(() => {
      loadArticles()
    })

    // 关键:把所有要在模板中用的变量和函数都 return
    return {
      articles,
      loading,
      loadArticles
    }
  }
}
</script>

七、快速转换口诀

  1. 所有代码放进 setup() { } ,用到的变量/函数必须 return出去

  2. props 单独写在 props 选项中

  3. emits 单独写在 emits 选项中

  4. 生命周期钩子用法不变


八、常见错误与解决

错误现象 原因 解决方案
模板中显示 undefined 变量没 return 添加到 return 对象中
props 不更新 解构了 props 直接使用 props.xxx
emit 不生效 没声明 emits 添加 emits: ['事件名']
this 报错 想用 this.xxx 直接用变量名,没有 this

九、总结

特性 <script setup> 传统 <script>
代码量 更少 稍多(需要 return)
学习曲线 平缓 稍陡
组件实例 无 this 无 this(setup 中也没有)
适用场景 新项目、组件库 老项目、复杂配置

核心思想 :两种写法本质是一样的,传统写法只是把语法糖"自动做的事"变成了"手动做"。理解 setup() 函数 + return 这个机制,你就能轻松看懂任何传统写法的 Vue 组件。


写在最后

如果你刚接触传统写法,不用慌。先把 return { } 里的内容当作"模板能用的东西清单",看不懂的代码就找这个清单。多写几次就能完全掌握。

希望这篇文章能帮助你快速适应公司项目的代码风格。如果有任何疑问,欢迎在评论区留言交流!

相关推荐
IT_陈寒36 分钟前
Redis缓存击穿把我整不会了,原来还有这手操作
前端·人工智能·后端
idcu1 小时前
深入 Lyt.js 组件系统:L2 渲染引擎层的核心
前端·typescript
这是程序猿1 小时前
Spring Boot自动配置详解
java·大数据·前端
文心快码BaiduComate1 小时前
干货|Comate Harness Engineering工程实践指南
前端·后端·程序员
还有多久拿退休金1 小时前
一张栈的图,治好你面试答不出 script 阻塞的病
前端·javascript
光辉GuangHui1 小时前
Agent Skill 也需要测试:如何搭建 Skill 评估框架
前端·后端·llm
To_OC2 小时前
我终于搞懂 Claude Code 核心逻辑!90%的人都用错了模式
前端·ai编程
蓝宝石的傻话2 小时前
Headless浏览器的隐形陷阱:为什么你的AI自动化工具抓不到页面早期错误?
前端
zithern_juejin2 小时前
原型与原型链
javascript
irving同学462382 小时前
Node 后端实战:JWT 认证与生产级错误处理
前端·后端