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

Vue3学习(watchEffect,标签的ref属性,计数器,defineExpose)

一,前言

今天继续学习。

二,watchEffect

atchEffect 是 Vue 3 组合式 API 中用于响应式地执行副作用的一个函数。它与 watch 不同,不需要明确指定要监听的数据源,而是自动收集依赖。

基本用法

watchEffect 接收一个回调函数,每当回调函数中使用的任何响应式数据发生变化时,这个回调函数都会重新执行。

<template><div class="person">
<h2>当前水温:{{temp}}度</h2>
<h2>当前水位:{{sum}}cm</h2>
<button @click="changeTemp">水温加十</button>
<button @click="changesum">水位加十</button></div>
</template>
<script lang="ts" setup name="Person">
import { ref,  watch,watchEffect } from 'vue'
let sum = ref(10)
let temp = ref(10)function changeTemp(){
temp.value+=10
}
function changesum(){
sum.value+=10
}
// watch实现
// watch([temp,sum],(value)=>{
//     let [newTemp,newSum] = value
//     console.log(newTemp,newSum)
//     if(newTemp > 30||newSum > 100){
//         console.log('温度过高或水位过高')
//     }
// })
// watchEffect实现
watchEffect(()=>{if(temp.value > 30||sum.value > 100){console.log('温度过高或水位过高')}
})
</script>
<style>
.person{width: 400px;height: 400px;color:  red;
}
</style>
<template><div><p>Count: {{ count }}</p><button @click="increment">增加</button><p>Message: {{ message }}</p><input v-model="message" placeholder="输入消息"><p>Computed: {{ computedValue }}</p></div>
</template><script setup>
import { ref, computed, watchEffect } from 'vue';// 创建响应式数据
const count = ref(0);
const message = ref('');// 创建计算属性
const computedValue = computed(() => count.value * 2);// 使用 watchEffect 监听变化
watchEffect(() => {console.log('count 变化了:', count.value);
});// 监听多个响应式数据
watchEffect(() => {console.log('message 或 computedValue 变化了:', message.value, computedValue.value);
});// 执行副作用并获取停止函数
const stop = watchEffect(() => {console.log('这个副作用可以手动停止');
});// 在某个条件下停止监听
if (count.value > 10) {stop(); // 停止这个 watchEffect
}// 执行副作用,并且可以在副作用重新执行前进行清理
watchEffect((onCleanup) => {// 创建一个定时器const timer = setTimeout(() => {console.log('定时器执行,count 值为:', count.value);}, 1000);// 注册清理函数onCleanup(() => {// 清除定时器clearTimeout(timer);console.log('副作用被清理了');});
});// 增加计数器
const increment = () => {count.value++;
};
</script>
watchEffect 的特点
  1. 自动追踪依赖:无需显式指定要监听的数据,回调函数中使用的任何响应式数据都会被自动追踪。
  2. 立即执行watchEffect 会在创建时立即执行一次回调函数,然后才开始监听依赖的变化。
  3. 清理副作用:可以通过传入的 onCleanup 函数注册清理逻辑,这些逻辑会在副作用重新执行前或组件卸载前运行。
  4. 返回停止函数watchEffect 返回一个停止函数,调用它可以手动停止监听。
与 watch 的区别
  • watch 需要明确指定要监听的数据源
  • watch 默认不会立即执行,需要设置 immediate: true
  • watch 可以获取到变化前后的值
  • watch 更适合需要对比新旧值的场景
常见应用场景
  • 数据变化时发送网络请求
  • 监听路由变化执行某些操作
  • 定时任务的创建与清理
  • DOM 操作等副作用

watchEffect 是 Vue 3 中处理响应式副作用的强大工具,特别是在不需要明确追踪特定数据,而是希望对任何依赖变化做出反应的场景下非常有用。

三,标签的ref属性

Vue 3 中的 ref 属性和 ref API

在 Vue 3 中,ref 有两种不同但相关的概念:

  1. 模板 ref - 类似于 React 的 ref,用于访问 DOM 元素或组件实例
  2. 响应式引用 (ref API) - Vue 3 组合式 API 中的一个核心概念,用于创建响应式数据
模板 ref (Template Refs)

Vue 3 中的模板 ref 与 Vue 2 类似,但在组合式 API 中有不同的使用方式:

<template><div><input ref="inputRef" type="text" placeholder="输入内容"><button @click="focusInput">聚焦输入框</button></div>
</template><script setup>
import { ref, onMounted } from 'vue';// 创建一个模板 ref
const inputRef = ref(null);// 聚焦输入框的方法
const focusInput = () => {inputRef.value.focus();
};// 在组件挂载后访问 ref
onMounted(() => {console.log('输入框元素:', inputRef.value);
});
</script>
响应式引用 (ref API)

Vue 3 组合式 API 中的 ref() 函数用于创建响应式引用:

<template><div><p>计数器: {{ count }}</p><button @click="increment">增加</button></div>
</template><script setup>
import { ref } from 'vue';// 创建响应式引用
const count = ref(0);// 修改 ref 的值需要使用 .value
const increment = () => {count.value++;
};// 在模板中使用时不需要 .value
// 但在 JavaScript 中访问时需要
console.log(count.value); // 0
</script>
组件引用

在 Vue 3 中引用子组件实例:

<template><div><ChildComponent ref="childRef" /><button @click="callChildMethod">调用子组件方法</button></div>
</template><script setup>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';// 引用子组件
const childRef = ref(null);// 调用子组件方法
const callChildMethod = () => {childRef.value?.someMethod();
};onMounted(() => {console.log('子组件实例:', childRef.value);
});
</script>

关键点总结

  1. 模板 ref
    • 使用 ref="someRef" 在模板中标记元素或组件
    • 在脚本中使用 const someRef = ref(null) 创建对应的引用
    • 访问时使用 someRef.value 获取实际的 DOM 元素或组件实例
  2. 响应式引用 (ref API)
    • 使用 ref() 创建响应式数据
    • 在 JavaScript 中访问时需要使用 .value
    • 在模板中使用时自动展开,无需 .value
  3. 组合式 API 中的 ref
    • reactive 不同,ref 可以用于任何类型的值,包括基本类型
    • 当值是对象时,ref 会自动转换为 reactive

Vue 3 中的 ref 系统是组合式 API 的核心部分,正确使用它可以帮助你更好地组织代码并利用 Vue 的响应式系统。

四,计数器

计数器的基本概念

在计算机科学和编程中,计数器是一种基本的变量或组件,用于跟踪某个事件发生的次数。它本质上是一个存储数值的容器,通常会随着特定操作的执行而递增或递减。

计数器的用途

计数器在编程中有广泛的应用场景:

  1. 循环控制:在 for 循环中作为索引变量
  2. 事件计数:统计用户点击次数、页面访问量等
  3. 状态管理:跟踪应用中的特定状态变化
  4. 计时功能:结合定时器实现倒计时或正计时
  5. 游戏开发:计分系统、生命值等

Vue3计数器示例

<template><div><p>当前计数: {{ count }}</p><button @click="increment">增加</button><button @click="reset">重置</button></div>
</template><script setup>
import { ref } from 'vue';const count = ref(0);const increment = () => {count.value++;
};const reset = () => {count.value = 0;
};
</script>

五,defineExpose

基本概念

在 Vue 2 中,子组件的所有属性和方法默认都是对外暴露的,父组件可以通过 $refs 直接访问。但在 Vue 3 的 <script setup> 中,组件实例的属性和方法默认是私有的,父组件无法直接访问。这是为了更好地遵循封装原则。

defineExpose 允许我们选择性地暴露特定的属性和方法,使它们可以被父组件访问。

示例:

<template><div><ChildComponent ref="childRef" /><button @click="callChildMethod">调用子组件方法</button><p v-if="childCount">子组件计数: {{ childCount }}</p></div>
</template><script setup>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';// 创建子组件引用
const childRef = ref(null);// 获取子组件暴露的计数
const childCount = computed(() => childRef.value?.count);// 调用子组件暴露的方法
const callChildMethod = () => {childRef.value?.increment();
};onMounted(() => {console.log('子组件实例:', childRef.value);
});
</script>
<template><div><p>子组件计数器: {{ count }}</p><button @click="increment">增加</button></div>
</template><script setup>
import { ref } from 'vue';// 定义内部状态
const count = ref(0);
const privateValue = ref('这是私有值');// 定义内部方法
const increment = () => {count.value++;
};const reset = () => {count.value = 0;
};// 定义私有方法
const privateMethod = () => {console.log('这是私有方法');
};// 暴露属性和方法给父组件
defineExpose({count,    // 暴露计数器值increment // 暴露增加方法// 注意:reset 和 privateValue 没有被暴露,父组件无法访问
});
</script>
关键点说明
  1. 仅在 <script setup> 中使用defineExpose<script setup> 语法特有的宏,普通的 <script> 中不需要它。
  2. 暴露的内容
    • 可以暴露响应式状态(如 refreactive 创建的)
    • 可以暴露方法
    • 暴露的是原始引用,父组件可以直接修改
  3. 访问方式
    • 父组件通过 ref 引用子组件
    • 使用 childRef.value.propertychildRef.value.method() 访问
  4. 与 Vue 2 的区别
    • Vue 2 中所有属性和方法默认暴露
    • Vue 3 中需要显式使用 defineExpose 暴露
实际应用场景
  1. 组件库开发:只暴露组件的公共 API,隐藏内部实现细节
  2. 复杂交互:父组件需要控制子组件的特定行为
  3. 过渡动画控制:父组件需要触发子组件的动画
http://www.xdnf.cn/news/12835.html

相关文章:

  • SpringCloud学习笔记-4
  • 实验二:数码管动态显示实验
  • 建造者模式深度解析与实战应用
  • WEB3技术重要吗,还是可有可无?
  • STM32入门学习之系统时钟配置
  • K8S认证|CKS题库+答案| 7. Dockerfile 检测
  • 五、jmeter脚本参数化
  • PHP中如何定义常量以及常量和变量的主要区别
  • Spark流水线+Gravitino+Marquez数据血缘采集
  • java综合项目开发一课一得
  • 使用 Melos 高效管理 Flutter/Dart Monorepo 项目
  • 用 Melos 解决 Flutter Monorepo 的依赖冲突:一个真实案例
  • Python 包管理器 uv 介绍
  • 基于PostGIS的各地级市路网长度统计及Echarts图表可视化实践-以湖南省为例
  • 支持selenium的chrome driver更新到137.0.7151.68
  • 时序数据库IoTDB结合SeaTunnel实现高效数据同步
  • 七、Sqoop Job:简化与自动化数据迁移任务及免密执行
  • Ubuntu20.04中 Redis 的安装和配置
  • 通过Cline使用智能体
  • webpack其余配置
  • uni-app学习笔记二十七--设置底部菜单TabBar的样式
  • AUTOSAR实战教程--标准协议栈实现DoIP转DoCAN的方法
  • 12-OPENCV ROCKX项目 人脸拍照
  • 【Blender】Blender 基础:导入导出
  • 【算法】【优选算法】优先级队列
  • Hermite 插值
  • Day47
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月7日第101弹
  • 【CSS-6】深入理解CSS复合选择器:提升样式表的精确性与效率
  • 宝塔安装配置FRP