Vue源码学习(十三):实现watch(一):方法,对象
好家伙,
代码出了点bug,暂时只能实现这两种形式
完整代码已开源https://github.com/Fattiger4399/analytic-vue.git
Vue:watch的多种使用方法
watch有非常多种使用方式,我们要对其进行分类讨论处理
1.初始化:
//initState.js
if (opts.watch) {
initWatch(vm);
}
initWatch()方法
function initWatch(vm) {
//1 获取watch
let watch = vm.$options.watch
console.log(watch)
//2 遍历 { a,b,c}
for (let key in watch) {
//2.1获取 他的属性对应的值 (判断)
let handler = watch[key] //数组 ,对象 ,字符,函数
if (Array.isArray(handler)) {//数组 []
handler.forEach(item=>{
createrWatcher(vm,key,item)
})
} else {//对象 ,字符,函数
//3创建一个方法来处理
createrWatcher(vm,key,handler)
}
}
}
createrWatcher()
//格式化处理
//vm 实例
//exprOrfn key
//hendler key对应的值
//options 自定义配置项 vue自己的为空,用户定义的才有
function createrWatcher(vm,exprOrfn,handler,options){
//3.1 处理handler
if(typeof handler ==='object'){
options = handler; //用户的配置项目
handler = handler.handler;//这个是一个函数
}
if(typeof handler ==='string'){// 'aa'
handler = vm[handler] //将实例行的方法作为 handler 方法代理和data 一样
}
//其他是 函数
//watch 最终处理 $watch 这个方法
// console.log(vm,"||vm")
// console.log(exprOrfn,"||exprOrfn")
// console.log(handler,"||handler")
// console.log(options,"||options") return vm.$watch(vm,exprOrfn,handler,options)
}
原型上挂$watch方法
export function stateMixin(vm) {
console.log(vm,6666)
//列队 :1就是vue自己的nextTick 2用户自己的
vm.prototype.$nextTick = function (cb) { //nextTick: 数据更新之后获取到最新的DOM
// console.log(cb)
nextTick(cb)
},
vm.prototype.$watch =function(Vue,exprOrfn,handler,options={}){ //上面格式化处理
// console.log(exprOrfn,handler,options)
//实现watch 方法 就是new watcher //渲染走 渲染watcher $watch 走 watcher user false
// watch 核心 watcher
let watcher = new Watcher(Vue,exprOrfn,handler,{...options,user:true})
if(options.immediate){
handler.call(Vue) //如果有这个immediate 立即执行
}
}
}
2.watcher.js
watcher类
class Watcher {
//vm 实例
//exprOrfn vm._updata(vm._render())
constructor(vm, exprOrfn, cb, options) {
// 1.创建类第一步将选项放在实例上
this.vm = vm;
this.exprOrfn = exprOrfn;
this.cb = cb;
this.options = options;
// 2. 每一组件只有一个watcher 他是为标识
this.id = id++
this.user = !!options.user
// 3.判断表达式是不是一个函数
this.deps = [] //watcher 记录有多少dep 依赖
this.depsId = new Set()
if (typeof exprOrfn === 'function') {
this.getter = exprOrfn
}else{ //{a,b,c} 字符串 变成函数
this.getter =function(){ //属性 c.c.c
let path = exprOrfn.split('.')
let obj = vm
for(let i = 0;i<path.length;i++){
obj = obj[path[i]]
}
return obj //
}
}
// 4.执行渲染页面
this.value = this.get() //保存watch 初始值
}
addDep(dep) {
//去重 判断一下 如果dep 相同我们是不用去处理的
let id = dep.id
// console.log(dep.id)
if (!this.depsId.has(id)) {
this.deps.push(dep)
this.depsId.add(id)
//同时将watcher 放到 dep中
// console.log(666)
dep.addSub(this)
}
// 现在只需要记住 一个watcher 有多个dep,一个dep 有多个watcher
//为后面的 component
}
run() { //old new
let value = this.get() //new
let oldValue = this.value //old
this.value = value
//执行 hendler (cb) 这个用户wathcer
if(this.user){
this.cb.call(this.vm,value,oldValue)
}
}
get() {
// Dep.target = watcher
pushTarget(this) //当前的实例添加
const value = this.getter()// 渲染页面 render() with(wm){_v(msg,_s(name))} ,取值(执行get这个方法) 走劫持方法
popTarget(); //删除当前的实例 这两个方法放在 dep 中
return value
}
//问题:要把属性和watcher 绑定在一起 去html页面
// (1)是不是页面中调用的属性要和watcher 关联起来
//方法
//(1)创建一个dep 模块
updata() { //三次
//注意:不要数据更新后每次都调用 get 方法 ,get 方法回重新渲染
//缓存
// this.get() //重新渲染
queueWatcher(this)
}
}
3.看看效果
<body>
<div id="app">{{a}}</div>
<script src='./dist/vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data: {
a: 1,
b:[1,2],
c:{c:{c:100}}
},
methods:{
aa(){
console.log(2000)
}
},
//watch 基本使用方式
//1 属性 :方法(函数)
//2 属性 :数组
//3 属性 :对象
//4 属性 :字符串
watch: {
'c.c.c'(newValue,oldValue){
console.log(newValue,oldValue,'||this isnewValue,oldValue from c.c.c')
}, a:{
handler(){ //
console.log('a数据更新')
},
immediate:true },
// a:'aa',
}
})
vm.a = 100
// vm.b[1] = 2
console.log(vm.c.c.c=2000)
</script>
</body>

Vue源码学习(十三):实现watch(一):方法,对象的更多相关文章
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
- VUE 源码学习01 源码入口
VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...
- Vue源码学习(一):调试环境搭建
最近开始学习Vue源码,第一步就是要把调试环境搭好,这个过程遇到小坑着实费了点功夫,在这里记下来 一.调试环境搭建过程 1.安装node.js,具体不展开 2.下载vue项目源码,git或svn等均可 ...
- Vue 源码学习(1)
概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- mybatis源码学习:从SqlSessionFactory到代理对象的生成
目录 一.根据XML配置文件构建SqlSessionFactory 二.通过SqlSessionFactory创建SqlSession 三.getMapper获取动态代理对象 一.根据XML配置文件构 ...
随机推荐
- 安装Hadoop单节点伪分布式集群
目录 安装Hadoop单节点伪分布式集群 系统准备 开启SSH 安装JDK 安装Hadoop 下载 准备启动 伪分布式模式安装 配置 配饰SSH免密登录本机 测试启动 单节点安装YARN 伪分布式集群 ...
- PDF书签的编辑器,基于(python、Tkinter)
使用 脚本 在github下载源码. 安装python3 安装必要的python包 pip install numpy pip install pandas pip install PyMuPDF p ...
- Unity自定义类使用携程--自身不继承MonoBehaviour
[TOC] 参考: https://www.jianshu.com/p/67f498cb839b 话不多说,直接上代码 1 using System.Collections; 2 using Unit ...
- C语言基础-基础指针
文章目录 指针 前言 1.什么是指针 2.指针的使用 (1)指针的定义 (2)指针的赋值 (3)指针类型 (4)如何使用指针 3.野指针 (1)导致野指针的原因 ① 未初始化指针 ②指针越界访问 ③指 ...
- SQLServer 数据库 Money 和 Float 类型运算的奇怪显现
SQLServer 数据库 Money和 Float类型运算的奇怪显现 1.1 背景 1.2 场景描述 1.3 原因及解决办法 1.1 背景 最近在做一个优化的项目 1.2 场景描述 DECLARE ...
- fastjson 1.2.80 漏洞浅析及利用payload
0x01 说明 在fastjson的1.2.80版本中可以通过将依赖加入到java.lang.Exception 期望类的子类中,绕过checkAuto. 0x02 简析 { "@type& ...
- 【博客重构之路】webman-admin安装指南
原文地址[博客重构之路]webman-admin安装指南 视频地址[bilibili] webman是什么 webman是一款基于workerman开发的高性能HTTP服务框架.webman用于替代传 ...
- loader的三种配置方式
在这篇 webpack处理css资源 文章中使用几个常用的loader 来编译 css 代码. 但其实 loader 的配置方式不止一种,一起来看看其它方式~ 在 webpack.config.js ...
- [nginx]编译安装openresty
前言 OpenResty是一个基于Nginx和Lua的高性能Web平台,其内部集成了大量精良的Lua库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 Web 应用.W ...
- 手写 Vuex4 源码
本文首发于掘金,未经许可禁止转载 Vuex4 是 Vue 的状态管理工具,Vuex 和单纯的全局对象有以下两点不同: Vuex 的状态存储是响应式的 不能直接改变 store 中的状态.改变 stor ...