组合式API【Vue3】

news2024/12/25 15:11:05

Vue3组合式API体验

通过一个 Counter(自增)案例 体验Vue3新引入的组合式API
Vue2的代码:

<template>
	<button @click="addCount">{{count}}</button>
</template>
<script>
export default {
	data(){
		return {
			count: 0
			}
		},
	methods: {
		addCount(){
			this.count++
		}
	}
}
</script>

Vue3组合式API实现的代码:

<template>
	<button @click="addCount">{{count}}</button>
</template>
<script setup>
	import {ref} from 'vue'
	const count = ref(0)
	const addCount = () => count.value++
</script>

Vue3更多的优势

  • 更容易维护
    • 组合式API
    • 更好的TypeScript支持
  • 更快的速度
    • 重写diff算法
    • 模板编译优化
    • 更高效的组件初始化
  • 更小的体积
    • 良好的TreeShaking
    • 按需引入
  • 更优的数据响应式
    • Proxy

认识create-vue

create-vue是Vue官方新的脚手架工具,底层切换到了vite(下一代前端工具链),为开发提供极速响应

  1. 前提环境条件
    已安装16.0或更高版本的Node.js
  2. 创建一个Vue应用
    • npm init vue@latest
      这一指令将会安装并执行 create-vue
      在这里插入图片描述

熟悉项目目录和关键文件

在这里插入图片描述
关键文件:

  1. vite.config.js - 项目的配置文件 基于vite的配置
  2. package.json - 项目包文件 核心依赖项变成了Vue3.x 和 vite
  3. main.js - 入口文件 createApp函数创建应用实例
  4. app.vue - 根组件 SFC单文件组件 script - template - style
    变化一:脚本script和模板template顺序调整
    变化二:模板template不再要求唯一根元素
    变化三:脚本script添加setup标识支持组合式API
  5. index.html - 单页入口 提供id为app的挂载点

组合式API - setup选项

setup选项的写法和执行

<script>
export default {
	setup(){
	
	},
	beforeCreate(){
	
	},
}
</script>

在这里插入图片描述

< script setup >语法糖

  • 原始复杂写法
<script>
export default {
	setup(){
		//数据
		const message = 'this is message'
		//函数
		const logMessage = () => {
			console.log(message)
		}
		return {
			message,
			logMessage
		}
	}
}
</script>
  • 语法糖写法
<script setup>
//数据
const message = 'this is message'
//函数
const logMessage = () => {
	console.log(message)
}
</script>

总结:

  1. setup选项的执行机制?
    beforeCreate钩子之前 自动执行
  2. setup写代码的特点是什么?
    定义数据 + 函数 然后以对象方式return
  3. < script setup >解决了什么问题?
    经过语法糖的封装更简单的使用组合式API
  4. setup中this还指向组件实例吗?
    指向undefined

组合式API - reactive和ref函数

  1. reactive()
    作用:接受对象类型数据的参数传入并返回一个响应式对象
  2. 核心步骤:
<script setup>
//导入
import {reactive} from 'vue'
//执行函数 传入参数 变量接收
const state = reactive(对象类型数据)
</script>
  • 从vue包中导入reactive函数
  • 在< script setup> 中执行reactive 函数并传入类型为对象的初始值,并使用变量接收返回值
    案例:
<script setup>
//1. 导入函数
import {reactive} from 'vue'

//2. 执行函数 传入一个对象类型的参数 变量接收
const state = reactive({
  count: 0
})

const setCount = () => {
  state.count++
}
</script>

<template>
  <div>
    <button @click="setCount">{{ state.count }}</button>
  </div>
</template>
  1. ref()
    作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
    核心步骤:
<script setup>
//导入
import {ref} from 'vue'
//执行函数 传入参数 变量接收
const count = ref(简单类型或者复杂类型数据)
</script>
  • 从vue包中导入ref函数
  • 在< script setup >中执行ref函数并传入初始值,使用变量接收ref函数的返回值

总结:
(1) reactive和ref函数的共同作用是什么?
用函数调用的方式生成响应式数据
(2)reactive vs ref?
- reactive不能处理简单类型的数据
- ref参数类型支持更好但是必须通过.value访问修改
- ref函数的内部实现依赖于reactive函数
(3)在实际工作中推荐使用哪个?
推荐使用ref函数,更加灵活

computed计算属性函数

计算属性基本思想和Vue2的完全一致,组合式API下的计算属性只是修改了写法
核心步骤:

  1. 导入computed函数
  2. 执行函数在回调参数中return基于响应式数据做计算的值,用变量接收

计算属性小案例:

<script setup>
// 原始响应式数组
import {ref} from 'vue'
// 1.导入computed函数
import {computed} from 'vue'
const list = ref([1, 2, 3, 4, 5, 6, 7, 8])

// 2.执行函数 return 计算之后的值 变量接收
const computedList = computed(() => {
  return list.value.filter(item => item > 2)
})
setTimeout(() => {
  list.value.push(9, 10)
}, 3000)
</script>

<template>
  <div>
    原始响应数组 - {{ list }}
  </div>
  <div>
    计算属性数组 - {{ computedList }}
  </div>
</template>
  • 计算属性中不应该有“副作用”(异步请求/修改dom)
  • 避免直接修改计算属性的值(计算属性应该是只读的)

watch函数

作用:侦听一个或者多个数据的变化,数据变化时执行回调函数
两个额外的参数:1. immediate(立即执行)2. deep(深度侦听)

  1. 基础使用 - 侦听单个数据
  • 导入watch函数
  • 执行watch函数传入要侦听的响应式数据(ref对象)和回调函数
<script setup>
import {ref, watch} from 'vue'
const count = ref(0)
const setCount = ()=>{
  count.value++
}

// ref对象不需要加.value
watch(count, (newVal, oldVal)=>{
  
})
</script>

<template>
  <div>
    <button @click="setCount">+{{ count }}</button>
  </div>
</template>
  1. 基础使用 - 侦听多个数据
    说明:同时侦听多个响应式数据的变化,不管哪个数据变化都需要执行回调
<script setup>
// 侦听多个数据变化
import {ref, watch} from 'vue'

const count = ref(0)
const changeCount = ()=>{
  count.value++
}

const name = ref('cp')
const changeName = ()=>{
  name.value = 'pc'
}

watch([count, name], ([newCount, newName], [oldCount, oldName])=>{
  console.log('count或者name变化了', [newCount, newName], [oldCount, oldName]);
})
</script>

<template>
  <div>
    <button @click="changeCount">修改count--{{ count }}</button>
  </div>
  <div>
    <button @click="changeName">修改name--{{ name }}</button>
  </div>
</template>
  1. immediate
    说明:在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调
const count = ref(0)
watch(count, () => {
	console.log('count发生了变化')}{immediate: true})
  1. deep
    默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项
<script setup>
import {ref, watch} from 'vue'
const state = ref({count: 0})
const changeStateByCount = () => {
	//直接修改count
	state.value.count++
}
//watch深度监听
watch(state, ()=>{
	console.log('count变化了')
}, {
	deep: true
})
</script>
<template>
  <div>
    {{state.count}}
    <button @click="changeStateByCount">通过count修改</button>
  </div>
</templete>
  1. 精确侦听对象的某个属性
    需求:在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调

总结:

  • 作为watch函数的第一个参数,ref对象需要添加.value吗?
    不需要,watch会自动读取
  • watch只能侦听单个数据吗?
    单个或者多个
  • 不开启deep,直接修改嵌套属性能触发回调吗?
    不能,默认是浅层侦听
  • 不开启deep,想在某个层次比较深的属性变化时执行回调怎么做?
    可以把第一个参数写成函数的写法,返回要监听的具体属性

组合式API - 生命周期函数

Vue3的生命周期(选项式 VS 组合式)

选项式API组合式API
beforeCreate/createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted

生命周期函数的基本使用

  1. 导入生命周期函数
  2. 执行生命周期函数 传入回调

执行多次
生命周期函数是可以执行多次的,多次执行时传入的回调会在时机成熟时依次执行

<script setup>
// 生命周期函数的使用
// 1.引入函数
import {onMounted} from 'vue'

// 2.执行函数 传入回调
onMounted(()=>{
  console.log('组件挂载完毕mounted执行了1')
})

onMounted(()=>{
  console.log('组件挂载完毕mounted执行了2')
})
</script>

<template>
  <div>

  </div>
</template>
  • 组合式API中生命周期函数的格式是什么?
    on+生命周期名字
  • 组合式API中可以使用onCreated吗?
    没有这个钩子函数,直接写到setup中
  • 组合式API中组件卸载完毕时执行哪个函数?
    onUnmounted

组合式API - 父子通信

组合式API下的父传子
基本思想

  1. 父组件中给子组件绑定属性
  2. 子组件内部通过props选项接收
    父:
<script setup>
// setup语法糖下局部组件无需注册直接可以使用
import SonCom from './son-com.vue'
</script>

<template>
  <div class="father">
    <h2>父组件App</h2>
    <!-- 1.绑定属性 -->
    <SonCom message="father message"/>
  </div>
</template>

<style scoped>
</style>

子:

<script setup>
// 2.defineProps接收数据
const props = defineProps({
    message: String
})
console.log(props);
</script>

<template>
    <div class="son">
        <h3>子组件Son</h3>
        <div>
            父组件传入的数据 - {{ message }}
        </div>
    </div>
</template>

<style scoped>
</style>

组合式API下的子传父
基本思想

  1. 父组件中给子组件标签通过 @ 绑定事件
  2. 子组件内部通过 $emit 方法触发事件
    父:
<script setup>
// 引入子组件
import sonComVue from './son-com.vue'
const getMessage = (msg) => {
  console.log(msg);
}
</script>
<template>
  <sonComVue @get-message="getMessage"/>
</template>

子:

<script setup>
//2. 通过defineEmits编译器宏生成emit方法
const emit = defineEmits(['get-message'])
const sendMsg = () => {
    //3. 触发自定义事件 并传递参数
    emit('get-message', 'this is son msg')
}
</script>

<template>
    <button @click="sendMsg">sendMsg</button>
</template>

父传子

  1. 子传父的过程中通过什么方式接收props?
defineProps({属性名:类型})
  1. setup语法糖中如何使用父组件传过来的数据?
const props = defineProps({属性名:类型})

子传父

  1. 子传父的过程中通过什么方式得到emit方法
defineEmits(['事件名称'])

组合式API - 模板引用

模板引用的概念:通过ref标识获取真实的dom对象或者组件实例对象
如何使用(以获取dom为例 组件同理)

  1. 调用ref函数生成一个ref对象
  2. 通过ref标识绑定ref对象到标签
<script setup>
import {onMounted, ref} from 'vue'
import TestCom from './test-com.vue'
//1. 调用ref函数 -> ref对象
const h1Ref = ref(null)
const comRef = ref(null)

//组件挂载完毕之后才能获取
onMounted(() => {
  console.log(h1Ref.value);
  console.log(comRef.value);
})
</script>

<template>
  <!-- //2. 通过ref标识绑定ref对象 -->
  <h1 ref="h1Ref">我是dom标签h1</h1>
  <TestCom ref="comRef"/>
</template>

defineExpose()
默认情况下在< script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性和方法允许访问

<script setup>
import {ref} from 'vue'
const testMessage = ref('this is test msg')
</script>
<script setup>
import {ref} from 'vue'
const testMessage = ref('this is test msg')
defineExpose({
	testMessage
})
</script>
  1. 获取模板引用的时机是什么?
    组件挂载完毕
  2. defineExpose编译宏的作用是什么?
    显示暴露组件内部的属性和方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/663705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SynchronousQueue的TransferQueue源码分析

QNode的源码信息分析 一行一行的分析大概内容&#xff1b;下面会省略大量的CAS操作当前节点可以获取到的next节点item在生产者和消费者下有所不同。生产者是有数据。消费者为null。waiter为当前线程isData属性是用来区分消费者和生产者的属性。值得一提的是最终生产者需要将it…

2023年我国省市县的高新技术企业数量(Excel/Shp格式)

企业是经济活动的参与主体。一个城市的企业数量决定了这个城市的经济发展水平&#xff01;比如一个城市的金融企业较多&#xff0c;那这个城市的金融产业肯定比较发达&#xff1b;一个城市的制造业企业较多&#xff0c;那这个城市的制造业肯定比较发达。 目前&#xff0c;在城…

Android 13(T) - Media框架 - 异步消息机制

由于网上已经有许多优秀的博文讲解了Android的异步消息机制&#xff08;ALooper/AHandler/AMessage那一套&#xff09;&#xff0c;而且流程也不是很复杂&#xff0c;所以这里将不会去讲代码流程。本篇将会记录学习过程中的疑问以及自己的解答&#xff0c;希望可以帮助有同样疑…

机器学习——感知机模型(手动代码)

感知机&#xff0c;应该是很简单的模型了 1. 建立模型 感知机的模型&#xff0c;是一种多元线性回归符号函数的二分类模型。 多元线性回归函数&#xff1a;【Z &#xfeff;&#xfeff;&#xfeff; W T X W^{T}X WTX】 符号函数&#xff1a; y sign(Z) 1&#xff0c;当y…

vulhub-struts2-S2-008 远程代码执行漏洞复现

漏洞描述 影响版本: 2.1.0 - 2.3.1 漏洞原理 S2-008 涉及多个漏洞&#xff0c;Cookie 拦截器错误配置可造成 OGNL 表达式执行&#xff0c;但是由于大多 Web 容器&#xff08;如 Tomcat&#xff09;对 Cookie 名称都有字符限制&#xff0c;一些关键字符无法使用使得这个点显得…

JAVA-IO流实践操作

什么是IO流&#xff1f; I&#xff1a;Input O&#xff1a;Output 通过IO可以完成硬盘文件的读和写。 流是一连串连续动态的数据集合。可以理解为是我们在内存和硬盘之间进行文件读写的一个管道。抽象的一个概念。我们可以看成是一个管道&#xff0c;我们输入的数据要从管道…

C语言编程—强制类型转换

强制类型转换是把变量从一种类型转换为另一种数据类型。例如&#xff0c;如果您想存储一个 long 类型的值到一个简单的整型中&#xff0c;您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型&#xff0c;如下所示&am…

PyTorch 深度学习 || 2. 全连接网络 | Ch2.2 PyTorch 全连接网络分类

PyTorch 全连接网络分类 文章目录 PyTorch 全连接网络分类1. 非线性二分类2. 泰坦尼克号数据分类2.1 数据的准备工作2.2 全连接网络的搭建2.3 结果的可视化 1. 非线性二分类 import sklearn.datasets #数据集 import numpy as np import matplotlib.pyplot as plt from sklear…

从源码角度分析 MyBatis 工作原理

一、MyBatis架构 从 MyBatis 代码实现的角度来看&#xff0c;MyBatis 的主要组件有以下几个&#xff1a; SqlSession - 作为 MyBatis 工作的主要顶层 API&#xff0c;表示和数据库交互的会话&#xff0c;完成必要数据库增删改查功能。 Executor - MyBatis 执行器&#xff0c;…

前端自动化测试的核心概念及思考

本文&#xff0c;将主要结合钉钉中的业务实践和落地&#xff0c;描述笔者对前端自动化测试场景的理解。 本文将主要从“为什么前端要做自动化测试、前端自动化测试分类、业务做自动化测试要抓住的核心点、核心工具推荐“这四个部分做阐述&#xff0c;下面直接进入正文。 大钉…

【嵌入式Linux内核驱动】05_IIC子系统 | 硬件原理与常见面试问题 | 应用编程 | 内核驱动 | 总体框架

硬件原理 IIC协议 IIC 基础 IIC协议简介—学习笔记_iic标准协议_越吃越胖的黄的博客-CSDN博客 简介 I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种串行通信协议&#xff0c;用于连接微控制器、传感器、存储器和其他外设。 I2C使用两条线&#xff08;SDA和S…

Spark 1--3章简介,架构体系, 环境搭建

今天开始了新的课程 由我们的星哥带领我们踏入Spark的神秘殿堂 01_SparkCore 1. Spark简介 1.1 什么是Spark Spark是一种快速、通用、可扩展的大数据分析引擎&#xff0c;2009年诞生于加州大学伯克利分校AMPLab&#xff0c;2010年开源&#xff0c;2013年6月成为Apache孵化…

Cisco模拟器配置OSPF

一、前言 1.1 本文为Cisco模拟器配置OSPF操作笔记 (供新手参考&#xff09; 使用Cisco模拟器&#xff0c;配置OSPF协议&#xff0c;并使各台电脑ping通&#xff0c;如下参考图&#xff01; 1.2 思科路由器设置ip设置 在将设备摆放完毕后&#xff0c;需要配置每台设备的IP&…

【科普】干货!带你从0了解移动机器人(四) ——移动机器人导航技术

移动机器人导航是指移动机器人确定自己在地图参考系中的位置后&#xff0c;自动规划出通往地图参考系中某个目标位置路径并沿着该路径到达目标位置点的能力&#xff0c;是移动机器人行动能力的关键。 基于整个智能制造的发展&#xff0c;移动机器人导航技术大致可分为以下几种&…

【MarkDown】CSDN Markdown之思维导图mindmap详解

文章目录 思维导图(Mindmap)一个思维导图的例子语法形状矩形圆角矩形圆形爆炸云朵六边形默认 图标和类图标类 不清晰的缩进Markdown字符串与库或网站资源集成 思维导图(Mindmap) Mindmap现在是一个实验性的图表类型。语法和特性可能会在未来版本中更改&#xff0c;除了图标集成…

【UE 从零开始制作坦克】9-坦克瞄准

效果 步骤 1. 将下载的图片资源导入 2. 再新建一个控件蓝图&#xff0c;命名为“WBP_Aim” 打开“WBP_Aim”&#xff0c;拖入图像控件 选择图像控件的锚点如下 偏移全部置0 图像选择刚导入的“miaozhunjing” 3. 打开骨骼“SKEL_West_Tank_M1A1Abrams” 可以看到在炮管上有一个…

房屋装修选择自装,如何寻找选购系统门窗,比价并施工(门窗阶段)

环境&#xff1a; 地点&#xff1a;杭州 装修类型&#xff1a;自装 面积&#xff1a;建面135平方 进度&#xff1a;选购安装铝合金门窗阶段 问题描述&#xff1a; 房屋装修选择自装&#xff0c;如何寻找选购系统门窗&#xff0c;比价并施工 解决方案&#xff1a; 一、了…

暑期托管班招生海报模板 一键就能完成设计

即将到来的暑期&#xff0c;许多的兴趣班也将迎来暑期招生热&#xff0c;那么兴趣班如何设计一幅招生用的招生易拉宝&#xff1f;可以一键生成内容&#xff0c;自定义填写兴趣班的报名方式&#xff0c;课程内容以及联系方式等内容的招生海报制作工具&#xff01;跟着教程一起使…

Rust之泛型、特性和生命期(三):Traits:定义共同的行为

开发环境 Windows 10Rust 1.70.0 VS Code 1.79.2 项目工程 这里继续沿用上次工程rust-demo Traits&#xff1a;定义共同的行为 Trait定义了一个特定类型所具有的功能&#xff0c;并且可以与其他类型共享。我们可以使用特质以抽象的方式来定义共享行为。我们可以使用特质的界…