Vue数据代理如何实现

发布时间:2023-01-09 10:52:22 作者:iii
来源:亿速云 阅读:105

这篇文章主要介绍“Vue数据代理如何实现”,在日常操作中,相信很多人在Vue数据代理如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue数据代理如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一,前言

Vue 数据初始化流程中,数组类型的数据劫持是如何实现的,核心思路如下:

出于对性能的考虑,Vue 没有对数组采用 Object.defineProperty 进行递归劫持,而是对能够导致原数组变化的 7 个方法进行了拦截和重写,实现了对数组的数据劫持。

二,数据代理的实现

1,Vue 是如何操作数据的

在 Vue 中,是可以在外部直接通过 vm 实例进行数据访问和操作:

let vm = new Vue({
  el: '#app',
  data() {
    return { message: 'Hello Vue', obj: { key: "val" }, arr:[1,2,3]}
  }
});
console.log(vm.message)
console.log(vm.arr.push(4))

抛出问题:vm.message 等价于 $options.data.message,是如何实现的?

2,当前是如何操作数据的

当前代码,外部的 vm 实例只能拿到 vm. o p t i o n s ,拿到 d a t a 需要 v m . options,拿到 data 需要 vm. options,拿到data需要vm.options.data

// src/state.js#initData
function initData(vm) {
    let data = vm.$options.data;
    data = isFunction(data) ? data.call(vm) : data;
    observe(data);
    data.message
    data.arr.push(4); 
}

要想实现 vm.message 和 $options.data.message 等效

相当于将 vm 实例操作代理到 $options.data 上,即实现数据代理

3,数据代理的思路

为了让外部的 vm 实例能够拿到观测后的 data,将处理后的 data 直接挂载到 vm 上

// src/state.js#initData
function initData(vm) {
    let data = vm.$options.data;
    data = vm._data = isFunction(data) ? data.call(vm) : data;
    observe(data);
}

这样,vm 实例就能够在外部通过 vm._data.message 获取到 data.message

接下来,再做一次代理,将 vm 实例操作(vm.message),代理到 vm._data 上即可

4,数据代理的实现

通过 Object.defineProperty 对 _data 中的数据操作进行劫持

即:vm.message 在 vm 实例上取值时,将它代理到 vm._data 上取值

// src/state.js#initData
function initData(vm) {
    let data = vm.$options.data;
    data = vm._data = isFunction(data) ? data.call(vm) : data;
    observe(data);
    // 当 vm.message 在 vm 实例上取值时,将它代理到vm._data上去取
    for(let key in data){
        Proxy(vm, key, '_data')
    }
}
// src/state.js#Proxy
/**
 * 代理方法
 *  当取 vm.key 时,将它代理到 vm._data上去取
 * @param {*} vm        vm 实例
 * @param {*} key       属性名
 * @param {*} source    代理目标,这里是vm._data
 */
function Proxy(vm, key, source) {
    Object.defineProperty(vm, key, {
        get(){
            return vm[source][key]
        },
        set(newValue){
            vm[source][key] = newValue;
        }
    })
}

5,数据代理的测试

let vm = new Vue({
  el: '#app',
  data() {
    return { message: 'Hello Vue', obj: { key: "val" }, arr:[1,2,3]}
  }
});
console.log(vm)
console.log(vm.message)

Vue数据代理如何实现

观察打印结果:

获取 vm 实例时,会通过 get 方法将 _data 全部属性打印出来

当前 vm 实例上,包含 data 全部属性及对应的 get、set 方法

这样,就实现了数据代理:

当从 vm 实例取值时,就会被代理到 vm._data 取值

到此,关于“Vue数据代理如何实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. flask展示vue打包后的页面方法是什么
  2. 怎样搭建基于SpringBoot+Vue 的Web商城应用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue

上一篇:pytorch中nn.Flatten()函数如何使用

下一篇:react生命周期的类组件和函数组件怎么写

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》