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配置文件构 ...
随机推荐
- 跨越HTTP无状态边界:Cookie与Session在Django中的实战应用
本文深入探索了Django中的Cookie和Session,解析了如何应对HTTP协议的无状态性问题,说明其基础概念,分析工作原理,并讨论何时应选择使用Cookie或Session.文章进阶部分,提出 ...
- 【IDEA】 远程调试
远程调试 使用特定JVM参数运行服务端代码 要让远程服务器运行的代码支持远程调试,则启动的时候必须加上特定的JVM参数,这些参数是: -Xdebug -Xrunjdwp:transport=dt_so ...
- 暗黑王者|ZEGO 低照度图像增强技术解析
在低光照的夜间,摄像头采集的画面通常是一片昏暗,画面清晰度要远远低于肉眼.而随着实时音视频应用技术的发展,我们已经看到了各种画质增强的视频增强技术,那么是否存在一种技术,可以使视频在低光照条件下看起来 ...
- 简单了解下最近正火的SwissTable
去年看到字节跳动给golang提了issue建议把map的底层实现改成SwissTable的时候,我就有想写这篇博客了,不过因为种种原因一直拖着. 直到最近遇golang官方开始讨论为了是否要接受Sw ...
- .NET周刊【7月第3期 2023-07-16】
国内文章 揭秘 .NET 中的 TimerQueue(上) https://www.cnblogs.com/eventhorizon/p/17557821.html TimerQueue 是.NET中 ...
- FPGA移位加三法
介绍 BCD码 BCD码的英文全称是Binary-Coded Decimal,简称BCD,按字面解释是二进制十进制代码,是一种二进制的数字编码形式. 常见的BCD码有8421BCD码,2421BCD ...
- 体验IntelliJ IDEA的远程开发(Remote Development)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 IDEA的远程开发功能,可以将本地的编译.构 ...
- 数据结构之B树
1 引言 B-tree,B即Balanced,是自平衡的多叉搜索树,用于组织和存储大量数据,以及数据库和文件系统等需要高效查找和插入操作的应用中. 为什么是"大量数据"?当主存不足 ...
- 调研capacitor兼容openharmony平台可行性
团队可能需要对开源的 capacitor 跨平台框架进行扩展,以生产支持 OpenHarmony 平台的应用,在此调研可行性.实现路径和预期工作量. 可行性分析 在验证 capacitor 是否可以将 ...
- 使用 KubeBlocks 为 K8s 提供稳如老狗的数据库服务
原文链接:https://forum.laf.run/d/994 大家好!今天这篇文章主要向大家介绍 Sealos 的数据库服务.在 Sealos 上数据库后端服务由 KubeBlocks 提供,为用 ...