Vue 组件之间通讯的各种情况
我们都知道 Vue 的两大核心是组件化和数据驱动,在 Vue 中,组件之间的值传递是一种十分常见的事情,那么你到底知道多少种组件的值传递的方法呢,接下来由我来带领大家了解一下
Vue 组件之间的关系Vue 的组件根据其在页面上的位置,我认为大致可以分为以下几种:
父子组件 什么是父子组件呢? 假如现在页面中有一个根组件ParentComponent,现在我们需要在这个根组件中加入其他内容,例如一张图片,一段具有事件和样式的文字等,我们可以假设这个加入内容的组件名称为ChildrenComponent, 这个新加入的组件ChildrenComponent 相对与 ParentComponent就是子组件, ParentComponent 就是 ChildrenComponent 的父组件,如下所示
123<parent-component> <children-component></children-component></parent-component>
兄弟组件 什么是兄弟组件呢?以上面的父子组件为例,假如现在加入的不是一 ...
new Object() 和 Object.create() 的区别
今天我们来谈一谈通过 new Object() 和 Object.create() 创造的对象有什么区别
首先这两个方法都可以用来创建一个对象
12345var a = new Object()var a = Object.create()// 或者var a = new Object(obj)var a = Object.create(obj)
但是这两个方法创建的对象是有一些不同
new Object() 创建的对象是通过构造函数创建的对象,添加的属性是在自身实例下面Object.create() 创建的对象可以理解为继承一个对象,添加的属性是在 __proto__ 属性下面
123456var a = {a: 1}var b = new Object(a)console.log(b) // {a: 1}var c = Object.create(a)console.log(c) // {}console.log(c.__proto__) // {a ...
Vue keep-alive 组件状态缓存
这段时间做项目时,老板要求要缓存一些页面的表单数据,于是想到了 vue 的 keep-alive ,在使用时,自己也犯了一些错误,在此记录一下
首次使用 在阅读文档的时候,没有理解文档的内容,keep-alive 组件,vue官方文档给的解释是 匹配首先检查组件自身的name选项,如果name选项不可用,则匹配他的局部注册名称,但是不知怎的被我理解成为了 路由配置的name属性,结果闹了一个大乌龙
然后,自己怎么测试都发现不能缓存页面状态,最后使用面向百度编程找到了自己的错误
如何使用 为了方便我们不用新增一个组件,就把组件的name添加到 keep-alive 组件中,在这里我采用了一个取巧的方法
保证组件的 name 属性与对应路由的 name 属性保持一致
提取我们所需要的路由对象
这个方法根据我们传入的路由名称 动态提取出我们需要的路由对象,而不是获取所有的路由对象
12345678910function handleGetRoutes(routeName) { let routeObj = Object.create(null) asyncRo ...
发布订阅模式及观察者
观察者模式 观察者模式的目的就是为了实现松耦合,面对接口编程
在观察者模式里面,有一个实例对象–被观察者(Subject),他维护一套观察者(observer)的结合,这些 Observer 实现相同的接口,subject 只需要知道,通知 Observer 需要调用哪个统一的方法
发布订阅模式 在发布订阅模式里,发布者并不会直接通知订阅者,发布者和订阅者彼此不相识,通过第三方来进行函数调用
发布者 只需要告诉 第三方 我要 发送 的信息是 XXX
订阅者 只需要告诉 第三方 我要 订阅 的消息是 XXX
当 第三方 接收到 发布者 发送的消息且是 XXX 时,就会报消息推送给订阅了 XXX 的 订阅者,当然也有可能是 订阅者 自己过来拿取
在发布订阅模式中,发布者和订阅者不是松耦合,而是完全解耦的
总结
从表面上看
观察者模式只有两个角色 观察者和被观察者发布订阅模式中有三个角色 发布者、订阅者和第三方
深层次
观察者模式 是松耦合关系发布订阅模式 是完全不存在耦合
使用层次
观察者模式 多用于单个应用内部发布订阅模式 更多的是一种跨应用的模式
...
Vue源码阅读 part 01
Vue源码目录结构
compiler 编译
Vue 使用字符串作为模板
在编译文件夹中存放对 模板字符串 解析的算法,抽象语法树,优化core 核心
Vue 构造函数,以及生命周期等方法platforms 平台
针对运行的环境(browser/andriod/ios) 的不同实现
也是 vue 的入口server 服务端
将 vue 用在服务器端的代码sfc 单文件组件shared 共用工具、方法
vue 具体文件
shared/constant 常量
ASSET_TYPES 每一个 vue 组件需要挂载的成员
LIFECYCLE_HOOKS 生命周期函数 hook
shared/utils 工具方法
isPrimitive 判断是否为基本数据类型
123456789function isPrimitive (value: any): boolean %checks { return ( typeof val ...
03 - Vue源码解读-发布订阅模式
发布订阅模式代理方法 将 app._data 中的成员给映射到 vue 实例上面,由于app.data 已经是响应式的对象了,所以只需要让app访问的成员去访问 app._data 的对应成员
引入一个函数 proxy(target, src, prop),target 的操作映射到 src.prop 上面 (当时没有 es6 的 Proxy 语法)
使用一个新的方法来处理 Observer 方法对属性进行处理,将这个方法封装到 initData 方法中
12345678910111213141516171819202122JGVue.prototype.initData = function () { let keys = Object.keys(this._data) // 响应式化 setReactive for (let k = 0; k < keys.length; k++) { setReactive(this._data, vm) } // 代理 for (let k = 0; k < keys. ...
03 - Vue源码解读-响应式
响应式原理
我们在使用 Vue 的时候,复制属性获得属性都是直接使用Vue实例
我们在设计属性值的时候,页面数据更新
Object.defineProperty(obj, key, {})123456789101112// 注意 value 和 writable 不可以和 get set 连用Object.defineProperty(obj, key, { enumerable: !!enumerable, configurable: true, set (newValue){ value = newValue }, get(){ console.log(value) return value }})
使用 Object.defineProperty() 实现数据监控
123456789101112131415161718192021222324252627282930313233343536373839404142const data = { name: ...
02 - Vue源码解读-渲染模型
判断元素
vue 本质上是使用 HTML 字符串作为模板,将字符串模板转化为 AST(抽象语法树) ,再转换成 VNode
模板 -> AST
AST -> VNode
VNode -> DOM
最消耗性能的是字符串解析(模板 -> AST)
小例子: let s = “1 + 2 (3 + 4 (5 + 6))” 得到结果建议:将字符串表达式转化为波兰式表达式,使用栈结构来运算
1
vue源码如何区分HTML标签和自定义组件?
vue源码把所有可用的HTML标签都存起来
使用柯里化操作将需要遍历的 HTML 标签存储起来
1234567891011121314function makeMap(keys) { const obj = Object.create(null) keys.map(item => { obj[item] = true return item }) return function(key) { return !!obj[key] } ...
函数 - 函数反柯里化(uncurrying)
参考链接
函数柯里化
含义 柯里化:是固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数,核心思想是把多参数传入的函数拆成单(部分)参数函数,内部再返回下一个单(部分)参数函数,依次处理剩余函数
反柯里化:扩大适用范围,创建一个应用范围更广的函数,使本来只有特定对象才适用的方法,扩展到更多对象
通用实现 12345678910111213141516171819202122232425// 第一种实现方式Function.prototype.unCurrying = function() { const self = this // ...rest 方法相当于使用es6语法的解构赋值使用rest接收入参数组,相当于arguments rest的值是传入的所有参数组成的一个数组 return function(...rest) { return Function.prototype.call.apply(self, rest) }}const push = Arr ...
函数 - 函数柯里化(Currying)
参考文章
函数反柯里化
函数柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理批特定的需求,增加了函数的适用性,降低了函数的适用范围
柯里化函数通用实现
1234567891011function currying(fn) { var slice = Array.prototype.slice, // 取出传入的多个参数(不包含第一位) _args = slice.call(arguments, 1) return function() { var _inargs = slice.call(arguments) // 将创建柯里化函数传入的参数与后传入的参数进行合并 return fn.apply(null, _args.concat(_inargs)) }}
提高适用性
解决了兼容性问题,但同时也会再来,使用的不便利性,不同的应用场景往,要传递很多参数,以达到解决特定问题的目的。有时候应用中,同一种规则可能会反复使用,这就可能会造成代码的重复性。
12345678910111 ...