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

vue3.0组件API风格以及组合式API响应式基础

vue组件API风格

vue组件API风格:选项式 API 和组合式 API

1、选项式API

与vue2写法相似,使用选项的对象来描述组件的逻辑,例如data、methods和mounted等生命周期函数。选项所定义的属性都会暴露在函数内部的this上,它会指向当前的组件实例。

<script>
export default{
	data(){
		return{
			count:0
		}
	},
	methods:{
		increment(){
			this.count++
		}
	},
	mounted(){
		console.log(`The initial count is ${this.count}.`);
	}
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

2、组合式API

通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与

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

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

3、选项式和组合式API的区别

  • **选项式:**以“组件实例”的概念为中心 (即上述例子中的 this),对于有面向对象语言背景的用户来说,这通常与基于类的心智模型更为一致。同时,它将响应性相关的细节抽象出来,并强制按照选项来组织代码,从而对初学者而言更为友好。
  • **组合式:**组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由,也需要你对 Vue 的响应式系统有更深的理解才能高效使用。相应的,它的灵活性也使得组织和重用逻辑的模式变得更加强大。

4、注意事项

Vue 2 在 2022 年 6 月发布了最后一个小版本 (2.7),Vue 2 在 2023 年 12 月 31 日将到达它的截止维护日期;目前vue3是vue当前的最新主版本;

vue3提供了更小的包体积、更好的性能、更好的可扩展性和更好的 TypeScript/IDE 支持。如果你现在要开始一个新项目,推荐你选择 Vue 3。但需支持EI11,如果项目无法满足此需求可考虑使用vue2

最新版本的 Vue (3.x) 只支持原生支持 ES2015 的浏览器。这并不包括 IE11。Vue 3.x 使用的 ES2015 功能无法在旧版本的浏览器中进行兼容,如果你需要支持旧版本的浏览器,请使用 Vue 2.x 替代

5、组合式API响应的核心

组合式api通常与< script setup > 搭配使用;

ref()
computed()
reactive()
readonly()
watchEffect()
watchPostEffect()
watchSyncEffect()
watch()

5.1、ref(),由于reactive的限制,推荐使用ref()作为声明响应式状态的主要API

组合API中,推荐使用ref()来声明响应式状态;
ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回:

当你在模板中使用了一个 ref,然后改变了这个 ref 的值时,Vue 会自动检测到这个变化,并且相应地更新 DOM。这是通过一个基于依赖追踪的响应式系统实现的。当一个组件首次渲染时,Vue 会追踪在渲染过程中使用的每一个 ref。然后,当一个 ref 被修改时,它会触发追踪它的组件的一次重新渲染。

//设置简单类型
<script setup>
import { ref } from 'vue'
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0

//ref 会根据初始化时的值推导其类型:
const year = ref(2020);//Number
const str = ref('hello word');//String
const isShow = ref(true);//Boolean
</script>
<script setup>
import { ref, onMounted} from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <div>在模板中使用 ref 时,我们不需要附加.value; 当在模板中使用时,ref 会自动解包</div>
  <button @click="increment">Count is: {{ count }}</button>
</template>

5.1.1、模板解包注意事项

在模板渲染上下文中,只有顶级的 ref 属性才会被解包。

另一个需要注意的点是,如果 ref 是文本插值的最终计算值 (即 {{ }} 标签),那么它将被解包;该特性仅仅是文本插值的一个便利特性,等价于 {{ object.id.value }}

const count = ref(0)
const object = { id: ref(1) };
const { id } = obj;//对象的解构,必须对象名相同
function countHandle(){
	count.value++;
	obj.id++;
}
<template>
  <div>count+1:{{ count+1 }} 按照预期工作,结果为1,</div>
  <div>obj.id:{{ obj.id }}  等价于 obj.id.value</div>
  <div>obj.id.value:{{ obj.id.value+1 }} 结果为2</div>
  <div>obj.id+1:{{ obj.id + 1 }} 不会按照预期工作,结果为[object Object]1</div>
  <div>{{ id+1 }} 结果为2</div>
  <button @click="countHandle()">点击方法查看响应区别</button>
</template>

5.1.2、DOM更新时机

当你修改了响应式状态时,DOM 会被自动更新。但是需要注意的是,DOM 更新不是同步的。Vue 会在“next tick”更新周期中缓冲所有状态的修改,以确保不管你进行了多少次状态修改,每个组件都只会被更新一次。

要等待 DOM 更新完成后再执行额外的代码,可以使用 nextTick() 全局 API:

//设置简单类型
<script setup>
import { ref } from 'vue'
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0

//ref 会根据初始化时的值推导其类型:
const year = ref(2020);//Number
const str = ref('hello word');//String
const isShow = ref(true);//Boolean
</script>
<script setup>
import { ref,nextTick } from 'vue'

function increment() {
  const count = ref(0);
  console.log(document.getElementById('counter').textContent);//0
  nextTick(()=>{
  	//现在DOM已更新
  	console.log(document.getElementById('counter').textContent);//1
  })
}
</script>

<template>
  <div>count: <span id="counter">{{count}}</span></div>
  <button @click="increment">Count is: {{ count }}</button>
</template>
async function countHandle(){
	count.value++;
	console.log(document.getElementById('counter').textContent);//0
	await nextTick();
	console.log(document.getElementById('counter').textContent);//1
}

5.2、reactive()响应式API

reactive() 将使对象本身具有响应性;
将一个 ref 赋值给一个 reactive 属性时,该 ref 会被自动解包:

<script setup>
const count = ref(0);
const obj = reactive({age:18,name:'张三'});
obj.count = count;
function countHandle(){
	count.value++;
	obj.age++;
}
</script>
<template>
<button @click="countHandle" id="counter">加1,count的值:{{count}}</button>
<div>obj的age:{{obj.age}}</div>
<div>obj的count:{{obj.count}}</div>
</template>

reactive() 的局限性:

  1. 有限的值类型:它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。
  2. 不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失;
  3. 对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:

一个 ref 会在作为响应式对象的属性被访问或修改时自动解包。换句话说,它的行为就像一个普通的属性

<script setup>
const state = reactive({count});

function countHandle(){
	count.value++;
}
</script>
<template>
<div>count: <span id="counter">{{count}}</span></div>
<div>state: {{state.count}}</div>
<button @click="countHandle()">count和state.count值同时更改</button>
</template>

如果将一个新的 ref 赋值给一个关联了已有 ref 的属性,那么它会替换掉旧的 ref:

<script setup>
const state = reactive({count});
const otherCount = ref(2);
//原始 ref 现在已经和 state.count 失去联系
state.count = otherCount;

function countHandle(){
	count.value++;
}
</script>
<template>
<div>count: <span id="counter">{{count}}</span></div>
<div>state: {{state.count}}</div>
<button @click="countHandle()">state.count值不会更改</button>
</template>

6、vue3响应式API:核心

  • ref()
  • computed()
  • reactive()
  • readonly()
  • watchEffect()
  • watchPostEffect()
  • watchSyncEffect()
  • watch()

vue3响应式API核心官网介绍


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

相关文章:

  • 【vue3封装element-plus的反馈组件el-drawer、el-dialog】
  • docker minio镜像arm64架构
  • 计算机网络之---TCP/IP四层模型
  • 基于FPGA的出租车里程时间计费器
  • 【机器学习:四、多输入变量的回归问题】
  • 基于SMT32U575RIT单片机-中断练习
  • 一款基于 SpringCloud 开发的AI聊天机器人系统,已对接GPT-4.0,非常强大
  • 电学基础知识
  • macbook删除软件只需几次点击即可彻底完成?macbook删除软件没有叉 苹果笔记本MacBook电脑怎么卸载软件? cleanmymac x怎么卸载
  • 4.GetMapping和PostMapping 和 @RequestMapping的区别。RequestBody 和ResponseBody的区别
  • Java面向对象特征(二)----- 继承
  • flinksql在实时数仓hologres的计算问题排查
  • 2024-3-18-C++day6作业
  • 抖音无水印视频关键词批量下载|视频下载工具
  • 青海200MW光伏项目 35kV开关站图像监控及安全警示系统
  • 蓝桥杯算法基础(24):多维数组与矩阵(4道小题)java版
  • [日报] Ribbon、Eureka、Nginx、负载均衡
  • 深入理解Apache Kafka Topic:架构设计与应用场景
  • 【Linux】日常使用命令(三)
  • 保护你的微服务:Sentinel熔断器的原理与应用解析(二)
  • 【vue】深入探讨vue中组件间多种传值方式
  • 蓝桥杯C++大学B组一个月冲刺记录2024/3/18
  • 【DL经典回顾】激活函数大汇总(二十一)(BReLU附代码和详细公式)
  • 身份证文字识别ocr免费-身份证实名认证接口-护照识别-Java调用代码
  • 【ADF4351】使用FPGA进行SPI寄存器配置、使用FPGA计算各个频率的频点,ADF4351配置程序
  • Games101课程笔记1--图形学简介