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

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

相关推荐
To_OC4 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
腻害兔4 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
不好听6134 小时前
从一行 JSX 到屏幕像素:前端开发者必须懂的浏览器渲染管线
前端
恒拓高科WorkPlus4 小时前
企业级内网即时通讯建设模型:BeeWorks内网IM四层架构
前端
前端小李子5 小时前
前端环境变量裸奔?我用 EnvShield 给它穿了件防弹衣
前端
youtootech5 小时前
HarmonyOS《柚兔学伴》项目实战25-我的页面、Web 嵌入与项目总结
前端·华为·harmonyos
小林ixn5 小时前
从零到一理解 React 父子组件通信:手写一个 Todo 应用带你彻底搞懂单向数据流
前端·javascript·react.js
醇氧7 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
窝子面8 小时前
手搓最简前后端协作-node
javascript·数据库