当前位置: 首页 > article >正文

Vue3 完整学习笔记 - 第二部分

Vue3 完整学习笔记 - 第二部分

2. Vue3 响应式系统深入

2.1 ref 深入理解

重点掌握:

  • ref 的工作原理
  • 基本类型和对象类型的处理差异
  • template 中的自动解包

核心示例:

<template>
  <div>
    <!-- 模板中自动解包,无需 .value -->
    <h1>{{ message }}</h1>
    <p>Count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

// 基本类型的响应式
const count = ref(0)
const message = ref('Hello')

// 在 JS 中需要 .value
const increment = () => {
  count.value++
  message.value = `Count is ${count.value}`
}

// 对象类型的响应式
const user = ref({
  name: 'John',
  age: 30
})

// 修改对象属性仍需要 .value
function updateUser() {
  user.value.age++
  // 或者整个替换对象
  user.value = { name: 'Jane', age: 25 }
}
</script>

2.2 reactive 深入理解

重点掌握:

  • reactive 的使用场景
  • 响应式对象的限制
  • 解构和展开的处理

示例代码:

<template>
  <div>
    <h2>{{ state.user.name }}</h2>
    <p>Age: {{ state.user.age }}</p>
    <button @click="updateState">Update State</button>
  </div>
</template>

<script setup>
import { reactive, toRefs } from 'vue'

// 创建响应式对象
const state = reactive({
  user: {
    name: 'John',
    age: 30
  },
  settings: {
    theme: 'dark',
    notification: true
  }
})

// ❌ 解构会失去响应性
const { user } = state

// ✅ 使用 toRefs 保持响应性
const { settings } = toRefs(state)

const updateState = () => {
  // 直接修改嵌套属性
  state.user.age++
  state.settings.theme = 'light'
}
</script>

2.3 toRefs 和 toRef 的使用

重点掌握:

  • toRefs 的使用场景
  • toRef 单个属性的处理
  • 解构响应式对象的正确方式

示例代码:

<template>
  <div>
    <h2>{{ name }}</h2>
    <p>Age: {{ age }}</p>
    <button @click="increment">Age +1</button>
  </div>
</template>

<script setup>
import { reactive, toRefs, toRef } from 'vue'

const state = reactive({
  name: 'John',
  age: 30
})

// 转换整个对象
const { name, age } = toRefs(state)

// 或者单独转换一个属性
const ageRef = toRef(state, 'age')

const increment = () => {
  // 都是响应式的
  age.value++
  // 或者
  ageRef.value++
}

// 使用场景:组件属性解构
const props = defineProps(['title'])
const title = toRef(props, 'title')
</script>

2.4 computed 计算属性

重点掌握:

  • 计算属性的基本使用
  • getter 和 setter
  • 计算属性缓存特性

示例代码:

<template>
  <div>
    <input v-model="firstName" />
    <input v-model="lastName" />
    <p>Full name: {{ fullName }}</p>
    <!-- 使用可写计算属性 -->
    <input v-model="fullName" />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

// 只读计算属性
const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`
})

// 可写计算属性
const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`
  },
  set(newValue) {
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})

// 带缓存的计算属性
const expensiveComputed = computed(() => {
  console.log('computing...')
  return someExpensiveOperation(firstName.value)
})
</script>

2.5 watch 侦听器基础

重点掌握:

  • 基本数据类型的侦听
  • 对象的侦听
  • 多个数据源的侦听

示例代码:

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

const count = ref(0)
const message = ref('Hello')
const user = ref({ name: 'John', age: 30 })

// 侦听单个ref
watch(count, (newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`)
})

// 侦听多个数据源
watch([count, message], ([newCount, newMessage], [oldCount, oldMessage]) => {
  console.log('Values changed:', { newCount, newMessage, oldCount, oldMessage })
})

// 侦听对象
watch(user, (newUser, oldUser) => {
  console.log('User changed:', newUser, oldUser)
}, { deep: true }) // 深度侦听

// 立即执行
watch(count, (newValue) => {
  console.log(`Initial count: ${newValue}`)
}, { immediate: true })
</script>

2.6 watchEffect 的使用

重点掌握:

  • watchEffect 的自动依赖追踪
  • 停止侦听
  • 清理副作用

示例代码:

<script setup>
import { ref, watchEffect } from 'vue'

const count = ref(0)
const message = ref('Hello')

// 自动收集依赖
const stop = watchEffect(() => {
  console.log(`Count is ${count.value}`)
  console.log(`Message is ${message.value}`)
})

// 带清理的副作用
watchEffect((onCleanup) => {
  const timer = setInterval(() => {
    count.value++
  }, 1000)
  
  // 清理函数
  onCleanup(() => clearInterval(timer))
})

// 停止侦听
setTimeout(() => {
  stop()
}, 5000)

// 异步请求示例
watchEffect(async () => {
  const response = await fetch(`/api/user/${count.value}`)
  const data = await response.json()
  message.value = data.name
})
</script>

http://www.kler.cn/a/533219.html

相关文章:

  • 深入理解Node.js_架构与最佳实践
  • 使用SpringBoot发送邮件|解决了部署时连接超时的bug|网易163|2025
  • OpenGL学习笔记(五):Textures 纹理
  • 自研有限元软件与ANSYS精度对比-Bar3D2Node三维杆单元模型-央视大裤衩实例
  • 【实践案例】基于大语言模型的海龟汤游戏
  • 线性调整器——耗能型调整器
  • Vue.js组件开发-实现广告图片浮动随屏幕滚动
  • LeetCode:115.不同的子序列
  • C++实现有限元三维杆单元计算 Bar3D2Node类(纯自研 非套壳)
  • 在 Ubuntu 22.04 上运行 Filebeat 7.10.2
  • vue2语法速通
  • 猫眼Java开发面试题及参考答案(上)
  • Cassandra的下载与安装
  • Java的String与StringBuilder例题
  • 如何学习大数据治理:轻松上手指南
  • 大语言模型概述
  • Redis的通用命令
  • 98,【6】 buuctf web [ISITDTU 2019]EasyPHP
  • 计算机网络安全与运维的关键 —— 常用端口全解析
  • 【JAVA】Netty使用教程
  • Java 报错:找不到或无法加载主类
  • Maven 项目的基本结构
  • 我们来学人工智能 -- 感悟DeepSeek
  • Llama最新开源大模型Llama3.1
  • Java之线程篇六
  • 关于论文复现的环境配置以及其他的坑点