-
reactive:复杂类型的响应式的数据对象。
等价于 vue 2.x 中的 Vue.observable() 函数
在对象属性发生变化时,模版是可以 响应更新渲染的:
const obj = reactive({name:'dream'})
-
ref :定义基础类型的响应式数据
Vue2.x是通过Object.defineProperty()封装的
- 不能很好的监听数组和对象的变化
vue3当中的ref通过
proxy
对数据进行封装- 监听整个对象的变化
- 所谓代理,可以理解成,在目标对象之前架设一层’拦截’,外界对该目标对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写
当数据变化时,自动触发视图更新
import {ref,reactive} from 'vue' let text = ref('触发axios') //基本数据类型 let obj = ref({name:'zxc'}) //传入一个复杂数据类型 let userInfo = reactive({name:'zxc'}) console.log(text) //返回一个RefImpl类型数据 console.log(userInfo) //返回一个通过Proxy类型数据 console.log(text.value) //使用value属性获取对应值 console.log(obj,obj.value) //返回一个RefImpl类型数据,其value值是一个通过Proxy类型数据,实际上底层是调用reactive进行处理,可以用obj.value.name来访问 console.log(isRef(userInfo),isRef(obj),isRef(text)) //false true true
ref获取dom元素
<template> <div> <div class="box" ref="boxEle" ></div> </div> </template> <script> import {onMounted, ref} from "vue"; export default { name: "useAxios", setup(props) { const boxEle = ref(null) console.log(boxEle) onMounted(()=>{ // document.querySelector('.box').style.background = 'hotpink' boxEle.value.style.background = 'darkgreen' }) return { boxEle } }, } </script>
-
isRef()和isReactive():判断一个值是否是ref(基础响应式)对象
const name = ref('dream') isRef(name) //true const userInfo = reactive({name:'zhangsan',age:23}) isReactive(userInfo) //true
-
unRef():一个语法糖
-
二者等价
const data = isRef(obj) ? obj.value : obj
const data = unref(obj)
import {ref,reactive} from 'vue' let text = ref('触发axios') //基本数据类型 let obj = ref({name:'zxc'}) //传入一个复杂数据类型 let userInfo = reactive({name:'zxc'}) console.log(unref(text), isRef(text) ? text.value : text) console.log(unref(obj), isRef(obj) ? obj.value : obj) console.log(unref(userInfo), isRef(userInfo) ? userInfo.value : userInfo)
-
-
toRef()和toRefs()
1、toRefs()
- 把reactive每个属性都转化为ref响应式数据
- 函数可以将 reactive() 创建出来的响应式复杂数据(Proxy代理的),转换为普通的响应式数据(ObjectRefImpl对象)
- 这个对象上的每个属性节点,都是 ref() 类型的响应式数据
- 代理响应式数据,从 proxy({name:‘dream’,age:18}) 变成 proxy({name:proxy({value:‘dream’’}),age:proxy({value:18})})
2、toRef()
- 是把reactive复杂对象的某个属性变成一个单独的ref来进行使用
- 取一个不存在的属性并具备响应式特性时
- 从toRefs里面读取一个不存在的属性时,是undefined,而没有一个默认的值
- const age = toRef(userInfo,‘age’)
- age.value = 18
- 从
userInfo
中取age
属性,如果age
不存在就给一个默认值,然后可进行赋值
- 不建议,最好提前给默认值
import {ref,reactive,isRef,isReactive} from 'vue' let text = ref('触发axios') //基本数据类型 let obj = ref({name:'zxc',age:13}) //传入一个复杂数据类型 let userInfo = reactive({name1:'zxc',age1:13}) //isReactive的使用 console.log(isReactive(userInfo),isReactive(obj),isReactive(text)) //true false false //对其value属性解构(ref定义复杂类型的) let {name, age} = obj.value console.log(name, age) // 'zxc' 13 //toRefs的使用,用在对reactive复杂类型的内部所有属性装换为ref普通数据类型 let {name1, age1} = toRefs(userInfo) console.log(age1.value, name1.value) // 13 'zxc' //toRef的使用,用在对reactive复杂类型的某个属性装换为ref普通数据类型 console.log(isRef(toRef(userInfo.name1)), toRef(userInfo,'name1'),toRef(userInfo,'name1').value) //true //toRef,和toRefs,对于本身是ref数据也会转换成 ObjectRefImpl对象,本身无意义(其也无法给key的值) console.log(isRef(toRef(text)), toRef(text)) //true Object console.log(isRef(toRef(obj)), toRef(obj)) // true ObjectRefImpl对象 // let {name,age} = toRefs(obj) //undefined undefined
-
isPorxy():判断是否是被Proxy包装
let text = ref('触发axios') //基本数据类型 let obj = ref({name:'zxc',age:13}) //传入一个复杂数据类型 let userInfo = reactive({name1:'zxc',age1:13}) console.log(isProxy(text),isProxy(obj),isProxy(userInfo),isProxy(toRef(userInfo,'name1'))) //false false true false
-
readonly和isReadOnly():
-
readonly:设置属性权限为只读
-
isReadOnly()**判断是否只读
//useReadOnly.js import {readonly,ref,isReadOnly} from 'vue' export const useReadOnly = () => { const value = ref('private value') return { privateValue:readonly(value), //设置只读 } } //test.vue import {isReadOnly} from 'vue' import {useReadOnly} from './useReadOnly.js' setup(){ const {privateValue} = useReadOnly() console.log(privateValue.value) //private value privateValue = 'my value' //报错提示,尝试修改只读选项 }
-