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_陈寒10 小时前
Vue的响应式更新把我坑惨了,原来是这个问题
前端·人工智能·后端
gyx_这个杀手不太冷静10 小时前
大人工智能时代下前端界面全新开发模式的思考(一)
前端·人工智能·ai编程
冰暮流星10 小时前
javascript之dom访问css
开发语言·javascript·css
Java小卷10 小时前
FormKit源码二开 - 校验功能扩展
前端·低代码
xiaotao13110 小时前
第二十一章:CI/CD 最佳实践
前端·ci/cd·vite·前端打包
千码君201610 小时前
kotlin:jetpack compose 生成动态可控的动画
vue.js·elementui·kotlin
C澒10 小时前
IntelliPro 企业级产研协作平台:数据可视化全流程拆解
前端·数据可视化
蓝黑202010 小时前
Vue组件通信之slot
前端·javascript·vue
布局呆星11 小时前
Vue3+TS 笔记:Props 与 Emits 的正确打开方式
javascript·vue.js·笔记
小李子呢021111 小时前
前端八股7--- Vue 状态管理工具(vuex和pinia)
前端·javascript·vue.js