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

专业独立门户网站建设/企业培训机构排名

专业独立门户网站建设,企业培训机构排名,做网站超链接,wordpress 国际化 mo下面,我们来系统的梳理关于 ref() 与 reactive() 的基本知识点: 一、响应式编程核心概念 1.1 什么是响应式编程? 响应式编程是一种声明式编程范式,它使数据变化能够自动传播到依赖它的代码部分。在 Vue 中,响应式系统…

下面,我们来系统的梳理关于 ref() 与 reactive() 的基本知识点:


一、响应式编程核心概念

1.1 什么是响应式编程?

响应式编程是一种声明式编程范式,它使数据变化能够自动传播到依赖它的代码部分。在 Vue 中,响应式系统实现了:

  • 数据驱动视图:数据变化自动更新DOM
  • 依赖追踪:自动跟踪数据依赖关系
  • 高效更新:最小化不必要的DOM操作

1.2 Vue 响应式系统演进

版本响应式实现特点
Vue 2Object.defineProperty拦截getter/setter,不支持数组索引变化
Vue 3Proxy API全面拦截对象操作,支持数组/集合类型

二、reactive() 深度解析

2.1 基本使用

import { reactive } from 'vue'const state = reactive({count: 0,user: {name: 'Alice',profile: {level: 5}}
})// 修改属性
state.count++ // 触发更新
state.user.name = 'Bob' // 深层响应

2.2 实现原理

Get
Set
Delete
reactive对象
Proxy拦截器
操作类型
追踪依赖
触发更新
收集当前effect
通知相关effect

2.3 核心特性

  • 深层响应:嵌套对象自动转为响应式
  • 类型保留:Array/Map/Set等特殊类型保持原型方法
  • 引用稳定:reactive() 返回同一个代理对象
    const obj = {}
    const proxy1 = reactive(obj)
    const proxy2 = reactive(obj)
    console.log(proxy1 === proxy2) // true
    

2.4 局限性

// 1. 原始值无法使用
const count = reactive(0) // 无效// 2. 属性解构丢失响应性
const { count } = state // 非响应式// 3. 新属性添加需要特殊处理
const state = reactive({})
state.newProp = 'value' // 非响应式// 正确添加响应式属性
import { set } from 'vue'
set(state, 'newProp', 'value')

三、ref() 深度解析

3.1 基本使用

import { ref } from 'vue'// 创建ref
const count = ref(0)
const user = ref({ name: 'Alice' })// 模板中使用
// <div>{{ count }}</div> 自动解包.value// JS中访问
console.log(count.value) // 0
count.value++ // 触发更新

3.2 实现原理

// 简化的ref实现
function ref(value) {const refObject = {get value() {track(refObject, 'value') // 依赖收集return value},set value(newVal) {value = newValtrigger(refObject, 'value') // 触发更新}}return refObject
}

3.3 核心特性

  • 包装原始值:使基本类型具有响应性
  • 模板自动解包:在模板中无需.value
  • 响应式替换:整个对象可替换
    const user = ref({ name: 'Alice' })// 替换整个对象
    user.value = { name: 'Bob' } // 保持响应性
    

3.4 ref 的特殊用法

// DOM元素引用
const inputRef = ref(null)onMounted(() => {inputRef.value.focus()
})// 组件引用
<ChildComponent ref="child" />const child = ref(null)
child.value.doSomething()// 函数式ref
<div :ref="(el) => { /* 操作元素 */ }"></div>

四、ref() vs reactive() 对比

4.1 核心差异对比

特性ref()reactive()
包装对象RefImpl 对象Proxy 对象
值访问需要 .value直接访问
原始值支持
深层响应
类型保留完整保留部分特殊处理
解构响应性支持解构属性需要toRefs
整体替换❌ (会破坏响应性)

4.2 使用场景指南

场景推荐说明
基本类型值ref字符串、数字等
复杂对象reactive表单对象、状态对象
组件状态reactive逻辑相关的状态组
模板引用refDOM元素/组件实例
函数参数ref避免响应式对象解构问题
组合函数返回值ref更灵活的响应式值

4.3 性能考量

  • 创建开销:reactive() 的 Proxy 创建比 ref() 稍重
  • 内存占用:ref() 有额外包装对象开销
  • 更新效率:两者更新效率相当
  • 最佳实践
    // 大型对象使用reactive更高效
    const bigData = reactive(largeDataset)// 独立值使用ref
    const loading = ref(false)
    

五、响应式系统高级用法

5.1 响应式转换工具

import { toRef, toRefs, isRef, isReactive, isProxy } from 'vue'const state = reactive({ count: 0 })// 对象属性转为ref
const countRef = toRef(state, 'count')// 整个对象转为ref集合
const refs = toRefs(state) // { count: Ref<number> }// 类型检查
console.log(isRef(countRef)) // true
console.log(isReactive(state)) // true
console.log(isProxy(state)) // true

5.2 浅层响应式

import { shallowReactive, shallowRef } from 'vue'// 浅层reactive:只响应根级属性
const shallowState = shallowReactive({nested: { value: 1 } // 内部非响应
})// 浅层ref:不自动解包内部值
const shallowObj = shallowRef({ count: 0 })
shallowObj.value.count++ // 不会触发更新

5.3 自定义Ref

import { customRef } from 'vue'function useDebouncedRef(value, delay = 200) {let timeoutreturn customRef((track, trigger) => {return {get() {track()return value},set(newValue) {clearTimeout(timeout)timeout = setTimeout(() => {value = newValuetrigger()}, delay)}}})
}// 使用
const text = useDebouncedRef('', 500)

5.4 响应式工具函数

import { markRaw, readonly, watchEffect } from 'vue'// 1. 标记非响应式对象
const nonReactiveObj = markRaw({ shouldNotBeTracked: true })// 2. 创建只读响应式对象
const readOnlyState = readonly(state)// 3. 响应式副作用
watchEffect(() => {console.log(`Count: ${state.count}`) // 自动追踪依赖
})

六、响应式原理深度剖析

6.1 依赖收集与触发

组件渲染 响应式对象 依赖管理器 访问属性 track(收集当前effect) 记录依赖关系 数据变化时 trigger(通知更新) 执行effect更新 组件渲染 响应式对象 依赖管理器

6.2 Proxy 拦截器实现

const reactiveHandlers = {get(target, key, receiver) {track(target, key) // 收集依赖const res = Reflect.get(target, key, receiver)if (isObject(res)) {return reactive(res) // 递归响应式}return res},set(target, key, value, receiver) {const oldValue = target[key]const result = Reflect.set(target, key, value, receiver)if (hasChanged(value, oldValue)) {trigger(target, key) // 触发更新}return result}// 省略deleteProperty/has等其他拦截
}

6.3 响应式系统三大核心

  1. Effect(副作用)

    let activeEffect
    class ReactiveEffect {run() {activeEffect = thisthis.fn() // 执行过程中收集依赖}
    }
    
  2. Dep(依赖集合)

    class Dep {constructor() {this.subscribers = new Set()}depend() {if (activeEffect) this.subscribers.add(activeEffect)}notify() {this.subscribers.forEach(effect => effect.run())}
    }
    
  3. TargetMap(目标映射)

    const targetMap = new WeakMap()function track(target, key) {if (!activeEffect) returnlet depsMap = targetMap.get(target)if (!depsMap) targetMap.set(target, (depsMap = new Map()))let dep = depsMap.get(key)if (!dep) depsMap.set(key, (dep = new Dep()))dep.depend()
    }
    

七、最佳实践与性能优化

7.1 选择指南

场景推荐替代方案原因
独立原始值refreactive更简洁
相关状态组reactive多个ref逻辑聚合
组件propsref-标准做法
全局状态reactiveref结构化数据
需要解构ref + toRefsreactive保持响应性

7.2 性能优化策略

  1. 避免大型响应式对象

    // 避免
    const hugeObj = reactive(/* 大型数据集 */)// 推荐:使用shallowRef或手动管理
    const data = ref({})
    data.value = largeDataset // 替换而非响应式
    
  2. 减少不必要的响应式

    // 静态配置无需响应式
    const config = markRaw({itemsPerPage: 10,maxRetries: 3
    })
    
  3. 合理使用计算属性

    const sortedList = computed(() => [...list.value].sort((a, b) => a.id - b.id)
    )
    
  4. 批量更新优化

    import { nextTick } from 'vue'const updateMultiple = () => {state.a = 1state.b = 2nextTick(() => {// DOM更新后执行})
    }
    

7.3 响应式数据模式

// 组合式函数模式
export function useCounter(initial = 0) {const count = ref(initial)const increment = () => count.value++const decrement = () => count.value--return {count,increment,decrement}
}// 在组件中使用
const { count, increment } = useCounter()

八、常见问题与解决方案

8.1 响应性丢失问题

问题:解构导致响应性丢失

const state = reactive({ count: 0 })
const { count } = state // 失去响应性

解决方案

// 1. 使用toRefs
const { count } = toRefs(state)// 2. 直接访问原对象
state.count// 3. 使用computed
const count = computed(() => state.count)

8.2 循环引用问题

问题:对象循环引用导致无限递归

const obj = reactive({})
obj.self = obj // 循环引用

解决方案

// 1. 避免循环引用
// 2. 使用markRaw切断响应链
obj.self = markRaw(obj)

8.3 数组操作问题

问题:直接索引修改数组不触发更新

const list = reactive([1, 2, 3])
list[0] = 9 // 不会触发更新

解决方案

// 1. 使用变异方法
list.splice(0, 1, 9)// 2. 整个替换
list.value = [9, 2, 3]// 3. 使用Vue.set (Vue 3中为set)
import { set } from 'vue'
set(list, 0, 9)
http://www.lryc.cn/news/580660.html

相关文章:

  • 五道口网站建设公司/网店代运营正规公司
  • 有没有99块钱做网站/江门网站定制多少钱
  • 哪家公司做网站好/西地那非片的正确服用方法
  • 深圳微网站建设公司/网络营销是什么
  • 湛江网站设计公司/广州seo技术外包公司
  • 搜狐网站建设的建议/杭州千锋教育地址
  • 推荐网站建设的书/googleseo优化
  • 建一个小型的购物网站服务器一年要多少钱/市场调研怎么做
  • 抖音代运营赚钱吗/seo运营是什么
  • 外行学网页制作与网站建设从入门到精通/发布软文是什么意思
  • 非公企业党建网站建设/全网推广的方式
  • 工信部网站icp备案/舆情信息网
  • 可以做网站的编程有什么软件/关键词优化排名软件流量词
  • 做网站和网页的目的和作用/百度导航下载2020新版语音
  • 网站建设工作成果怎么写/网络推广引流是做什么工作
  • 如何做自己官方网站/凡科建站怎么样
  • 当当网网站建设/新的网络推广方式
  • 1688开山网一起做网站/seo搜索引擎是什么意思
  • 网站管理后台 模板/谷歌推广外包
  • 利用css技术做网站的思路/西安百度推广运营公司
  • 苏州做网站最好公司有哪些/百度快照查询
  • 重庆做网站制作的公司/常见的网络推广方法有哪些
  • 企业邮箱怎么注册的/百度关键词seo排名
  • 企业网站主页设计模板/如何优化搜索引擎
  • 中和华丰建设有限责任公司网站/教育机构排名
  • wordpress手游/seo公司推广
  • 网站设计师岗位职责/宁德市教育局官网
  • 重庆智能网站建设价格/危机公关处理
  • 手机制作表格/seo推广是什么
  • 佛山市seo广告优化工具/搜索引擎优化关键词