【Vue3 第五章】reactive 系列

简介: 【Vue3 第五章】reactive 系列

数字化管理平台

Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus

权限系统-商城

个人博客地址

一、reactive()

reactive() 函数用于返回一个对象的响应式代理。与 ref() 函数定义响应式数据的异同点如下:

ref 函数和 reactive 函数都是用来定义响应式数据的。

ref 函数更适合定义基本数据类型(可接收基本数据类型和对象)

函数参数可以是基本数据类型,也可以接受对象类型

如果参数是对象类型时,其实底层的本质还是 reactive,系统会自动给 ref 传入的值进行转换

ref(1) -> reactive({value:1})
// ref函数只能操作浅层次的数据,把基本数据类型当作自己的属性值;深层次依赖于reactive

在 template 中访问,系统会自动添加 .value 。在 js 中需要手动 .value 进行访问

import { ref } from 'vue'
// 为基本数据类型添加响应式状态
const name = ref('Neo')
// 为复杂数据类型添加响应式状态
const state = ref({
  count: 0
})
// 打印name的值
console.log(name.value)
// 打印count的值
console.log(state.value.count)

ref 响应式原理是依赖于Object.defineProperty()的get()和set()的

reactive 函数更适合定义复杂的数据类型(json/arr/obj/map/set)

它的响应式是更加‘深层次’的(会影响对象内部所有嵌套的属性,所有的数据都是响应式的),底层本质是将传入的数据包装成一个 JavaScript Proxy,其行为表现与一般对象相似。不同之处在于 Vue 能够跟踪对响应式对象属性的访问与更改操作。因此不等于源对象,建议只使用响应式代理,避免使用原始对象。

import { reactive } from 'vue'
let list = reactive([])
const addData = () => {
  setTimeout(() => {
    let arr = ['banana','orange','peal']
    list.push(...arr)
    console.log(list)
  },1000)
}

参数必须是对象或者数组,如果要让对象的某个元素实现响应式时比较麻烦。需要使用 toRefs 函数处理

import { reactive, toRefs } from 'vue'
// 通过 reactive 定义响应式数据
const state = reactive({
    // 定义每一个表单控件的配置项:type类型、label文本、prop绑定字段 等信息
    items: [{
        label: "用户名",
        prop: "name",
        inputwidth: "100%",
    }, {
        password: true,
        label: "密码",
        prop: "pwd",
        inputwidth: "100%",
        rules: [{ required: true, message: "请输入密码", trigger: 'blur' }]
    }, {
        label: "手机号",
        prop: "phone",
        inputwidth: "100%",
        required: true,
        validateType: "phone"
    }],
    // 定义每一个表单绑定字段对应的信息(form表单数据信息)
    formData: {
        name: "",
        pwd: "",
        phone: ""
    },
    // form 元素配置信息
    options: {
        size: "small",
        formWidth: "35%",//表单占父元素的宽度
        labelWidth: "80px",//标签的长度
    },
})
// 通过 toRefs 获取 reactive 中的每一项属性的引用(js中调用使用 .value,template 中直接使用自动解析)
const { items, formData, options } = toRefs(state);
console.log(items,options)

获取数据值的时候直接获取,不需要加.value

import { reactive } from 'vue'
// 响应式状态
const state = reactive({
  count: 0
})
// 打印count的值
console.log(state.count)

二、readonly()

readonly() 函数接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。本身不能去修改值,但受原始对象改变的影响。

import { readonly } from "vue"
let obj = reactive({name:"Jack"})
let readObj = readonly(obj)
const change = () => {
  // 不能直接修改只读属性
  // readObj.name = "Lucy";
  // 受原始对象改变的影响
  obj.name = "David";
  console.log(obj,readObj);
}

只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。

三、shallowReactive()

reactive() 的浅层作用形式。和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。

import { reactive,shallowReactive } from "vue";
const stu = reactive({name:"Jack"})
const obj = shallowReactive({
  foo:{
    bar:{
      num:1
    }
  }
})
const change = () => {
  // reactive() 作用是深层次的,和shallowReactive() 一起使用时,会影响其数据变化
  stu.name = "David"
  // shallowReactive() 作用是浅层的,只能修改第一层的数据。深层次数据无法修改。但是会受reactive数据修改的影响。
  obj.foo.bar.num = 1000;
  console.log(obj)
}

四、shallowReadonly()

readonly() 的浅层作用形式。和 readonly() 不同,这里没有深层级的转换:只有根层级的属性变为了只读。属性的值都会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。同样会受原始对象数据改变的影响。

const state = shallowReadonly({
  foo: 1,
  nested: {
    bar: 2
  }
})
// 更改状态自身的属性会失败
state.foo++
// ...但可以更改下层嵌套对象
isReadonly(state.nested) // false
// 这是可以通过的
state.nested.bar++

五、isReactive() 和 isReadonly()

isReactive() 函数检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。

isReadonly() 函数检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。


相关文章
|
14天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
117 64
|
14天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
|
14天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
24 8
|
13天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
18 1
|
13天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
25 1
|
14天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
22天前
|
JavaScript 索引
Vue 3.x 版本中双向数据绑定的底层实现有哪些变化
从Vue 2.x的`Object.defineProperty`到Vue 3.x的`Proxy`,实现了更高效的数据劫持与响应式处理。`Proxy`不仅能够代理整个对象,动态响应属性的增删,还优化了嵌套对象的处理和依赖追踪,减少了不必要的视图更新,提升了性能。同时,Vue 3.x对数组的响应式处理也更加灵活,简化了开发流程。
|
1月前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
53 1
|
17天前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
31 0
|
17天前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
45 0