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 { } 里的内容当作"模板能用的东西清单",看不懂的代码就找这个清单。多写几次就能完全掌握。

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

相关推荐
hunteritself34 分钟前
夯爆了!Qoder 狂肝 2 小时,293 个测试全绿,Credits 一分没扣
前端·人工智能·chrome·深度学习·机器学习
Hilaku43 分钟前
为什么前端应该主动去学数据库?
前端·javascript·程序员
朱 欢 庆1 小时前
el-table 表格组件二次封装
javascript·vue.js·elementui
涛涛ing1 小时前
2026年,你终于可以在 `<textarea>` 里定位任意字符了
前端
三8441 小时前
TLS + Web API 安全 · 05 · JWT 与 OAuth2 攻防
前端·安全
zhongwei2282 小时前
vba将一个文件夹的内容复制到另外一个文件夹的函数,若存在则是否覆盖的参数。复制前检查源文件夹是否存在。若目标文件夹不存在,则新建
前端·vba
+VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue外卖点餐系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
FYKJ_20102 小时前
springboot刑事案件管理系统03047-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
怕浪猫3 小时前
分享一个做视频的skill,这条白板视频,每一笔都是代码画的
前端·javascript·面试
aa小小3 小时前
大屏自适应缩放方案
前端·数据可视化