Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aoy的说明书 #1

Open
aooy opened this issue Mar 18, 2017 · 6 comments
Open

aoy的说明书 #1

aooy opened this issue Mar 18, 2017 · 6 comments

Comments

@aooy
Copy link
Owner

aooy commented Mar 18, 2017

作者:杨敬卓

转载请注明出处

目录

  • 前言
  • 动机
  • 原理
  • 使用
  • 总结

前言

随着移动端的崛起,现代标准浏览器的推广,为解决浏览器兼容问题的jQuery渐渐没落。vue和react这些新的前端框架带来了完全不一样的开发体验,不再需要手动去处理dom节点,只需要关心数据层面的问题。

动机

流行的框架和库往往因为功能齐全导致体积巨大,有时我们只用到它们很少的功能,尝试去学习原理,自己实现特定功能有益于学习。

aoy深受Vue和react的影响,是使用Vue和react后,去实践写的一个简单框架。在Vue和react中,每个组件都可以有自己的数据存储容器,当父子组件或不同层级组件需要频繁大量的通信数据时,如果没有Vuex和redux这些状态管理框架,往往最后会变得一团糟。

把所有组件的数据存储在一个唯一的容器里,数据只在容器和组件之间流动。 这是aoy的设计理念。现在aoy只有最基本的功能。只有600行代码,想了解Virtual DOM和diff算法的同学可以试着去阅读源码。

原理

使用了Object.defineProperty绑定store的数据,当观察到数据改变,比较新旧数据产生的Virtual DOM,将差异应用到真实dom上。练练ps,给大家画张图。

使用

//初始化aoy实例,取得store
var aoy = Aoy.init();
var store = aoy.store;
var el = aoy.el;

//数据
var userData = [
	{name: 'c', age: 19, city: 'Beijin'},
	{name: 'a', age: 20, city: 'Xian'},
	{name: 'b', age: 12, city: 'Hangzhou'},
	{name: 'd', age: 30, city: 'Wuhan'}
];

//将数据添加进store
store.add('table',{
	userData: userData
});

//封装的节点函数,便于复用
function Table(childern){
	return el('table',childern);
}

function Tr(childern){
	return el('tr', childern);
}
function Th(txt){
	return el('td', txt);
}
function Td(txt){
	return el('td', txt);
}

//记录字段的排序
var sortStore = Object.create(null);

//创建组件
var mytable = aoy.createComponent({
	el: document.body,
	sortData: function(field,e){  //字段的排序函数
		let i;
		userData.sort(function(a, b){
			if(i = (sortStore[field] === 'down')){		
				if(a[field] < b[field]) return 1;
			}else{
				if(a[field] > b[field]) return 1;
			}
		});
		sortStore[field] = i?'up':'down';
		this.table.userData = userData;
	},
	render: function(){
		var trs = [
				el('tr',[
						 el('th',{onclick: this.sortData.bind(this, 'name') },'name'), 
						 el('th',{onclick: this.sortData.bind(this, 'age') },'age'), 
						 el('th',{onclick: this.sortData.bind(this, 'city') },'city')
						]
					)
				];
		this.table.userData.forEach(function(v, i){
				var tdName = Td(v.name);
				var tdAge = Td(v.age);
				var tdCity = Td(v.city);
				var tr = Tr([tdName, tdAge, tdCity]);
				trs.push(tr);
			});	
		var table = Table(trs);
		return table;
	}
});
// 连接组件与数据,同时渲染进文档
aoy.connect(mytable,'table');
  • 如果想最大化的利用dom节点,例如 ul > li *n 结构,可以给节点加上key属性。
var userData = [
	{name: 'c', key: '3'},
	{name: 'a', key: '1'},
	{name: 'b', key: '2'},
	{name: 'd', key: '4'}
];
function Li (v) {
   return el('li',{ key :  v.key}, v.name);
}
var list = [];
userData.forEach(function ( v ){
  list.push( Li(v) );
})
function render () {
  return el('ul',[ list ]);
}

Note

  • 只在需要大量重绘的地方使用。

  • 每个aoy实例都会初始化自己的store, 建议一个document下只实例化一个aoy。

  • 在组件中使用this时,this均指向它的调用者。如果需要在调用时取得组件,可以使用bind绑定。

var myinput = aoy.createComponent({
	el: document.body,
	inputFn: function(){
		console(this)      //input
	},
	render: function(){
		return el('Input', {oninput: this.inputFn,type: 'text' });
	}
});
var myinputComponent= aoy.createComponent({
	el: document.body,
	inputFn: function(){
		console(this)      //myinputComponent
	},
	render: function(){
		return el('Input', {oninput: this.inputFn.bind(this),type: 'text' });
	}
});
  • 依赖计算只绑定到最高层级, 也就是shore的key,当你修改shore的一个深层对象时,视图不会有反应。aoy并没有像vue那样为组件所调用的每一个数据做依赖计算,甚至覆盖数组的原生方法达到双向绑定的目的。这意味着优化的钥匙掌握在使用者手中,可以将深层次的数据结构拆分,也可以搭配immutable-js使用。
var aoy = Aoy.init()
var store = aoy.store
store.add('a' , {b: {text: 'this is p' }})
var myP = aoy.createComponent({
	el: document.body,
	render: function(){
		return el('p',this.a.b.text);
	}
});
aoy.connect(myP, 'a')
aoy.store.get('a').b.text = 'new'  //视图不会改变
aoy.store.get('a').b ={text: 'new'} //视图更新

总结

aoy可以说是学习Vue和react原理再结合自己想法的产物,还有很多不足之处。

@aooy aooy changed the title aoy aoy的说明书 Mar 18, 2017
@strongcode9527
Copy link

大神,膜拜一下,打算通读一下源码

@aooy aooy added the javascript label Apr 4, 2017
@wangjunrenya
Copy link

带我一个,我也要通读一下源码

@wangerniu
Copy link

上个车

@MrZeHai
Copy link

MrZeHai commented Nov 8, 2018

明天有时间看一下源码,我是实习生,哈哈加油

@EmolLi
Copy link

EmolLi commented Jan 30, 2019

谢谢大神的项目!已通读源码,深有体会 =)
react和vue源码过于复杂,您的项目极大得帮助了像我这样想要了解web framework架构的学生
然后弱弱提一点,"shore"是个typo吧?

@LesterWeng
Copy link

谢谢大神的项目!已通读源码,深有体会 =)
react和vue源码过于复杂,您的项目极大得帮助了像我这样想要了解web framework架构的学生
然后弱弱提一点,"shore"是个typo吧?

应该是笔误 store

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants