一个项目学习Vue3---响应式基础

观察下面一段代码,学习响应式基础的全部内容

<template><div><div>将下面的msg属性放到上面来:{{ msg }}</div><button @click="count++">{{ count }}</button><button @click="object.count.value++">{{ object.count.value }}</button><button @click="open">点击变猪</button><button @click="addAge">长大一岁</button><a :href="hrefValue" id="herfValue">Dom更新的时间:{{ hrefValue }}</a><button @click="changeUrl">更改上面url</button><button @click="addAgeReactive">长大一岁{{ age.count }}</button></div>
</template><script lang="ts" setup>
import { nextTick } from 'vue'
import { ref } from 'vue'
import { reactive } from 'vue'
//绑定上方的学无止境
const msg = ref('学无止境')
//绑定上方的count
const count = ref(0)
//如果这么写count是不能被解包的
const object = { count: ref(1) }
//如果标签中存在object.count++则不会被解包
//必须使用object.count.value++才能//下面代买会输出学无止境
console.log(msg.value)
//绑定上方的变猪
function open() {msg.value = '猪'
}
//绑定一个对象
const user = ref({userName: '张三',age: 10
})
//增加一岁
function addAge() {user.value.age++
}
const hrefValue = ref('www.baidu.com')
async function changeUrl() {hrefValue.value = 'www.json.cn'let element = document.getElementById('herfValue')if (element) {console.log(element.getAttribute('href'))}await nextTick//他在执行了上面的nextTick方法之后才会改变值if (element) {console.log(element.getAttribute('href'))}
}
const age = reactive({ count: 0 })
//又增加一岁
function addAgeReactive() {//reactive创建的不需要写valueage.count++
}
let raw = {}
const proxy = reactive(raw)
//true
console.log(reactive(raw) === proxy)
//false
console.log(proxy === raw)
//即便返回
const proxy2 = reactive({})
proxy2.nested = raw
//返回false
console.log(proxy2.nested === raw)
proxy2.nested = proxy
//返回true
console.log(proxy2.nested === proxy)//reactive局限性
let state = reactive({ count: 0 })// 上面的 ({ count: 0 }) 引用将不再被追踪
// (响应性连接已丢失!) 重复赋值
state = reactive({ count2: 1 })
// 当解构时,count 已经与 state.count 断开连接
let { count2 } = state
// 不会影响原始的 state
count2++// 该函数接收到的是一个普通的数字
// 并且无法追踪 state.count 的变化
// 我们必须传入整个对象以保持响应性
//找不到count 这个属性,所以代理对象之间不能相互赋值
callSomeFunction(state.count2)function callSomeFunction(count) {//返回0console.log(count)
}//Ref自动解包
const name = ref('张三')
const bigName = reactive({ name })
//输出的实际是ref("张三")
console.log(bigName.name)
//ref("张三") = "李四"
bigName.name = '李四'
//返回李四
console.log(name.value)
//返回李四
console.log(bigName.name)//如果将一个新的 ref 赋值给一个关联了已有 ref 的属性,那么它会替换掉旧的 ref:
const otherName = ref("王五")
bigName.name = otherName
//返回王五
console.log(bigName.name)
//返回李四
console.log(name.value) //与 reactive 对象不同的是,当 ref 作为响应式数组或原生集合类型 (如 Map) 中的元素被访问时,它不会被解包:
const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)</script><style scoped>
</style>

他执行之后产生的页面是这样的

知识点1:ref()

当我们在script引入

<script lang="ts">import { ref } from 'vue'
</script>

我们就可以使用ref来代理一些变量,还记得我们在vue2中的写法吗?通过选项式API,我们在return中的变量都可以被vue双向绑定,而在vue3中我们可以使用更加便捷的方式来操作变量,

<script lang="ts">
import { ref } from 'vue'
setup(){const msg = ref('学无止境')return {msg}
}
</script>

在上面return中的内容就相当于vue2中任何return、methods等一切可以双向绑定的内容,是的,他也可以代理方法

<script lang="ts">
import { ref } from 'vue'
setup(){const msg = ref('学无止境')function open() {msg.value = '猪'}return {openmsg}
}
</script>

这样他就可以代理方法了,我们看到一个msg.value,什么意思呢?ref本质是一个对象,.value可以对对象进行解包,这样就可以获取msg的内容。当然如果你绑定到html代码里面,这个东西是会自动解包的

<div>将下面的msg属性放到上面来:{{ msg }}</div>

它也可以绑定对象等

<template><button @click="addAge">长大一岁</button>
</template>
<script lang="ts">
setup(){//绑定一个对象const user = ref({userName: '张三',age: 10})//增加一岁function addAge() {user.value.age++}return {user,addAge}
}
</script>

如果你想分别获取ref变化之前和之后的值,nextTick可以帮助到你

<template><a :href="hrefValue" id="herfValue">Dom更新的时间:{{ hrefValue }}</a><button @click="changeUrl">更改上面url</button>
</template>
<script lang="ts">
import { nextTick } from 'vue'
import { ref } from 'vue'
setup(){const hrefValue = ref('www.baidu.com')async function changeUrl() {hrefValue.value = 'www.json.cn'let element = document.getElementById('herfValue')if (element) {console.log(element.getAttribute('href'))}await nextTick//他在执行了上面的nextTick方法之后才会改变值if (element) {console.log(element.getAttribute('href'))}}return {changeUrl,hrefValue }
}
</script>

上面的代码在   await nextTick之前,他的值事还没有变化的,所以你hrefValue.value之后,是不能快速的获取到他的值的

写了这么多,我们发现每次都需要最后都要return,每次都需要写setup函数不方便,那么我们可以简化一些代码,例如上面那段代码,我们可以简化成

<template><a :href="hrefValue" id="herfValue">Dom更新的时间:{{ hrefValue }}</a><button @click="changeUrl">更改上面url</button>
</template>
<script lang="ts" setup>const hrefValue = ref('www.baidu.com')async function changeUrl() {hrefValue.value = 'www.json.cn'let element = document.getElementById('herfValue')if (element) {console.log(element.getAttribute('href'))}await nextTick//他在执行了上面的nextTick方法之后才会改变值if (element) {console.log(element.getAttribute('href'))}}}
</script>

这样就可以不写setup和return函数了,他会自己检测需要return的东西,函数或者变量都会被返回。

知识点2: reactive()

reactive的使用和ref基本类似

const age = reactive({ count: 0 })
//又增加一岁
function addAgeReactive() {//reactive创建的不需要写valueage.count++
}

如上面所示,他不需要进行写.value就可以对变量进行++操作

在比较相等性,也就是引用上,可能与我们想象的不同

let raw = {}
const proxy = reactive(raw)
//会引用同一个对象,返回true
console.log(reactive(raw) === proxy)
//封装的对象和原始对象不一样,返回false
console.log(proxy === raw)
const proxy2 = reactive({})
proxy2.nested = raw
//封装对象的属性被赋值普通对象,返回false
console.log(proxy2.nested === raw)
proxy2.nested = proxy
//封装对象的属性被赋值封装对象,返回true
console.log(proxy2.nested === proxy)

区别于vue2,return中的对象只会双向绑定,但是vue3中这么开放肯定会存在覆盖的现象

//reactive局限性
let state = reactive({ count: 0 })// 上面的 ({ count: 0 }) 引用将不再被追踪
// (响应性连接已丢失!) 重复赋值
state = reactive({ count2: 1 })
// 当解构时,count 已经与 state.count 断开连接
let { count2 } = state
// 不会影响原始的 state
count2++// 该函数接收到的是一个普通的数字
// 并且无法追踪 state.count 的变化
// 我们必须传入整个对象以保持响应性
//找不到count 这个属性,所以代理对象之间不能相互赋值
callSomeFunction(state.count2)function callSomeFunction(count) {//返回0console.log(count)
}

如上state又被重复赋值了,那么他最后指向的是后者 当解构时,count 已经与 state.count 断开连接,即便++,也只是普通变量的++,不能改变count2的值

知识点3:ref自动解包

//Ref自动解包
const name = ref('张三')
const bigName = reactive({ name })
//输出的实际是ref("张三")
console.log(bigName.name)
//ref("张三") = "李四"
bigName.name = '李四'
//返回李四
console.log(name.value)
//返回李四
console.log(bigName.name)//如果将一个新的 ref 赋值给一个关联了已有 ref 的属性,那么它会替换掉旧的 ref:
const otherName = ref("王五")
bigName.name = otherName
//返回王五
console.log(bigName.name)
//返回李四
console.log(name.value) //与 reactive 对象不同的是,当 ref 作为响应式数组或原生集合类型 (如 Map) 中的元素被访问时,它不会被解包:
const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)

就是有时候需要写.value,有时候不需要,在ref对象被当作一个对象传入时候是自动解包的,他在其他对象里面则无法自动解包

   关注公众号:资小库,问题快速答疑解惑

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

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

相关文章

关于Autowired

Autowired 是 Spring Framework 中的一个注解&#xff0c;用于自动注入依赖对象。通过这个注解&#xff0c;Spring 可以自动将匹配的 bean 注入到所需的类中&#xff0c;从而实现控制反转&#xff08;IoC&#xff09;和依赖注入&#xff08;DI&#xff09;。 基本用法 Autowi…

javascript: void(0);用法和常见问题

在JavaScript中&#xff0c;void(0)是一个表达式&#xff0c;它用来获取一个特殊的值undefined&#xff0c;并且执行一个没有返回值的操作。这个表达式经常用于创建一个没有实际返回值的函数调用&#xff0c;或者在需要一个表达式的地方使用&#xff0c;但不希望有任何返回值。…

【Carsim】Carsim2019与Matlab2015b联合仿真测试

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Carsim2019与Matlab2015b联合仿真测试。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c…

HTML基础知识学习指南

HTML基础知识学习指南 1. 介绍 HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础。它是一种标记语言&#xff0c;用于定义网页的内容和结构。HTML由一系列元素组成&#xff0c;这些元素使用标签来表示。 2. HTML文档结构 HTML文档的基本结构包括以下部分&#…

AI作画工具深度剖析:Midjourney vs. Stable Diffusion (SD)

在人工智能技术的推动下&#xff0c;艺术创作的边界被不断拓宽&#xff0c;AI作画工具成为数字艺术家与创意人士的新宠。其中&#xff0c;Midjourney与Stable Diffusion&#xff08;SD&#xff09;作为当前领域的佼佼者&#xff0c;以其独特的算法机制、丰富的功能特性及高质量…

python-糖果俱乐部(赛氪OJ)

[题目描述] 为了庆祝“华为杯”的举办&#xff0c;校园中开展了许多有趣的热身小活动。小理听到这个消息非常激动&#xff0c;他赶忙去参加了糖果俱乐部的活动。 该活动的规则是这样的&#xff1a;摊位上有 n 堆糖果&#xff0c;第 i 堆糖果有 ai​ 个&#xff0c;参与的同学可…

面向工业化的多类电子元件自动计数系统测试报告

目录 1、项目描述 2、登录注册测试 2、主界面测试 2.1、在线计数测试 2.2、离线计数测试 2.3、浏览数据测试 1、项目描述 该系统利用机器视觉平台采集电子元件图像&#xff0c;设计并实现了适应不同形态分布的电子元件计数模型&#xff0c;能够快速且准确地进行计数和分类&…

0139__TCP协议

全网最详细TCP参数讲解&#xff0c;再也不用担心没有面试机会了_tcp的参数-CSDN博客 TCP协议详解-腾讯云开发者社区-腾讯云 TCP-各种参数 - 简书

【408考点之数据结构】树形查找

树形查找 树形查找是利用树这种数据结构进行查找操作的方法。树形查找的主要优势在于它能够通过层次结构有效地组织数据&#xff0c;使得查找、插入和删除操作都能够高效进行。以下是对树形查找的详细总结。 1. 二叉查找树&#xff08;Binary Search Tree, BST&#xff09; …

第4章:操作系统

第4章&#xff1a;操作系统 操作系统概述 进程管理 在有限的资源下&#xff0c;要保证系统不发生死锁&#xff0c;则可以按这种逻辑来分析。首先给每个进程分配所需资源数减1个资源&#xff0c;然后系统还有1个资源&#xff0c;则不可能发生死锁。 线程 存储管理 虚拟存储器的…

C++ //练习 14.22 定义赋值运算符的一个新版本,使得我们能把一个表示ISBN的string赋给一个Sales_data对象。

C Primer&#xff08;第5版&#xff09; 练习 14.22 练习 14.22 定义赋值运算符的一个新版本&#xff0c;使得我们能把一个表示ISBN的string赋给一个Sales_data对象。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 struct Sa…

全面讲解GRASP原则

学习目标&#xff1a; 掌握GRASP 学习内容&#xff1a; GRASP&#xff08;General Responsibility Assignment Software Patterns&#xff0c;通用责任分配软件模式&#xff09;原则是一组设计原则和模式&#xff0c;旨在帮助软件设计人员合理地分配类和对象的责任。GRASP原则…

昇思25天学习打卡营第九天|使用静态图加速

背景 提供免费算力支持&#xff0c;有交流群有值班教师答疑的华为昇思训练营进入第九天了。 今天是第九天&#xff0c;前八天的学习内容可以看链接 昇思25天学习打卡营第一天|快速入门 昇思25天学习打卡营第二天|张量 Tensor 昇思25天学习打卡营第三天|数据集Dataset 昇思25天…

高效的向量搜索算法——分层可导航小世界图(HNSW)

最近在接触大模型相关内容&#xff0c;发现一种高效的向量搜索算法HNSW&#xff0c;这里做一下记录。 在之前自己也接触过一段时间的复杂网络&#xff08;网络科学&#xff09;&#xff0c;没想到&#xff0c;将网络科学的思想引入到向量搜索算法中&#xff0c;可以产生令人眼前…

如何实现公网环境远程连接本地局域网宝塔FTP服务远程管理文件

文章目录 前言1. Linux安装Cpolar2. 创建FTP公网地址3. 宝塔FTP服务设置4. FTP服务远程连接小结 5. 固定FTP公网地址6. 固定FTP地址连接 &#x1f4a1;推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。…

Python28-5 k-means算法

k-means 算法介绍 k-means 算法是一种经典的聚类算法&#xff0c;其目的是将数据集分成 ( k ) 个不同的簇&#xff0c;每个簇内的数据点尽可能接近。算法的基本思想是通过反复迭代优化簇中心的位置&#xff0c;使得每个簇内的点与簇中心的距离之和最小。k-means 算法的具体步骤…

S7-1500轴工艺对象105报文安装(硬件目录的支持包 HSP)

S7-1500PLC里硬件组态没法组态到105报文是因为对应的HSP文件没有安装&#xff0c;首先需要安装对应的HSP文件。 1、HSP文件安装 V19版本的HSP安装链接如下 https://download.csdn.net/download/m0_46143730/89503735 2、安装HSP文件 3、需要将博途软件关闭才能完成安装 4、拖…

猫头虎博主全栈前沿AI技术领域矩阵社群

猫头虎博主全栈前沿AI技术领域矩阵社群 &#x1f44b;大家好&#xff0c;我是猫头虎&#xff01;今天我要向大家介绍一个非常重要的社群矩阵——专为全栈前沿AI技术领域的朋友们打造的各种技术交流和资源互助的社群。这些社群不仅能帮助大家快速提升技术水平&#xff0c;还能拓…

Java中的行为驱动开发(BDD)实践

Java中的行为驱动开发&#xff08;BDD&#xff09;实践 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨Java中的行为驱动开发&#xff08;BD…

【MySQL备份】Percona XtraBackup全量备份实战篇

目录 1. 前言 2.准备工作 2.1.环境信息 2.2.创建备份目录 2.3.配置/etc/my.cnf文件 2.4.授予root用户BACKUP_ADMIN权限 3.全量备份 4.准备备份 5.数据恢复 6.总结 "实战演练&#xff1a;利用Percona XtraBackup执行MySQL全量备份操作详解" 1. 前言 本文…