内容简介:接上文:对应Git代码地址请见:参考:
接上文: 一套代码小程序&Web&Native运行的探索05——snabbdom
对应Git代码地址请见: https://github.com/yexiaochai/wxdemo/tree/master/mvvm
https://github.com/fastCreator/MVVM(极度参考,十分感谢该作者,直接看Vue会比较吃力的,但是看完这个作者的代码便会轻易很多,可惜这个作者没有对应博客说明,不然就爽了)
https://www.tangshuang.net/3756.html
https://www.cnblogs.com/kidney/p/8018226.html
http://www.cnblogs.com/kidney/p/6052935.html
https://github.com/livoras/blog/issues/13
通过之前的学习,我们断断续续的了解到了一套MVVM框架需要了解的精华(我觉得的精华):
① 模板解析,由模板生成框架element
② 生成渲染函数,由element生成render匿名函数,这里便涉及到了指令的解析,render函数执行后生成了最终Vnode需要的数据字典,这里完成了HTML->Vnode的全部工作
③ 使用snabbdom进行页面渲染,后续数据更新调用发布订阅系统更新数据
而MVVM系统还有个比较关键的点是组件系统,一般认为MVVM的量大特点其实是响应式数据更新(Vnode相关),然后就是组件体系,这两者需要完成的工作都是让我们更搞笑的开发代码,一个为了解决纷乱的dom操作,一个为了解决负责的业务逻辑结构,所以我们今天便来学习组件体系相关逻辑
其实组件体系的实例化事实上跟new MVVM是一致的,只不过需要一点特殊处理,这里我们看其渲染时候的变化:
1 if (typeof tag == 'string') {
2 let Ctor = resolveAsset(this.$options, 'components', tag)
3 if (Ctor) {
4 return this._createComponent(Ctor, data, children, tag)
5 }
6 }
这里对tag做了判断,如果是字符串,并且我们参数里面传递了components参数,这里便会拿出来执行createComponent逻辑:
1 //创建组件
2 //子组件option,属性,子元素,tag
3 _createComponent(Ctor, data, children, sel) {
4 Ctor.data = mergeOptions(Ctor.data);
5 let componentVm;
6 let Factory = this.constructor
7 let parentData = this.$data
8 data.hook.insert = (vnode) => {
9 //...
10 }
11 Ctor._vnode = new VNode(sel,null,data, [], undefined, createElement(sel));
12 return Ctor._vnode
13 }
这里创建vnode的时候没有做什么特殊处理,所以我们的会形成这样的dom结构:
<my-component></my-component> <div m-for="(val, key, index) in arr">索引 1 :叶小钗</div> <div m-for="(val, key, index) in arr">索引 2 :素还真</div> <div m-for="(val, key, index) in arr">索引 3 :一页书</div>
但是这里有一个hook,在my-component作为dom插入的时候回被调用:
1 _createComponent(Ctor, data, children, sel) {
2 Ctor.data = mergeOptions(Ctor.data);
3 let componentVm;
4 let Factory = this.constructor
5 let parentData = this.$data
6 data.hook.insert = (vnode) => {
7 Ctor.data = Ctor.data || {};
8 var el =createElement('sel')
9 vnode.elm.append(el)
10 Ctor.el = el;
11 componentVm = new Factory(Ctor);
12 vnode.key = componentVm.uid;
13 componentVm._isComponent = true
14 componentVm.$parent = this;
15 (this.$children || (this.$children = [])).push(componentVm);
16 //写在调用父组件值
17 for (let key in data.attrs) {
18 if (Ctor.data[key]) {
19 warn(`data:${key},已存在`);
20 continue;
21 }
22 }
23 }
24 Ctor._vnode = new VNode(sel,null,data, [], undefined, createElement(sel));
25 return Ctor._vnode
26 }
这里先创建了一个空标签(sel)直接插入my-component中,然后执行与之前一样的实例化流程:
componentVm = new Factory(Ctor);
这个会在patch后将实际的dom节点更新上去:
this.$el = patch(this.$el, vnode); //$el现在为sel标签(dom标签)
这个就是snabbdom hook所干的工作,可以看到组件系统这里有这些特点:
① 组件是一个独立的mvvm实例,通过parent可以找到其父亲mvvm实例,可能跟实例,也可能是另一个组件
② 跟实例可以根据$children参数找到其下面所有的组件
③ 组件与跟实例通过data做交流,原则不允许在组件内部改变属性值,需要使用事件进行通信,事件通信就是在组件中的点击事件不做具体的工作,而是释放$emit(),这种东西让跟实例调用,最终还是以setData的方式改变基本数据,从而引发组件同步更新
所以只要把之前的内容搞懂了,组件一块会比较轻松,我们之前没涉及到属性,这里我们来试试数据传递:
html = `
<div ontap="onclick">
<my-component name="{{name}}"></my-component>
<div m-for="(val, key, index) in arr">索引 {{key + 1}} :{{val}}</div>
</div>
`
let vm = new MVVM({
el: '#app',
template: html,
components: {
'my-component': {
props: ['name'],
template: '<div>{{name}}-children component!</div>'
}
},
data: {
name: '叶小钗',
age: 30,
arr: [
'叶小钗', '素还真', '一页书'
]
},
methods: {
onclick: function(e) {
this.setData({
name: '素还真',
age: this.age + 1
});
}
}
})
具体代码各位看这里吧: https://github.com/yexiaochai/wxdemo/tree/master/mvvm
经过简单的学习,我们大概了解了组件的流程,接下来我们做下阶段的整理,把之前学的东西连起来
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人人都是产品经理2.0
苏杰 / 电子工业出版社 / 2017-5 / 66.6
《人人都是产品经理2.0——写给泛产品经理》继续定位在-1~3 岁的产品经理。这里特别要强调,“-1 岁”指的是“泛产品经理”群体,比如自认为是“产品新人”的“职场老人”,需要自己做产品的早期创业者,对产品感兴趣并且工作中可能要承担部分职责的技术、设计、运营等人员,其他行业对互联网产品感兴趣的从业者等,《人人都是产品经理2.0——写给泛产品经理》可以说是为他们量身定做的。 内容方面,《人人都......一起来看看 《人人都是产品经理2.0》 这本书的介绍吧!