Vue3 reactive响应式赋值页面不渲染的解决

目录
  • Vue3 reactive响应式赋值页面不渲染
    • 问题描述
    • 1.因数据结构而导致的未渲染解决方法
    • 2.因页面节点未加载导致页面未渲染解决方法
    • 3.因未指到具体点未渲染解决方法
  • Vue3 响应式原理-reactive
    • Reactivity模块基本使用
    • 编写reactive函数

Vue3 reactive响应式赋值页面不渲染

问题描述

//声明变量
let data = reactive([])
http().then(res=>{
  data = res.data
  console.log(data)
})
//data数据更新,页面没有渲染

1.因数据结构而导致的未渲染解决方法

依旧是reactive,可以在外面包一层

//声明
let state = reactive({
  data:[]
})
//赋值
state.data= res.data

改为ref赋值

//声明
let data = ref([])
//赋值
data.value = res.data

2.因页面节点未加载导致页面未渲染解决方法

import {nextTick} from 'vue'
const func = async ()=>{
    await nextTick()
    state.data= res.data
}

3.因未指到具体点未渲染解决方法

const state = reactive({
    data:[{
        name:'tom',
        age:3
    },...]
})
const func = async ()=>{
    //state.data.forEach(item=>{
    //    item.age = 4//未生效
    //})
    state.data.forEach((item,index)=>{
        state.data[index].age = 4
    })
}

Vue3 响应式原理-reactive

Reactivity模块基本使用

<div id="app"></div>
<script src="./reactivity.global.js"></script>
<script>
    const { reactive, effect, shallowReactive, shallowReadonly, readonly } = VueReactivity;
    // let state = reactive({ name: 'jw', age: 30 });
    // const state = shallowReactive({ name: 'jw', age: 30 })
    // const state = readonly({ name: 'jw', age: 30 })
    const state = reactive({ name: 'jw', age: 30})
    effect(() => { // 副作用函数 (effect执行渲染了页面)
        app.innerHTML = state.name + '今年' + state.age + '岁了'
    });
    setTimeout(() => {
        state.age++;
    }, 1000)
</script>

reactive方法会将对象变成proxy对象, effect中使用reactive对象时会进行依赖收集,稍后属性变化时会重新执行effect函数。

编写reactive函数

const reactiveMap = new WeakMap(); // 缓存列表
const mutableHandlers: ProxyHandler<object> = {
    get(target, key, receiver) {
        // 等会谁来取值就做依赖收集
        const res = Reflect.get(target, key, receiver);
        return res;
    },
    set(target, key, value, receiver) {
        // 等会赋值的时候可以重新触发effect执行
        const result = Reflect.set(target, key, value, receiver);
        return result;
    }
}
function createReactiveObject(target: object, isReadonly: boolean) {
    if (!isObject(target)) {
        return target
    }
    const exisitingProxy = reactiveMap.get(target); // 如果已经代理过则直接返回代理后的对象 
    if (exisitingProxy) {
        return exisitingProxy;
    }
    const proxy = new Proxy(target, mutableHandlers); // 对对象进行代理
    reactiveMap.set(target,proxy)
    return proxy;
}

这里必须要使用Reflect进行操作,保证this指向永远指向代理对象

let school = {
    name:'zf',
    get num(){
        return this.name;
    }
}
let p = new Proxy(school,{
    get(target, key,receiver){
        console.log(key);
        // return Reflect.get(target,key,receiver)
        return target[key]
    }
})
p.num

将对象使用proxy进行代理,如果对象已经被代理过,再次重复代理则返回上次代理结果。 那么,如果将一个代理对象传入呢?

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vue3中的响应式原理-effect

    目录 effect的基本实现 依赖收集 触发更新 分支切换与cleanup 停止effect 调度执行 深度代理 总结 effect的基本实现 export let activeEffect = undefined;// 当前正在执行的effect class ReactiveEffect {     active = true;     deps = []; // 收集effect中使用到的属性     parent = undefined;     constructor(public fn

  • 浅析一下Vue3的响应式原理

    目录 Proxy Reflect 举个例子 reactive effect track trigger Proxy Vue3 的响应式原理依赖了 Proxy 这个核心 API,通过 Proxy 可以劫持对象的某些操作. const obj = { a: 1 }; const p = new Proxy(obj, {   get(target, property, receiver) {     console.log("get");     return Reflect.get(tar

  • vue3响应式Object代理对象的读取示例详解

    目录 正文 读取属性 xx in obj for ... in 正文 从这一章开始,作者将更新深入的讲解响应式,尤其是vue3响应式的具体的实现.其实在前面一章,如果你仔细阅读,你是可以实现一个简单的响应式函数的,类似于@vue/reactive,当然那只是个demo,是个玩具,我能不能在生产环境上去使用的,它差了太多功能和边界条件. 现在,我们才是真正的深入@vue/reactive. 在vue中,obj.a是一个读取操作,但是仔细想来,读取这个操作很宽泛. obj.a // 访问一个属性 '

  • Vue3中的ref和reactive响应式原理解析

    目录 1 ref 2 isref判断是不是一个ref对象 3 shallowref创建一个跟踪自身.value变化的 ref,但不会使其值也变成响应式的 4 triggerRef 5 customRef 6 reactive用来绑定复杂的数据类型 7 readonly 8 shallowReactive 9toRef 10toRefs 11toRaw Vue3系列4--ref和reactive响应式 本节主要介绍了响应式变量和对象,以及变量和对象在响应式和非响应式之间的转换. 1 ref 接受一

  • Vue3 Reactive响应式原理逻辑详解

    目录 前言 一.怎么实现变量变化 二.怎么实现变量变化 三.将多个dep存储在Map中 四.将多个object的depsMap继续存储起来 五.核心 六.源码解析(TypeScript) 前言 本篇文章主要讲解vue响应式原理的逻辑,也就是vue怎么从最开始一步步推导出响应式的结构框架. 先从头构建一个简单函数推导出Vue3的Reactive原理,最后再进行源码的验证. 一.怎么实现变量变化 怎么实现变量变化,相关依赖的结果也跟着变化 当原本price=5变为price=20后total应该变为

  • vue3响应式Proxy与Reflect的理解及基本使用实例详解

    目录 正文 理解Proxy与Reflect Proxy Reflect 实践示例 正文 在第四章中,作者讲述了Vue.js中响应式系统的设计与实现,这一块其实是整个框架的基石,也是MVVM中,ViewModel(VM)的重要组成部分. 其实在上一章中我已经感觉很难了,有一些操作作者也只是几笔带过,却很值得我们思考.这一张中,我们将目光着重于响应式数据本身,来完善上一章中我们的demo. 理解Proxy与Reflect vue3的响应式离不开Proxy,说到Proxy则离不开Reflect.这两个

  • Vue3 reactive响应式赋值页面不渲染的解决

    目录 Vue3 reactive响应式赋值页面不渲染 问题描述 1.因数据结构而导致的未渲染解决方法 2.因页面节点未加载导致页面未渲染解决方法 3.因未指到具体点未渲染解决方法 Vue3 响应式原理-reactive Reactivity模块基本使用 编写reactive函数 Vue3 reactive响应式赋值页面不渲染 问题描述 //声明变量 let data = reactive([]) http().then(res=>{   data = res.data   console.log

  • vue3 reactive响应式依赖收集派发更新原理解析

    目录 proxy 依赖收集 currentEffect 派发更新 总结 proxy vue3的响应式实现依旧是依赖收集与派发更新,本节乃至后面涉及的代码都是经过简化,文章目的是讲解原理,直接贴源码会很枯燥 vue3已经从Object.property更换成Proxy,Proxy相比于前者可以直接监听对象数组,对于深层次的对象和数组,会把触发对应getter,然后去递归进行依赖收集,并不是直接像vue2暴力那样递归,总体而言性能更好 对reactive传进来的对象进行Proxy进行劫持在内部进行依

  • Vue3关于响应式数据类型详解(ref、reactive、toRef、及toRefs)

    目录 ref reactive toRef() toRefs() ref 接受一个内部值,返回一个响应式的.可更改的 ref 对象,此对象只有一个指向其内部值的 property .value. 类型 function ref<T>(value: T): Ref<UnwrapRef<T>> interface Ref<T> { value: T } 详细信息 ref 对象是可更改的,也就是说你可以为 .value 赋予新的值.它也是响应式的,即所有对 .va

  • Vue3 的响应式和以前有什么区别,Proxy 无敌?

    前言 大家都知道,Vue2 里的响应式其实有点像是一个半完全体,对于对象上新增的属性无能为力,对于数组则需要拦截它的原型方法来实现响应式. 举个例子: let vm = new Vue({ data() { return { a: 1 } } }) // ❌ oops,没反应! vm.b = 2 let vm = new Vue({ data() { return { a: 1 } }, watch: { b() { console.log('change !!') } } }) // ❌ oo

  • 一文带你了解vue3.0响应式

    目录 使用案例 reactive API相关的流程 reactive createReactiveObject 创建响应式对象 mutableHandlers 处理函数 get函数 get函数的的调用时机 track 收集依赖 set函数 trigger 分发依赖 get和副作用渲染函数关联 副作用渲染函数的执行过滤 结尾 我们知道Vue 2.0是利用Ojbect.defineProperty对对象的已有属性值的读取和修改进行劫持,但是这个API不能监听对象属性的新增和删除,此外为了深度劫持对象

  • 40行代码把Vue3的响应式集成进React做状态管理

    前言 vue-next是Vue3的源码仓库,Vue3采用lerna做package的划分,而响应式能力@vue/reactivity被划分到了单独的一个package中. 如果我们想把它集成到React中,可行吗?来试一试吧. 使用示例 话不多说,先看看怎么用的解解馋吧. // store.ts import { reactive, computed, effect } from '@vue/reactivity'; export const state = reactive({ count:

  • vue3常用响应式对象的api,你全用过了吗

    目录 Ⅰ. ref.reactive ( 递归监听 ) Ⅱ. isRef.isReactive ( 判断 ) Ⅲ. toRef 和 toRefs ( 解构 ) Ⅳ. toRaw . markRaw ( 解除代理) Ⅴ. unref ( 拷贝 ) Ⅵ. shallowRef .shallowReactive( 非递归监听 ) Ⅶ. triggerRef (强制更新) 总结 Ⅰ. ref.reactive ( 递归监听 ) import {ref,reactive} from 'vue'; setu

随机推荐