1. 浏览器调试技巧

1.1 调试工具使用

  • 语雀文档参考Vue3 官方调试文档

  • 语雀文档参考Vue3 官方调试文档
    链接作用:该链接指向 Vue.js 官方文档的「工具」章节,专门介绍 Vue DevTools 浏览器扩展的使用。点击后可以:

    1. 了解如何安装 Vue DevTools 浏览器扩展
    2. 学习使用 DevTools 检查组件树、状态、事件
    3. 掌握性能分析和时间旅行调试等高级功能
    4. 查看官方推荐的调试最佳实践
  • Watch 监视功能:在浏览器开发者工具的右侧 Watch 面板中,可以手动添加要监视的变量,实时查看其值的变化。这在调试 propsref 时特别有用。

浏览器 Watch 功能n/img_convert/05f0455cb7d4c0404fbabaec71bff1fd.png)

2. Vue3 SFC (.vue) 单文件三大模块

2.1 <template> 模板(HTML 结构层)

作用:编写页面的 DOM 结构。

包含内容

  • HTML 标签
  • Vue 指令(v-ifv-forv-bind@click 等)
  • 插值表达式 {{ 变量 }}

特点

  • Vue 编译器会将模板编译成 render() 渲染函数,最终生成虚拟 DOM 并渲染为真实页面
  • 不能直接编写 JavaScript 逻辑,只能通过绑定关联 <script> 中定义的数据和方法
  • Vue3 支持 <template> 根节点多标签(无需外层包裹 div

2.2 <script> 脚本(逻辑、数据层)

作用:定义页面的所有业务逻辑、数据、方法、生命周期、props、导入组件等。

两种写法

  1. Options API:传统的配置式写法
  2. Composition API(Setup 语法糖):组合式写法

包含内容

  • 定义响应式数据(ref/reactive
  • 定义函数方法
  • 接收父组件传值 props
  • 定义组件自定义事件 emits
  • 生命周期钩子(onMountedonUpdated 等)
  • 引入子组件和第三方工具

注意:在 setup 语法糖下,代码会在组件创建阶段优先执行。

2.3 <style> 样式(CSS 层)

作用:编写当前组件的样式。

三种模式

  1. 普通样式:全局样式,不加 scoped 会污染全页面
  2. <style scoped>:样式只作用于当前组件 DOM(通过 data-v 哈希属性隔离)
  3. <style lang="scss">:可使用 Sass/Less 等 CSS 预处理器

特点:只负责样式,不参与组件逻辑与渲染。

3. .vue 文件编译与执行顺序

打包编译顺序

<script><template><style>

浏览器运行渲染顺序

<script> 先执行 → 生成 render 函数 → <template> 渲染 DOM → <style> 生效

完整分步流程

第一步:优先解析执行 <script>

  • 代码从上到下执行
  • 导入依赖 → 执行 setup / 选项配置 → 创建响应式数据、声明方法
  • 组件实例创建、数据初始化全部在这一步完成

第二步:编译 <template>

  • 模板不会原样留在页面
  • Vue 编译器把 template 编译成 render 渲染函数
  • render 函数内部使用 <script> 里定义的数据生成 VNode(虚拟 DOM)

第三步:挂载渲染 DOM

  • 执行 render() 函数
  • 虚拟 DOM 转为真实 DOM,页面 HTML 渲染出来

第四步:加载 <style>

  • CSS 样式载入页面
  • DOM 应用对应样式正确示例

错误示例cn/img_convert/6755a962e6cab421fb5693e5c74b22f2.png)

错误示例

核心原理

  • 模板里 ref="变量名" → 必须在 <script setup> 顶层作用域存在同名 ref 变量
  • 组件挂载 onMounted 后,Vue 自动把真实 DOM 对象赋值给 oracleDiv.value

错误分析

错误原因ref() 创建变量是在点击函数运行时才创建,但 DOM 在 onMounted(页面初始化时)就已经渲染完毕。

执行流程分析

  1. script 运行阶段:只定义 getDivContent 函数,let oracleDiv = ref() 这行代码完全没运行,变量不存在
  2. DOM 挂载阶段:Vue 找全局名叫 oracleDivref 变量,找不到!无法赋值 DOM
  3. 用户点击后:才临时在函数局部创建 oracleDiv,此时挂载早已结束,Vue 不会回头再赋值 → value 永远为 null

5. Vue3 两种代码写法

5.1 Options API(选项式 API)

结构:固定配置选项

<script>
export default {
  // 数据
  data() {
    return {
      num: 0,
      user: { name: '小李', age: 18 }
    }
  },
  
  // 方法
  methods: {
    add() {
      this.num++
    }
  },
  
  // 生命周期
  mounted() {
    console.log('页面挂载完毕')
  },
  
  // watch 监听
  watch: {
    num(newV) {
      console.log('num变了', newV)
    },
    user: {
      handler() {
        console.log('user变化')
      },
      deep: true
    }
  }
}
</script>

注意事项

  1. 通过 this 访问数据和方法:this.num / this.user
  2. data() 必须返回对象
export default {
  data() {
    // data 必须 return 对象,页面才能拿到数据
    return {
      count: 0
    }
  }
}
  1. 老式组合式 setup() 需要 return
export default {
  setup() {
    const count = ref(0)
    // 不在 script setup 语法糖里,想在模板中使用 → 必须 return
    return { count }
  }
}

5.2 组合式 API(Composition API)

<script setup>
import { ref, reactive, watch, onMounted } from 'vue'

const num = ref(0)
const user = reactive({ name: '小李', age: 18 })
const add = () => num.value++

watch(num, () => {})
onMounted(() => {})
</script>

特点

  • 相关业务代码写在一起,没有 this
  • 便于代码抽离封装成 hooks,大项目维护方便

6. watch 监听器详解

6.1 基本特性

  • 原生 watch 本身不分「增、删、改、加、减」,只要值变化就触发回调

6.2 监听对象、数组(引用值)

不写 deep: true:内部属性改动不会触发 watch

deep: true:对象任意层级改动、新增 key、删除 key、数组 push/pop,全部统一触发回调

const user = reactive({ name: '小明', age: 18 })

// deep:true 开启深度监听
watch(user, (newVal, oldVal) => {
  console.log('对象变化了')
}, { deep: true })

user.age = 20    // 修改属性 → 触发
user.sex = '男'  // 新增属性 → 触发
delete user.name // 删除属性 → 触发

6.3 监视 reactive 定义的引用数据类型

基础用法:直接监听整个 reactive 对象,不用手动 deep: true

const obj = reactive({ name: '张三', info: { age: 18 } })

// 监听整个 reactive 对象,默认自动开启 deep
watch(obj, (newVal, oldVal) => {
  // newVal === oldVal → true!同一个 Proxy 地址
  console.log(newVal === oldVal)
})

// 改一级属性
obj.name = '李四'
// 改深层属性
obj.info.age = 20

只监听对象里某个属性(函数写法)

watch(() => obj.name, (newV, oldV) => {
  // new ≠ old,普通值,地址不一样
})
obj.name = '李四'

7. 历史来源小科普

语法糖这个词是 1960 年代 Lisp 语言发明者提出,沿用至今Vue3 核心知识点 箭头函数 () => {} 是普通 function 的语法糖

  • <script setup> 遵循这个命名惯例,写法简化、逻辑不变 → 语法糖

8. 核心知识点图解

Vue3 核心知识点

8.1 RefImpl 和 Proxy

Proxy**:管理对象内部细节改动(reactive 全靠它)

  • RefImplref 专属外壳,解决基本类型无法被 Proxy 代理的短板,.value 靠它实现响应式
  • 控制台显示:浏览器控制台显示 RefImpl,就是提醒你:该变量是 ref 包装对象,不能直接操作原始数据,JS 取值必须加 .value

8.2 :v-bind: 简写

写法 含义 传递内容
personList="persons"
(无冒号)
纯字符串字面量 子组件拿到字符串 "persons"
:personList="persons"
(带冒号)
JS 表达式 把父组件 persons
**变量(整个响应式数组)**传给子组件 personList

8.3 父传子 ref 数据传递注意事项

ref 数据通过 props 传递时会自动剥除 RefImpl,子组件拿到的是原生 Proxy 数据,所以 props 有解构陷阱:

// ❌ 错误解构,丢失响应式
const { personList } = defineProps<{ personList: Item[] }>()

// ✅ 正确:用 toRefs 保持响应式
const props = defineProps<{ personList: Item[] }>()
const { personList } = toRefs(props)

9. {{ name }} 插值表达式(模板语法)

<!-- Child.vue -->
{{ name }}

作用:把 name 变量里的数据显示在网页上。

特性

  • 里面可以写简单运算:{{ name + '666' }}zhangsan666
  • 只有模板能用 {{}}<script> 里必须写 props.name

更多推荐