文章目录
- Proxy(Object)
- proxy是什么东西
- Proxy(Object)
- reactive()这个小括号里头可以写什么?
- reactive定义的对象类型的响应数据是深层次的
- 专业词汇:响应式对象和原对象
- 回顾
- ref定义对象类型的响应式数据
- ref定义的对象类型响应式数据和reactive定义的对象类型的响应式数据
- 回顾
- ref的.value很烦人怎么解决
- reactive的局限性:替换对象的做法
- ref的理解:ref替换对象怎么做?
- ref的另外的误区
- 开发时候响应式数据怎么使用
- 回顾
- 解构赋值的理解
- 怎么让响应式对象解构变成响应式
- toRefs的作用
- toRefs的小点
- toRefs的总结
- toRef API
- toRefs和toRef总结
- computed计算属性评价
- computed计算属性的例子
- computed计算属性的使用场景是什么?
- vue2当中的计算属性是怎么写的
- vue3当中的计算属性的写法
- 计算属性的特点
- 计算属性是有缓存的
- 计算属性:只读的
- 计算属性到底是什么?
- 修改计算属性发现是只读的
- 怎么写让计算属性既能读也能改
ref定义基本类型的数据;
如果不是基本类型的数据,使用什么呢?
reactive用于定义对象类型的数据;
ref定义基本类型的数据
reactive定义对象类型的数据
从这一步启动;
非常简单的,上面的就是reactive的用法,很简单的,就是用reactive()包裹一下对象就可以了;
Proxy(Object)
一个car对象,如果我们直接打印,就是上面的{brand: '奔驰', price: 100}
一个car对象,如果我们使用reactive包裹了之后,再次进行打印,就是Proxy(Object){brand: '奔驰', price: 100}
proxy是什么东西
Proxy就是javascript当中原生的、内置的函数
:
使用console.log(Proxy),打印出来的效果如下所示:
Proxy(Object)
reactive()这个小括号里头可以写什么?
对象是可以写的;
一般对象也是对象的;
数组也是对象的;
函数也是对象的;
我们写了一个数组,然后在template当中进行展示;
v-for是对数组当中的内容的遍历;然后遍历的时候最好是有一个key,我们的v-bind:key可以缩写成为
:key
;
reactive定义的对象类型的响应数据是深层次的
这个就是所谓的:深层次的,对象类型的数据;
我们将这个666的数据,在页面上渲染出来;
然后我们写了一个方法,去改变这个数据;
但是现在这个数据,不是响应式的;
我们要想要对数据进行响应式处理,就是像是上面这样,使用reactive进行包裹的;
专业词汇:响应式对象和原对象
比如上面的数据中,我们使用reactive包裹前的对象,就是原对象,包裹后的对象,就是响应式对象
;
如果你在控制台输出,看到下面的玩意,都是响应式对象:
回顾
ref是定义基本类型的响应式数据;
reactive是定义对象类型的响应式数据;reactive只能够定义对象类型的响应式数据;
ref是可以定义基本类型的响应式数据,也可以定义对象类型的响应式数据;
貌似ref是更厉害的;
ref定义对象类型的响应式数据
ref定义的对象类型响应式数据和reactive定义的对象类型的响应式数据
表面上你是使用ref来将一个对象类型的数据,变成了响应式的数据;
但是底层,ref的value,还是使用reactive来将对象数据,变成了响应式的数据;
ref看起来什么都可以处理,当它遇到了对象类型的数据,还是要求助于reactive的;
回顾
ref既能够定义基本类型,也能够定义对象类型;
reactive只能够定义对象类型;
我开发的时候使用什么呢?
ref的.value很烦人怎么解决
在vscode当中可以使用volar插件,实现自动.value;
插件会帮你记住的;
reactive的局限性:替换对象的做法
reactive的局限性就是上面的这句话;
重新分配一个对象的时候,会失去响应式的;
有点懵逼的;
reactive包裹的数据是一个对象的;这是没有问题的;
如果你想要替换这个对象的所有的内容,就使用Object.assign这种做法是可以的;
ref的理解:ref替换对象怎么做?
如果你的对象数据,是使用ref包裹的;
那么:
当你想要进行对象替换的时候,是可以直接写的:
这是因为:写ref就必须写.value,只要你写了.value,那么你的数据就肯定是响应式的
ref的另外的误区
开发时候响应式数据怎么使用
- 如果你需要的是基本类型的数据,那么直接使用ref;
- 如果需要一个响应式对象,层级不深的,ref和reactive都是可以的;
- 如果需要一个响应式对象,层级很深的,reactive是推荐的;
上面的这个东西,就是原则;
如果你做的是表单相关的,表单数据收集回显,那么推荐你使用的reactive;
为什么这么建议呢,为什么不能够ref一把梭呢?
这主要就是因为ref是必须.value的;
你想象一下,一个表单当中有非常多的数据;
然后你大量使用ref,知道有volar可以给你补充.value,但是你的代码当中也是有非常多的.value;
这是真的不好看;
这不是一个强制性的原则;
回顾
ref要注意.value(template当中是不需要的,但是在javascript当中是需要的)
reactive要注意Object.assign
解构赋值的理解
let {name, age} = person
let name = person.name
let age = person.age
name和person.name,这TM是两个东西,知道的吗?
像是上面的代码,页面是不会修改的;
因为name和person.name是不一样的;
person.name这个是响应式数据;
name可不是哦
这个问题是什么?
从一个响应式对象,解构出来变量的时候,它不是响应式的;
怎么让响应式对象解构变成响应式
toRefs的作用
toRefs的作用,就是将reactive定义的响应式对象
,变成一个一个由ref所定义的响应式对象
;
这行代码的意思是什么?
将一个reactive定义的响应式对象,转变成为了一个上面的第一张图的样子;
就是ref定义的响应式对象,并且里面的每个元素都是ref定义的响应式对象的;
完成了这个步骤之后,我们的解构才发生作用的;
这样我们解构出来的name和age,才都是响应式的;
toRefs的小点
看上面的代码当中,当我们使用toRefs转换之后进行的解构,那么上面的代码当中的name.value和person.name是有关联的;
toRefs的总结
接收一个由reactive定义的响应式对象;
并且将响应式对象当中的每一组key-value都变成了新的对象,ref定义的响应式对象的;
所以一句话总结:reactive定义的响应式对象解构要使用toRefs;
toRef API
这个东西用得不是特别多的;
这张图的意思,就是我们将一个响应式对象的person当中的一个键age拎出来;
然后使用toRef包裹一下,然后就赋值给了nl;
打印nl就是下面的样子:
toRefs和toRef总结
toRefs和toRef都是将一个响应式对象当中的东西,解构拿出来,不仅仅是解构拿出来,而且解构出来的东西,还是响应式的;
computed计算属性评价
很有用的;
不管你是用vue2还是vue3都是很有用的;
computed计算属性的例子
这个例子的意思,就是使用v-model来进行数据绑定;
用户输入的是什么东西,就和firstName和lastName绑定;
根据用户输入的姓,根据用户输入的名,拼装成为一个姓名;
computed计算属性的使用场景是什么?
从上面的例子的场景,需求来看,计算属性好像是,没有什么用处的;
computed计算属性,本质上是让你的代码更好维护的;
给你一个新的需求,我希望用户输入的姓是zhang,用户输入的名是san,然后你是通过拼装字符串的,你是比较倔强的,你是认为你通过拼装字符串就可以实现这个需求了,你是认为不需要字符串的。
我是认为我可以打你的脸蛋子的;
我的需求是,我希望全名的这个部分是姓的部分是首字母大写的;
来吧,你来实现吧;
你可能的实现,就是下面的样子的;
firsName.slice(0, 1).toUpperCase() + firstName.slice(1)
就这一行代码,没有问题,你是实现了这个需求的;
但是你违背了一个原则:
原则就是:官方文档当中说了,模板当中要写的都是尽量简单的表达式;
你TM写的有点复杂了;
也就是说,这么长的表达式,就不应该出现的模板当中的;
vue2当中的计算属性是怎么写的
vue2当中的计算属性,是一个配置项的;
vue3当中的计算属性的写法
第一步,要从vue当中引入一个computed,这是一个函数
;
第二步,就是调用这个computed函数;
import {ref, computed} from 'vue'
let firstName = ref('zhang')
let lastName = ref('meng')
let fullName = computed(() => {
return firstName.value.slice(0, 1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value
})
计算属性的特点
就是计算属性的计算里头,依赖的数据,只要是发生了变化,那么它就会重新计算的;
你看看上面的代码,我是在模板当中使用了好几次计算属性的;
我在计算属性的内部我通过console.log(1)来看看到底,TMD是调用了几次计算的呢;
你会发现就TMD调用了1次;
计算属性是有缓存的
计算属性是有缓存的,方法是没有缓存的;
计算属性:只读的
上面的写的计算属性是只读的,这个意思就是说,计算属性的计算过程和方法是不可以修改的;
就是类似fullName = xxx;
计算属性到底是什么?
在上面的代码当中fullName是计算属性的,我们打印一下,然后就拿到了下面的东西:
你就会发现这个fullName是一个Ref定义的响应式数据
;
修改计算属性发现是只读的
怎么写让计算属性既能读也能改
<template>
<div class="person">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
全名:<span>{{ fullName }}</span> <br><br>
<button @click="changeFullName">将fullname修改成为yang-mi</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref, computed} from 'vue'
let firstName = ref('zhang')
let lastName = ref('meng')
let fullName = computed({
get() {
return firstName.value.slice(0, 1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value
},
set(val) {
const [str1, str2] = val.split('-')
firstName.value = str1
lastName.value = str2
}
})
function changeFullName() {
fullName.value = 'yang-mi'
}
</script>
<style scoped>
.person {
background-color: #75f4ae;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button {
margin: 0 5px;
}
</style>