对框架设计模式的理解

MVVM

  1. mvvm由model -> view, model <- view的原型演化而来(也就是说交互存在两个方向:v -> m, v <- m),在二者之间加入vm解耦。
  2. v收到用户指令要改动m,不能直接访问m,必须使用vm提供的方法间接访问m,所以v的结点可能需要提供到m中映射数据的索引或引用。
  3. vm应监控m中的数据,一旦数据有变,vm通知v更新对应的v节点,所以,vm中应有v节点和对应数据的binding。
  4. 那么v和m中的数据和ui组件如何绑定呢?可将数据结构处理为类似哈希表的形式:生成共同的id,在v和m中对应的对象可使用id提取。

MVC(后端)

  1. config 配置文件的意义:编写代码时,时常遇到要写死在代码中的常量,其中的大部分常量有自己的生命周期,时常面临变更的需要,它们实际上是一种生命周期更长的状态(state),因此,基于高内聚、低耦合的原则,很有必要将它们从逻辑流程中抽离,从实际使用的意义来说,配置文件是杠杆:一点点的修改可以精准地撬动大量的行为变化

react

  1. 关键词:UI , View,virtual-DOM , 函数式,declarive,生命周期,无状态组件,高阶组件,受控组件
  2. render中return ( <> )return后的括号不可少,否则有风险无法识别tag,括号中的元素必须归于同一个根节点
  3. state变量位于每个<>实例私有作用域中,相当于在constructor中声明private变量,所以state和节点实例一一对应,多用于根部节点。
  4. state要用setState{prop: value}来改变,改变之后重新调用对应节点的class的render,生成新的virtualDOM。
  5. 组件抽象成了对象,开发者可以在抽象程度很高的层面上把控view,view几乎相当于自动从data上长出来的;react开发相当于只操作data,更改了data后react自动更新view,省去了对view的操作。
  6. props是组件上的多层次数据缓存
  7. react在html节点层和app层之间加了一个组件层,其抽象程度位于二者之间。组件层将逻辑渗透在节点之间。
  8. render<>就是调用React.createElement()
  9. 花括号中必须是表达式,不能是语句,因为花括号的内容将作为createElement的参数;不能在其中对数据进行改动——比如push,这样意味着view对data的直接操作,that’s chaos。
  10. virtualDOM:用R.createElement生成的轻量对象,是对DOM的简化抽象。
  11. 在改动DOM前,setState会触发render新的virtualDOM,然后与旧的virtualDOM比对,筛出有改动的部分,然后在对那部分进行DOM实际操作,提升了效率。
  12. setState是异步操作,在render时才触发更改state,可避免多次setState频繁刷新。
  13. 开发者从始至终没有直接操作view,而是告诉react如何render data to view。
  14. 受控组件使用于输入直接影响render方式的情况
  15. 我理解的react流程:0.开发时组件树的结构预先编写在各组件的render中 1.初始化,实例化各个组件代理(一堆方法的集合)。2.将组件树通过组件代理的render映射为虚拟DOM树 3.如果有旧的虚拟DOM树,对比新旧虚拟DOM得出要更新的部分 4.浏览器根据第2/3步的结果渲染出DOM。
  16. 感想:传统MV*模式,M和V间的交互中问题主要原因是Model非常抽象,而View(DOM)非常具象,这导致这二者的交流需要中介的转译,当二者抽象程度相差巨大时,中介的构造也变得非常复杂,难于操作。react实现了在与Model同样的抽象层级上对View的操作,它含有的抽象层级数量可以由开发者控制,就像一条可长可短的纽带。
  17. state中的数据应尽可能原始、简单,数据结构可以在render前部构造。
  18. view对model的更改必须由root组件把method作为参数传给底层组件。
  19. render是纯函数,组件实例中包含状态与行为,render只是其中的一个行为。
  20. render中return的对象中必须都是value,不能有直接暴露的语句,因为其中的jsx要编译为React.createElement({}),render中的value都要映射到参数对象的值,如果存在语句就会出错。若又复杂逻辑必须有语句处理的话,可用三元表达式或匿名函数或在class中先声明一个返回组件的方法,再在render中调用这个方法。
  21. render props 使得children 和 父组件解耦,它们中间多了一层逻辑
  22. React.createElement: (type: string, props: {}, …children: ReactNode[]) => ReactElement。注意: children是数组。children是props中的一个属性(不同于vue的slot)
  23. ts在react中往往用于规范props和state的格式
  24. redux中store的改变如何触发render: store.subscribe(render)
  25. componentWillReceiveProps(nextProps){}可以用来比较新旧props,如果…则…,可以setState,不会额外调用render。设计的使用场景大概是用来侦测上游state,如果有了xx变化则启动xx流程,只要父组件render被调用^有props接入(不管有无变化),然后就会触发(在其他生命周期之前,甚至在判断是否需要更新组件之前),如果使用redux,当store变化后,很可能马上会调用所有组件的willReceive。在其中发出请求的时候要格外注意判断条件,起码先比对之前的props(props的前后变化相当于一个action),否则容易导致浏览器无限循环请求。
  26. 不建议在componentWillReceiveProps中篡改reload,因为这么做导致reload难以共享
  27. 每次render必定由上游的setState或全局Store的dispatch触发。
  28. 关于diff算法,目前的理解是: 父组件render产生n层的子节点树,diff层层递进(应该是前序遍历),每个子树的每层是个数组,如果同一index对应的节点type有变且没有key,则销毁并更新(如果该节点是组件还会触发willunmount并卸载组件实例对象)
  29. componentDidUpdate的用法: 如果要依照渲染完成后DOM元素的属性(height等等)实时更新数据,则可考虑用它。需要注意的是,如果在其中setState或更新props则很可能导致死循环,为此必须给更新行为加if条件。

Vue

  1. 不需要使用ko类似的闭包来感知状态的变化,简单地赋值即可,比起ko方便了很多,简直不能再方便了,这样的方便是如何实现的呢?答案是Object.defineProperty(o, value,{get(){return -}, set(newV){--}})
  2. vue的组件在使用前须先注册(两种情况:全局和局部)
  3. 局部注册:new Vue({components:{c1: valueOfComponent, c2: valueOfComponent}})
  4. vm有状态:data&computed,有行为method&watch,有view: template,同react的组件相似,vue的组件也不是单纯的UI,是数据、行为、视图混合的更抽象的组件
  5. computed在data和view中加了个中间层,某种角度上可以说是渲染数据的第一步。
  6. Vue-cli组件中,注册模板在script标签中的components属性
  7. 目前看来,vm中的callback触发时this都指向vm。因此值得注意的是尽量不要使用箭头函数。
  8. vue-router可在路由/:id中输入参数,通过{{ this.$route.params.id}}提取参数
  9. 生命周期mounted相当于react的componentDidMount,在mounted更新状态后触发updated生命周期
  10. 我猜测生命周期应是这样分布于vm的constructor中:
    function Vm (){this.beforeCreate = ...; this.lifeCycle = ...; //先写入生命周期钩子,然后在构造函数中合适的点插入调用生命周期 this.xx = xx; this.beforeCreate(); this.xx = xx; this.lifeCycle()}
  11. 有的生命周期则在contructor之外调用,比如mounted,估计是在父组件的render中调用:vm.render(); vm.挂载();vm.mounted;
  12. props的改变不会触发beforeUpdate
  13. vue更新view也是异步:当一个数据变动后,不会立即更新DOM,而是由eventLoop机制控制,在任务队列空了以后才更新DOM。
  14. vuex中:1 一个mutation即一个改变state的行为 2 一个action是对一组mutation的抽象,在vuex中以promise的形式执行,以方便异步操作 3 getter用来方便组件取用state,一般置入computed 4 组件中触发action采用如此形式:this.$store.dispatch('ACTION_NAME', payLoad)
  15. 感兴趣的功能:.mixin, .use, directive, render, slot,ref
  16. 在beforeMount和Mounted之间,也就是挂载过程中,vue开始把模板译为DOM,如果遇到子组件,则在注册的组件中搜寻该组件并create和挂载。
  17. 生命周期围绕这些行为:1 创建组件实例 2 挂载组件vDOM -> DOM 3 更新数据 4 销毁组件
  18. 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行
  19. 可以像router-view一样切换显示的组件
  20. 异步的action,我曾试着这样处理:把异步的promise放在store里,要用的时候data.then(innerData => this.data = innerData),但是这样有一个缺点就是视图无法或者难以响应promise的变化\
  21. vue中父组件可通过$refs直接访问子组件的实例和数据。

knockout

  1. 可能使用了观察者模式,在ko.observable中埋伏了.fire(),每当调用observable对数据进行更改时,fire()会通知viewmodel,以这种方法监控对数据的调用。以下是我理解的实现方式:
function observable(value){
	return function(replaceVal){
		if(replaceVal){
			ko.fire() //通知viewModel有改动
			value = replaceVal;
		}else{
			return value;
		}
	}
} 
  1. 用data-bind绑定view和model。考虑到表现和行为的分层,data-bind最好在js中的init函数中写入。
  2. 在octopus模式中,对data的取用往往需要在octopus对象上增添一个相应的method,这很笨拙且浪费资源。ko用obsevable返回的函数来代理data变量,解决了这个问题。
  3. data-bind="text: xx"可以理解为text(context.xx),text是ko的method{把context.xx写入节点的text},冒号后面的是参数。
  4. data-bind也可以绑定各种表达式(函数,三元操作之类的).
  5. data-bind=“click: foo”,回调函数foo调用的方式是context.foo()
  6. ko.applyBindings(obj)会绑定obj为binding context root,foreach:和with:会使部分节点范围内的binding context变小
  7. 若要访问binding context范围外的数据,可使用binding context提供的变量$parent 、$data、$root等等
  8. ko的事件会将触发事件的节点上的binding-context对象作为this参数传给handler
  9. this.a = ko.obsevable(1); this.a = ko.obsevable(1); this.sum = ko.computed(function)(){ return this.a() + this.b() }, this)ko.computed的原理:当你修改a时,必然是a(newValue),调用a会触发computed中的匿名回调函数从而更新sum的值;computed的监控在a、b是对象的时候对a、b的属性无效,因为此时a、b是指针,当它们的属性变化(比如增加一个属性)时,a、b指向的内存地址并没有变,而且,修改a的属性只需要a().attr = newValue,没有给a传递val,ko将操作识别为读取而不是写。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值