vue基础之data
使用
调用data
onLoad(option) {
    _self = this;
    _self.$data.xxxx = "te";
}
绑定节点
元素~~~~
<input @click="categoryChange" :data-id="item.id" />
方法
methods: {
    tabSelect(e) {
        this.TabCur = e.currentTarget.dataset.id;
    },
}
双向绑定原理
https://www.cnblogs.com/wangjiachen666/p/9883916.html
原理
Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新。
也就是说:
输入框内容变化时,data 中的数据同步变化。即 view => model 的变化。
data 中的数据变化时,文本节点的内容同步变化。即 model => view 的变化。
使数据对象变得“可观测”
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
依赖收集
完成了数据的'可观测',即我们知道了数据在什么时候被读或写了,那么,我们就可以在数据被读或写的时候通知那些依赖该数据的视图更新了,为了方便,我们需要先将所有依赖收集起来,一旦数据发生变化,就统一通知更新。其实,这就是典型的“发布订阅者”模式,数据变化为“发布者”,依赖对象为“订阅者”。
订阅者Watcher
订阅者Watcher 是一个 类,在它的构造函数中,定义了一些属性:
vm:一个Vue的实例对象;
exp:是node节点的v-model或v-on:click等指令的属性值。如v-model="name",exp就是name;
cb:是Watcher绑定的更新函数;
总结
实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。
代码
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1 id="name"></h1>
    <input type="text">
    <input type="button" value="改变data内容" onclick="changeInput()">
<script src="observer.js"></script>
<script src="watcher.js"></script>
<script>
function myVue (data, el, exp) {
this.data = data;
observable(data);                      //将数据变的可观测
el.innerHTML = this.data[exp];           // 初始化模板数据的值
new Watcher(this, exp, function (value) {
el.innerHTML = value;
});
return this;
}
var ele = document.querySelector('#name');
var input = document.querySelector('input');
var myVue = new myVue({
    name: 'hello world'
}, ele, 'name');
//改变输入框内容
input.oninput = function (e) {
    myVue.data.name = e.target.value
}
//改变data内容
function changeInput(){
    myVue.data.name = "难凉热血"
}
</script>
</body>
</html>
observer.js
  /**
     * 把一个对象的每一项都转化成可观测对象
     * @param { Object } obj 对象
     */
    function observable (obj) {
        if (!obj || typeof obj !== 'object') {
            return;
        }
        let keys = Object.keys(obj);
        keys.forEach((key) =>{
            defineReactive(obj,key,obj[key])
        })
        return obj;
    }
    /**
     * 使一个对象转化成可观测对象
     * @param { Object } obj 对象
     * @param { String } key 对象的key
     * @param { Any } val 对象的某个key的值
     */
    function defineReactive (obj,key,val) {
        let dep = new Dep();
        Object.defineProperty(obj, key, {
            get(){
                dep.depend();
                console.log(`${key}属性被读取了`);
                return val;
            },
            set(newVal){
                val = newVal;
                console.log(`${key}属性被修改了`);
                dep.notify()   //数据变化通知所有订阅者
            }
        })
    }
    class Dep {
    constructor(){
        this.subs = []
    }
    //增加订阅者
    addSub(sub){
        this.subs.push(sub);
    }
    //判断是否增加订阅者
    depend () {
        if (Dep.target) {
            this.addSub(Dep.target)
        }
    }
    //通知订阅者更新
    notify(){
        this.subs.forEach((sub) =>{
            sub.update()
        })
    }
}
Dep.target = null;
watcher.js
  class Watcher {
        constructor(vm,exp,cb){
            this.vm = vm;
            this.exp = exp;
            this.cb = cb;
            this.value = this.get();  // 将自己添加到订阅器的操作
        }
        get(){
            Dep.target = this;  // 缓存自己
            let value = this.vm.data[this.exp]  // 强制执行监听器里的get函数
            Dep.target = null;  // 释放自己
            return value;
        }
        update(){
            let value = this.vm.data[this.exp];
            let oldVal = this.value;
            if (value !== oldVal) {
                this.value = value;
                this.cb.call(this.vm, value, oldVal);
            }
    }
}
vue基础之data的更多相关文章
- vue 基础-->进阶 教程(1): 基础(数据绑定)
		第一章 建议学习时间4小时 课程共3章 前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零 ... 
- vue 基础-->进阶 教程(2): 指令、组件
		第二章 建议学习时间4小时 课程共3章 前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零 ... 
- vue 基础-->进阶 教程(3):组件嵌套、组件之间的通信、路由机制
		前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零开始,教给大家vue的基础.高级操作.组件 ... 
- vue基础学习(二)
		02-01 vue事件深入-传参.冒泡.默认事件 <div id="box"> <div @click="show2()"> < ... 
- vue基础特性
		在这里我们主要是讲解一些vue实例的属性和一些基础的指令 vue实例属性: 其实和我们之前所学的对象的属性是相似的东西 vue的基础指令: 对于指令,大家可能之前么有接触过相关的概念,其实大家可以这样 ... 
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十八║Vue基础: 指令(下)+计算属性+watch
		回顾 今天来晚辣,给公司做了一个小项目,一个瀑布流+动态视频控制的DEMO,有需要的可以联系我,公司的项目就不对外展示了(一个后端程序员真的要干前端了哈哈哈). 书接上文,昨天正式的开始了Vue的代码 ... 
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十九║Vue基础: 样式动态绑定+生命周期
		回顾 哈喽大家好,前后端分离系列文章又开始了,今天周一,还是感谢大家花时间来观看我写的博客,周末呢,没有写文章,但是也没有闲着,主要是研究了下遗留问题,看过之前文章的应该知道,之前的在AOP使用Red ... 
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明
		缘起 新的一天又开始啦,大家也应该看到我的标题了,是滴,Vue基础基本就到这里了,咱们回头看看这一路,如果你都看了,并且都会写了,那么现在你就可以自己写一个Demo了,如果再了解一点路由,ajax请求 ... 
- Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令
		自学vue框架,每天记录重要的知识点,与大家分享!有不足之处,希望大家指正. 本篇将讲述:vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令 前期学习基础,使用vue. ... 
随机推荐
- EFLAGS寄存器(标志寄存器)
			这篇文章不是从0开始的,前面还有一些汇编基础指令以及进制,我都没写,时间问题,还是今天空闲,我才想补一下博文,后面我陆续会把前面知识点渐渐补上.我不会重0基础讲起,中间会以.汇编.C.C++交叉的形式 ... 
- XGBoost 完整推导过程
			参考: 陈天奇-"XGBoost: A Scalable Tree Boosting System" Paper地址: <https://arxiv.org/abs/1603 ... 
- 155--MinStack
			/* 解法一:使用链表从0实现栈,用min来存放最小值. 复杂的地方是,如果pop了最小的数,就要遍重新找到最小的数. */ public class MinStack { List<Integ ... 
- odoo10学习笔记四:onchange、唯一性约束
			转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189273.html 一:onchange机制[onchange=前端js函数!可以实现前端实时更新以及修 ... 
- 对Quene中的队列的状态进行操作
			查看队列的状态(包括队列的满状态.空.元素个数等等) import multiprocessing quene = multiprocessing.Queue(3) quene.put(12) que ... 
- CentOS6.7安装Oracle数据库
- 唐敬博-201871010118 《面向对象程序设计(java)》第七周学习总结
			在博客园撰写博客(随笔),总结7周实验内容,作业格式要求如下: 博文名称:学号-姓名<面向对象程序设计(java)>第七周学习总结(1分) 博文正文开头格式:(2分) 项目 内容 这个作业 ... 
- python预科前三天:计算器知识、Python下载和安装、Pycharm下载安装激活设置、解释型和编译型、git、思维导图、显示隐藏文件、隐藏已知文件扩展名、创建组织、创建项目、提交作业、排BUG技巧
			1.计算机组成结构:CPU.硬盘.内存.输入输出设备.主板.电源. 2.硬件之间的协作关系:是CPU运算完后给操作系统.专业术语叫指令. 3.键盘输入a之后发生的事情:键盘-CPU-操作系统-显卡-显 ... 
- vmware centos 桥接模式 联网记录
			参考这篇文章 https://www.cnblogs.com/jasmine-Jobs/p/5928218.html 记得要修改/etc/sysconfig/network文件的网关配置,因为ip变动 ... 
- web框架--tornado自定义分页
			1.tornado_main.py #!/usr/bin/env python # -*- coding: utf-8 -*- import tornado.web import tornado.io ... 
