手写vue2.0源码二之data获取方式

文章类型:Vue

发布者:hp

发布时间:2023-05-24

在vue里里面,我们通常通过this.xxx就能拿到数据,而vue里面的data是一个函数,今天,整理一下实现方式

一:我们先定义入口函数,接收传递过来的参数,并且暴露出去

/*
定义个入口函数
将参数传进去
这也是为撒叫options API
就是需要就添加进去
*/

function Vue(options){
    console.log(options)
    //调用初始化方法
    this.init(options)
 }

二:在组件中进行new Vue()实例化这个方法和传递对象属性

import Vue from 'vue'
console.log(Vue)
let vm=new Vue({
    el:'#app',
    data(){
        return{
            msg:456        }
    }
})

三:我们就进行需要定义一个初始化方法,携带传递的数据

 this.init(options)
   * 
  * @param {*} options
  * 定义一个初始化方法  
  */
 Vue.prototype.init=function(options){
    //保存实例
    let vm=this
    vm.$options=options
    /*定义初始化数据方法
    传递实例
    */
   initState(vm)
 }

四:在初始化方法里面进行初始化数据方法调用,说白了就是所有数据处理函数入口

/**
 * 定义一个init数据文件
 * 专门处理数据相关初始化
 * 
 */
 function initState(vm){
    console.log(vm)
    let options=vm.$options
    /*
    进行判断
    需要那些api实例化
    有data  computed  watcher
    */
   if(options.data){
    //定义初始化数据方法
        initData(vm)
   }

}

四:传递的是对象,会携带各种各样的api,那么我们就要进行拆分,独立函数来独立响应的逻辑,说白了就是Hook

//定义初始化方法
 function initData(vm){
    /**
     * 这里会赋值一份data数据,
     * 主要是保持数据的原始性,避免对数据进行破坏
     * 采取复制一份,操作拷贝的值
     */
     let data=vm.$options.data
    data=vm._data= typeof vm.$options.data=='function' ? data.call(vm) : data || {}

    /*
    对象进行遍历转换
    */
   for(let k in data){
    proxyData(vm,'_data',key)
   }
}

五:保留传递过来的属性,进行拷贝_data进行操作,实际操作这个拷贝的值,进行递归遍历调用,然后进行处理数据,来解决vm._data.xxx变化成vm.xxx

/*
主要是进行数据代理
通过vm._data.xx变成vm.xxx效果
*/

function proxyData(vm,target,key){
    Object.defineProperty(vm,key,{
        get(){
            /*
            通过get属性 读取对象的值重新返回
            */
            return vm[target][key]
        },
        set(newVal){
            /*
            通过set属性 设置对象的值重新返回
            */
            vm[target][key]=newVal
        }
    })
}

六:通过 Object.defineProperty说白了就是遍历去给每个属性进行一次返回和修改,通过对象[][]方式进行返回,手动进行配置返回,这样就可以实现vm.xxx

console.log('vm')
console.log(vm.msg)
//vm
/*
ƒ Vue(options){
    console.log(options)
    //调用初始化方法
    this.init(options)
 }
 */
 // 456