update readme & build
This commit is contained in:
parent
2e19892e17
commit
0ef67708ec
72
README.md
72
README.md
|
@ -12,7 +12,7 @@ Coming soon....
|
|||
- JSX 是开发体验最棒(智能提示),[语法噪音最少](https://github.com/facebook/jsx#why-not-template-literals)的 UI 表达式
|
||||
- 每一个组件拥有 update 方法自由渲染最佳更新视图的时机,功耗低,自由度高,性能卓越
|
||||
- 局部 CSS 最佳解决方案(Shadow DOM),社区为局部 CSS 折腾了不少框架,Shadow DOM Style 是最完美的方案
|
||||
- WeStore 体系,99% 的项目不需要什么时间旅行,请不要上来就 redux,Omi store 体系可以满足所有项目,也能时间旅行
|
||||
- 类似 WeStore 体系,99% 的项目不需要什么时间旅行,请不要上来就 redux,Omi store 体系可以满足所有项目,也能时间旅行
|
||||
- 看看[Facebook React 和 Web Components对比优势](https://www.cnblogs.com/rubylouvre/p/4072979.html),Omi 融合了各自的优点,而且给开发者自由的选择喜爱的方式
|
||||
|
||||
对比同样开发 TodoApp, Omi 和 React 渲染完的 DOM 结构:
|
||||
|
@ -25,6 +25,8 @@ Coming soon....
|
|||
|
||||
- [Getting Started](#getting-started)
|
||||
- [Hello Omi](#hello-omi)
|
||||
- [TodoApp](#todoapp)
|
||||
- [Store](#store)
|
||||
- [Lifecycle](#lifecycle)
|
||||
- [Install](#install)
|
||||
- [Links](#links)
|
||||
|
@ -131,9 +133,6 @@ render(<my-app name='Omi v4.0'></my-app>, 'body')
|
|||
"babel-preset-omi": "^0.1.1",
|
||||
```
|
||||
|
||||
### Scoped CSS
|
||||
|
||||
|
||||
如果不想把 css 写在 js 里,你可以使用 [to-string-loader](https://www.npmjs.com/package/to-string-loader), 比如下面配置:
|
||||
|
||||
``` js
|
||||
|
@ -231,6 +230,71 @@ define('todo-app', TodoApp)
|
|||
render(<todo-app></todo-app>, 'body')
|
||||
```
|
||||
|
||||
### Store
|
||||
|
||||
|
||||
```js
|
||||
export default {
|
||||
data: {
|
||||
items: [],
|
||||
text: '',
|
||||
firstName: 'dnt',
|
||||
lastName: 'zhang',
|
||||
fullName: function () {
|
||||
return this.firstName + this.lastName
|
||||
},
|
||||
globalPropTest: 'abc', //更改我会刷新所有页面,不需要再组件和页面声明data依赖
|
||||
ccc: { ddd: 1 } //更改我会刷新所有页面,不需要再组件和页面声明data依赖
|
||||
},
|
||||
add: function () {
|
||||
this.data.items.push({
|
||||
text: this.data.text,
|
||||
id: Date.now()
|
||||
})
|
||||
this.data.text = ''
|
||||
this.update()
|
||||
},
|
||||
globalData: ['globalPropTest', 'ccc.ddd'],
|
||||
logMotto: function () {
|
||||
console.log(this.data.motto)
|
||||
},
|
||||
//默认 false,为 true 会无脑更新所有实例
|
||||
//updateAll: true
|
||||
}
|
||||
```
|
||||
|
||||
自定义 Element 需要声明依赖的 data,这样 Omi store 根据自定义组件上声明的 data 计算依赖 path 并会按需局部更新。如:
|
||||
|
||||
```js
|
||||
class TodoApp extends WeElement {
|
||||
static get data() {
|
||||
return { items: [], text: '' }
|
||||
}
|
||||
...
|
||||
...
|
||||
...
|
||||
handleChange = (e) => {
|
||||
this.store.data.text = e.target.value
|
||||
}
|
||||
|
||||
handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (!this.store.data.text.length) {
|
||||
return;
|
||||
}
|
||||
this.store.add()
|
||||
}
|
||||
}
|
||||
|
||||
define('todo-app', TodoApp)
|
||||
```
|
||||
|
||||
需要在 render 的时候从根节点注入 store 才能在所有自定义 Element 里使用 this.store:
|
||||
|
||||
```js
|
||||
render(<todo-app></todo-app>, 'body', store)
|
||||
```
|
||||
|
||||
### Lifecycle
|
||||
|
||||
| Lifecycle method | When it gets called |
|
||||
|
|
|
@ -616,10 +616,12 @@
|
|||
var update = false;
|
||||
// add new & update changed attributes
|
||||
for (name in attrs) {
|
||||
//diable when using store system?
|
||||
//!dom.store &&
|
||||
if (typeof attrs[name] === 'object') {
|
||||
// todo diff??
|
||||
dom.props[npn(name)] = attrs[name];
|
||||
update = true;
|
||||
dom.parentNode && (update = true);
|
||||
} else if (name !== 'children' && name !== 'innerHTML' && (!(name in old) || attrs[name] !== (name === 'value' || name === 'checked' ? dom[name] : old[name]))) {
|
||||
setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
|
||||
}
|
||||
|
@ -650,6 +652,10 @@
|
|||
}
|
||||
|
||||
WeElement.prototype.connectedCallback = function connectedCallback() {
|
||||
this.store = options.store;
|
||||
if (this.store) {
|
||||
this.store.instances.push(this);
|
||||
}
|
||||
this.install();
|
||||
|
||||
var shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
|
@ -706,9 +712,224 @@
|
|||
return WeElement;
|
||||
}(HTMLElement);
|
||||
|
||||
function render(vnode, parent) {
|
||||
parent = typeof parent === 'string' ? document.querySelector(parent) : parent;
|
||||
diff(null, vnode, {}, false, parent, false);
|
||||
function diff$1(current, pre) {
|
||||
var result = {};
|
||||
syncKeys(current, pre);
|
||||
_diff(current, pre, '', result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function syncKeys(current, pre) {
|
||||
if (current === pre) return;
|
||||
var rootCurrentType = type(current);
|
||||
var rootPreType = type(pre);
|
||||
if (rootCurrentType == '[object Object]' && rootPreType == '[object Object]') {
|
||||
if (Object.keys(current).length >= Object.keys(pre).length) {
|
||||
for (var key in pre) {
|
||||
var currentValue = current[key];
|
||||
if (currentValue === undefined) {
|
||||
current[key] = null;
|
||||
} else {
|
||||
syncKeys(currentValue, pre[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (rootCurrentType == '[object Array]' && rootPreType == '[object Array]') {
|
||||
if (current.length >= pre.length) {
|
||||
pre.forEach(function (item, index) {
|
||||
syncKeys(current[index], item);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _diff(current, pre, path, result) {
|
||||
if (current === pre) return;
|
||||
var rootCurrentType = type(current);
|
||||
var rootPreType = type(pre);
|
||||
if (rootCurrentType == '[object Object]') {
|
||||
if (rootPreType != '[object Object]' || Object.keys(current).length < Object.keys(pre).length) {
|
||||
setResult(result, path, current);
|
||||
} else {
|
||||
var _loop = function _loop(key) {
|
||||
var currentValue = current[key];
|
||||
var preValue = pre[key];
|
||||
var currentType = type(currentValue);
|
||||
var preType = type(preValue);
|
||||
if (currentType != '[object Array]' && currentType != '[object Object]') {
|
||||
if (currentValue != pre[key]) {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
}
|
||||
} else if (currentType == '[object Array]') {
|
||||
if (preType != '[object Array]') {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
} else {
|
||||
if (currentValue.length < preValue.length) {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
} else {
|
||||
currentValue.forEach(function (item, index) {
|
||||
_diff(item, preValue[index], (path == '' ? '' : path + ".") + key + '[' + index + ']', result);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (currentType == '[object Object]') {
|
||||
if (preType != '[object Object]' || Object.keys(currentValue).length < Object.keys(preValue).length) {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
} else {
|
||||
for (var subKey in currentValue) {
|
||||
_diff(currentValue[subKey], preValue[subKey], (path == '' ? '' : path + ".") + key + '.' + subKey, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (var key in current) {
|
||||
_loop(key);
|
||||
}
|
||||
}
|
||||
} else if (rootCurrentType == '[object Array]') {
|
||||
if (rootPreType != '[object Array]') {
|
||||
setResult(result, path, current);
|
||||
} else {
|
||||
if (current.length < pre.length) {
|
||||
setResult(result, path, current);
|
||||
} else {
|
||||
current.forEach(function (item, index) {
|
||||
_diff(item, pre[index], path + '[' + index + ']', result);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setResult(result, path, current);
|
||||
}
|
||||
}
|
||||
|
||||
function setResult(result, k, v) {
|
||||
if (type(v) != '[object Function]') {
|
||||
result[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
function type(obj) {
|
||||
return Object.prototype.toString.call(obj);
|
||||
}
|
||||
|
||||
function render(vnode, parent, store) {
|
||||
parent = typeof parent === 'string' ? document.querySelector(parent) : parent;
|
||||
if (store) {
|
||||
store.instances = [];
|
||||
extendStoreUpate(store);
|
||||
options.store = store;
|
||||
store.originData = JSON.parse(JSON.stringify(store.data));
|
||||
}
|
||||
diff(null, vnode, {}, false, parent, false);
|
||||
}
|
||||
|
||||
function extendStoreUpate(store) {
|
||||
store.update = function () {
|
||||
var _this = this;
|
||||
|
||||
var diffResult = diff$1(this.data, this.originData);
|
||||
if (Object.keys(diffResult)[0] == '') {
|
||||
diffResult = diffResult[''];
|
||||
}
|
||||
var updateAll = matchGlobalData(this.globalData, diffResult);
|
||||
if (Object.keys(diffResult).length > 0) {
|
||||
this.instances.forEach(function (instance) {
|
||||
if (updateAll || _this.updateAll || instance.constructor.updatePath && needUpdate(diffResult, instance.constructor.updatePath)) {
|
||||
instance.update();
|
||||
}
|
||||
});
|
||||
this.onChange && this.onChange(diffResult);
|
||||
for (var key in diffResult) {
|
||||
updateByPath(this.originData, key, typeof diffResult[key] === 'object' ? JSON.parse(JSON.stringify(diffResult[key])) : diffResult[key]);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function matchGlobalData(globalData, diffResult) {
|
||||
if (!globalData) return false;
|
||||
for (var keyA in diffResult) {
|
||||
if (globalData.indexOf(keyA) > -1) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, len = globalData.length; i < len; i++) {
|
||||
if (includePath(keyA, globalData[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function needUpdate(diffResult, updatePath) {
|
||||
for (var keyA in diffResult) {
|
||||
if (updatePath[keyA]) {
|
||||
return true;
|
||||
}
|
||||
for (var keyB in updatePath) {
|
||||
if (includePath(keyA, keyB)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function includePath(pathA, pathB) {
|
||||
if (pathA.indexOf(pathB) === 0) {
|
||||
var next = pathA.substr(pathB.length, 1);
|
||||
if (next === '[' || next === '.') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateByPath(origin, path, value) {
|
||||
var arr = path.replace(/]/g, '').replace(/\[/g, '.').split('.');
|
||||
var current = origin;
|
||||
for (var i = 0, len = arr.length; i < len; i++) {
|
||||
if (i === len - 1) {
|
||||
current[arr[i]] = value;
|
||||
} else {
|
||||
current = current[arr[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function define(name, ctor) {
|
||||
customElements.define(name, ctor);
|
||||
if (ctor.data) {
|
||||
ctor.updatePath = getUpdatePath(ctor.data);
|
||||
}
|
||||
}
|
||||
|
||||
function getUpdatePath(data) {
|
||||
var result = {};
|
||||
dataToPath(data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[key] = true;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === '[object Object]') {
|
||||
_dataToPath(data[key], key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _dataToPath(data, path, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[path + '.' + key] = true;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === '[object Object]') {
|
||||
_dataToPath(data[key], path + '.' + key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var instances = [];
|
||||
|
@ -719,7 +940,8 @@
|
|||
WeElement: WeElement,
|
||||
render: render,
|
||||
options: options,
|
||||
instances: instances
|
||||
instances: instances,
|
||||
define: define
|
||||
};
|
||||
|
||||
options.root.Omi.version = '4.0.0';
|
||||
|
@ -730,7 +952,8 @@
|
|||
WeElement: WeElement,
|
||||
render: render,
|
||||
options: options,
|
||||
instances: instances
|
||||
instances: instances,
|
||||
define: define
|
||||
};
|
||||
|
||||
if (typeof module != 'undefined') module.exports = Omi;else self.Omi = Omi;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -613,10 +613,12 @@ function diffAttributes(dom, attrs, old) {
|
|||
var update = false;
|
||||
// add new & update changed attributes
|
||||
for (name in attrs) {
|
||||
//diable when using store system?
|
||||
//!dom.store &&
|
||||
if (typeof attrs[name] === 'object') {
|
||||
// todo diff??
|
||||
dom.props[npn(name)] = attrs[name];
|
||||
update = true;
|
||||
dom.parentNode && (update = true);
|
||||
} else if (name !== 'children' && name !== 'innerHTML' && (!(name in old) || attrs[name] !== (name === 'value' || name === 'checked' ? dom[name] : old[name]))) {
|
||||
setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
|
||||
}
|
||||
|
@ -647,6 +649,10 @@ var WeElement = function (_HTMLElement) {
|
|||
}
|
||||
|
||||
WeElement.prototype.connectedCallback = function connectedCallback() {
|
||||
this.store = options.store;
|
||||
if (this.store) {
|
||||
this.store.instances.push(this);
|
||||
}
|
||||
this.install();
|
||||
|
||||
var shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
|
@ -703,9 +709,224 @@ var WeElement = function (_HTMLElement) {
|
|||
return WeElement;
|
||||
}(HTMLElement);
|
||||
|
||||
function render(vnode, parent) {
|
||||
parent = typeof parent === 'string' ? document.querySelector(parent) : parent;
|
||||
diff(null, vnode, {}, false, parent, false);
|
||||
function diff$1(current, pre) {
|
||||
var result = {};
|
||||
syncKeys(current, pre);
|
||||
_diff(current, pre, '', result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function syncKeys(current, pre) {
|
||||
if (current === pre) return;
|
||||
var rootCurrentType = type(current);
|
||||
var rootPreType = type(pre);
|
||||
if (rootCurrentType == '[object Object]' && rootPreType == '[object Object]') {
|
||||
if (Object.keys(current).length >= Object.keys(pre).length) {
|
||||
for (var key in pre) {
|
||||
var currentValue = current[key];
|
||||
if (currentValue === undefined) {
|
||||
current[key] = null;
|
||||
} else {
|
||||
syncKeys(currentValue, pre[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (rootCurrentType == '[object Array]' && rootPreType == '[object Array]') {
|
||||
if (current.length >= pre.length) {
|
||||
pre.forEach(function (item, index) {
|
||||
syncKeys(current[index], item);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _diff(current, pre, path, result) {
|
||||
if (current === pre) return;
|
||||
var rootCurrentType = type(current);
|
||||
var rootPreType = type(pre);
|
||||
if (rootCurrentType == '[object Object]') {
|
||||
if (rootPreType != '[object Object]' || Object.keys(current).length < Object.keys(pre).length) {
|
||||
setResult(result, path, current);
|
||||
} else {
|
||||
var _loop = function _loop(key) {
|
||||
var currentValue = current[key];
|
||||
var preValue = pre[key];
|
||||
var currentType = type(currentValue);
|
||||
var preType = type(preValue);
|
||||
if (currentType != '[object Array]' && currentType != '[object Object]') {
|
||||
if (currentValue != pre[key]) {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
}
|
||||
} else if (currentType == '[object Array]') {
|
||||
if (preType != '[object Array]') {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
} else {
|
||||
if (currentValue.length < preValue.length) {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
} else {
|
||||
currentValue.forEach(function (item, index) {
|
||||
_diff(item, preValue[index], (path == '' ? '' : path + ".") + key + '[' + index + ']', result);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (currentType == '[object Object]') {
|
||||
if (preType != '[object Object]' || Object.keys(currentValue).length < Object.keys(preValue).length) {
|
||||
setResult(result, (path == '' ? '' : path + ".") + key, currentValue);
|
||||
} else {
|
||||
for (var subKey in currentValue) {
|
||||
_diff(currentValue[subKey], preValue[subKey], (path == '' ? '' : path + ".") + key + '.' + subKey, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (var key in current) {
|
||||
_loop(key);
|
||||
}
|
||||
}
|
||||
} else if (rootCurrentType == '[object Array]') {
|
||||
if (rootPreType != '[object Array]') {
|
||||
setResult(result, path, current);
|
||||
} else {
|
||||
if (current.length < pre.length) {
|
||||
setResult(result, path, current);
|
||||
} else {
|
||||
current.forEach(function (item, index) {
|
||||
_diff(item, pre[index], path + '[' + index + ']', result);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setResult(result, path, current);
|
||||
}
|
||||
}
|
||||
|
||||
function setResult(result, k, v) {
|
||||
if (type(v) != '[object Function]') {
|
||||
result[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
function type(obj) {
|
||||
return Object.prototype.toString.call(obj);
|
||||
}
|
||||
|
||||
function render(vnode, parent, store) {
|
||||
parent = typeof parent === 'string' ? document.querySelector(parent) : parent;
|
||||
if (store) {
|
||||
store.instances = [];
|
||||
extendStoreUpate(store);
|
||||
options.store = store;
|
||||
store.originData = JSON.parse(JSON.stringify(store.data));
|
||||
}
|
||||
diff(null, vnode, {}, false, parent, false);
|
||||
}
|
||||
|
||||
function extendStoreUpate(store) {
|
||||
store.update = function () {
|
||||
var _this = this;
|
||||
|
||||
var diffResult = diff$1(this.data, this.originData);
|
||||
if (Object.keys(diffResult)[0] == '') {
|
||||
diffResult = diffResult[''];
|
||||
}
|
||||
var updateAll = matchGlobalData(this.globalData, diffResult);
|
||||
if (Object.keys(diffResult).length > 0) {
|
||||
this.instances.forEach(function (instance) {
|
||||
if (updateAll || _this.updateAll || instance.constructor.updatePath && needUpdate(diffResult, instance.constructor.updatePath)) {
|
||||
instance.update();
|
||||
}
|
||||
});
|
||||
this.onChange && this.onChange(diffResult);
|
||||
for (var key in diffResult) {
|
||||
updateByPath(this.originData, key, typeof diffResult[key] === 'object' ? JSON.parse(JSON.stringify(diffResult[key])) : diffResult[key]);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function matchGlobalData(globalData, diffResult) {
|
||||
if (!globalData) return false;
|
||||
for (var keyA in diffResult) {
|
||||
if (globalData.indexOf(keyA) > -1) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, len = globalData.length; i < len; i++) {
|
||||
if (includePath(keyA, globalData[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function needUpdate(diffResult, updatePath) {
|
||||
for (var keyA in diffResult) {
|
||||
if (updatePath[keyA]) {
|
||||
return true;
|
||||
}
|
||||
for (var keyB in updatePath) {
|
||||
if (includePath(keyA, keyB)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function includePath(pathA, pathB) {
|
||||
if (pathA.indexOf(pathB) === 0) {
|
||||
var next = pathA.substr(pathB.length, 1);
|
||||
if (next === '[' || next === '.') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateByPath(origin, path, value) {
|
||||
var arr = path.replace(/]/g, '').replace(/\[/g, '.').split('.');
|
||||
var current = origin;
|
||||
for (var i = 0, len = arr.length; i < len; i++) {
|
||||
if (i === len - 1) {
|
||||
current[arr[i]] = value;
|
||||
} else {
|
||||
current = current[arr[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function define(name, ctor) {
|
||||
customElements.define(name, ctor);
|
||||
if (ctor.data) {
|
||||
ctor.updatePath = getUpdatePath(ctor.data);
|
||||
}
|
||||
}
|
||||
|
||||
function getUpdatePath(data) {
|
||||
var result = {};
|
||||
dataToPath(data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[key] = true;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === '[object Object]') {
|
||||
_dataToPath(data[key], key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _dataToPath(data, path, result) {
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[path + '.' + key] = true;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if (type === '[object Object]') {
|
||||
_dataToPath(data[key], path + '.' + key, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var instances = [];
|
||||
|
@ -716,7 +937,8 @@ options.root.Omi = {
|
|||
WeElement: WeElement,
|
||||
render: render,
|
||||
options: options,
|
||||
instances: instances
|
||||
instances: instances,
|
||||
define: define
|
||||
};
|
||||
|
||||
options.root.Omi.version = '4.0.0';
|
||||
|
@ -727,9 +949,10 @@ var omi = {
|
|||
WeElement: WeElement,
|
||||
render: render,
|
||||
options: options,
|
||||
instances: instances
|
||||
instances: instances,
|
||||
define: define
|
||||
};
|
||||
|
||||
export default omi;
|
||||
export { h, h as createElement, WeElement, render, options, instances };
|
||||
export { h, h as createElement, WeElement, render, options, instances, define };
|
||||
//# sourceMappingURL=omi.esm.js.map
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -205,7 +205,7 @@
|
|||
var update = !1;
|
||||
for (name in attrs) if ('object' == typeof attrs[name]) {
|
||||
dom.props[npn(name)] = attrs[name];
|
||||
update = !0;
|
||||
dom.parentNode && (update = !0);
|
||||
} else if (!('children' === name || 'innerHTML' === name || name in old && attrs[name] === ('value' === name || 'checked' === name ? dom[name] : old[name]))) setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
|
||||
update && dom.update();
|
||||
}
|
||||
|
@ -228,10 +228,128 @@
|
|||
});
|
||||
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
||||
}
|
||||
function render(vnode, parent) {
|
||||
function diff$1(current, pre) {
|
||||
var result = {};
|
||||
syncKeys(current, pre);
|
||||
_diff(current, pre, '', result);
|
||||
return result;
|
||||
}
|
||||
function syncKeys(current, pre) {
|
||||
if (current !== pre) {
|
||||
var rootCurrentType = type(current);
|
||||
var rootPreType = type(pre);
|
||||
if ('[object Object]' == rootCurrentType && '[object Object]' == rootPreType) {
|
||||
if (Object.keys(current).length >= Object.keys(pre).length) for (var key in pre) {
|
||||
var currentValue = current[key];
|
||||
if (void 0 === currentValue) current[key] = null; else syncKeys(currentValue, pre[key]);
|
||||
}
|
||||
} else if ('[object Array]' == rootCurrentType && '[object Array]' == rootPreType) if (current.length >= pre.length) pre.forEach(function(item, index) {
|
||||
syncKeys(current[index], item);
|
||||
});
|
||||
}
|
||||
}
|
||||
function _diff(current, pre, path, result) {
|
||||
if (current !== pre) {
|
||||
var rootCurrentType = type(current);
|
||||
var rootPreType = type(pre);
|
||||
if ('[object Object]' == rootCurrentType) if ('[object Object]' != rootPreType || Object.keys(current).length < Object.keys(pre).length) setResult(result, path, current); else {
|
||||
for (var key in current) !function(key) {
|
||||
var currentValue = current[key];
|
||||
var preValue = pre[key];
|
||||
var currentType = type(currentValue);
|
||||
var preType = type(preValue);
|
||||
if ('[object Array]' != currentType && '[object Object]' != currentType) {
|
||||
if (currentValue != pre[key]) setResult(result, ('' == path ? '' : path + ".") + key, currentValue);
|
||||
} else if ('[object Array]' == currentType) if ('[object Array]' != preType) setResult(result, ('' == path ? '' : path + ".") + key, currentValue); else if (currentValue.length < preValue.length) setResult(result, ('' == path ? '' : path + ".") + key, currentValue); else currentValue.forEach(function(item, index) {
|
||||
_diff(item, preValue[index], ('' == path ? '' : path + ".") + key + '[' + index + ']', result);
|
||||
}); else if ('[object Object]' == currentType) if ('[object Object]' != preType || Object.keys(currentValue).length < Object.keys(preValue).length) setResult(result, ('' == path ? '' : path + ".") + key, currentValue); else for (var subKey in currentValue) _diff(currentValue[subKey], preValue[subKey], ('' == path ? '' : path + ".") + key + '.' + subKey, result);
|
||||
}(key);
|
||||
} else if ('[object Array]' == rootCurrentType) if ('[object Array]' != rootPreType) setResult(result, path, current); else if (current.length < pre.length) setResult(result, path, current); else current.forEach(function(item, index) {
|
||||
_diff(item, pre[index], path + '[' + index + ']', result);
|
||||
}); else setResult(result, path, current);
|
||||
}
|
||||
}
|
||||
function setResult(result, k, v) {
|
||||
if ('[object Function]' != type(v)) result[k] = v;
|
||||
}
|
||||
function type(obj) {
|
||||
return Object.prototype.toString.call(obj);
|
||||
}
|
||||
function render(vnode, parent, store) {
|
||||
parent = 'string' == typeof parent ? document.querySelector(parent) : parent;
|
||||
if (store) {
|
||||
store.instances = [];
|
||||
extendStoreUpate(store);
|
||||
options.store = store;
|
||||
store.originData = JSON.parse(JSON.stringify(store.data));
|
||||
}
|
||||
diff(null, vnode, {}, !1, parent, !1);
|
||||
}
|
||||
function extendStoreUpate(store) {
|
||||
store.update = function() {
|
||||
var _this = this;
|
||||
var diffResult = diff$1(this.data, this.originData);
|
||||
if ('' == Object.keys(diffResult)[0]) diffResult = diffResult[''];
|
||||
var updateAll = matchGlobalData(this.globalData, diffResult);
|
||||
if (Object.keys(diffResult).length > 0) {
|
||||
this.instances.forEach(function(instance) {
|
||||
if (updateAll || _this.updateAll || instance.constructor.updatePath && needUpdate(diffResult, instance.constructor.updatePath)) instance.update();
|
||||
});
|
||||
this.onChange && this.onChange(diffResult);
|
||||
for (var key in diffResult) updateByPath(this.originData, key, 'object' == typeof diffResult[key] ? JSON.parse(JSON.stringify(diffResult[key])) : diffResult[key]);
|
||||
}
|
||||
};
|
||||
}
|
||||
function matchGlobalData(globalData, diffResult) {
|
||||
if (!globalData) return !1;
|
||||
for (var keyA in diffResult) {
|
||||
if (globalData.indexOf(keyA) > -1) return !0;
|
||||
for (var i = 0, len = globalData.length; i < len; i++) if (includePath(keyA, globalData[i])) return !0;
|
||||
}
|
||||
return !1;
|
||||
}
|
||||
function needUpdate(diffResult, updatePath) {
|
||||
for (var keyA in diffResult) {
|
||||
if (updatePath[keyA]) return !0;
|
||||
for (var keyB in updatePath) if (includePath(keyA, keyB)) return !0;
|
||||
}
|
||||
return !1;
|
||||
}
|
||||
function includePath(pathA, pathB) {
|
||||
if (0 === pathA.indexOf(pathB)) {
|
||||
var next = pathA.substr(pathB.length, 1);
|
||||
if ('[' === next || '.' === next) return !0;
|
||||
}
|
||||
return !1;
|
||||
}
|
||||
function updateByPath(origin, path, value) {
|
||||
var arr = path.replace(/]/g, '').replace(/\[/g, '.').split('.');
|
||||
var current = origin;
|
||||
for (var i = 0, len = arr.length; i < len; i++) if (i === len - 1) current[arr[i]] = value; else current = current[arr[i]];
|
||||
}
|
||||
function define(name, ctor) {
|
||||
customElements.define(name, ctor);
|
||||
if (ctor.data) ctor.updatePath = getUpdatePath(ctor.data);
|
||||
}
|
||||
function getUpdatePath(data) {
|
||||
var result = {};
|
||||
dataToPath(data, result);
|
||||
return result;
|
||||
}
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
result[key] = !0;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if ('[object Object]' === type) _dataToPath(data[key], key, result);
|
||||
});
|
||||
}
|
||||
function _dataToPath(data, path, result) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
result[path + '.' + key] = !0;
|
||||
var type = Object.prototype.toString.call(data[key]);
|
||||
if ('[object Object]' === type) _dataToPath(data[key], path + '.' + key, result);
|
||||
});
|
||||
}
|
||||
var options = {
|
||||
store: null,
|
||||
root: function() {
|
||||
|
@ -288,6 +406,8 @@
|
|||
}
|
||||
_inherits(WeElement, _HTMLElement);
|
||||
WeElement.prototype.connectedCallback = function() {
|
||||
this.store = options.store;
|
||||
if (this.store) this.store.instances.push(this);
|
||||
this.install();
|
||||
var shadowRoot = this.attachShadow({
|
||||
mode: 'open'
|
||||
|
@ -333,7 +453,8 @@
|
|||
WeElement: WeElement,
|
||||
render: render,
|
||||
options: options,
|
||||
instances: instances
|
||||
instances: instances,
|
||||
define: define
|
||||
};
|
||||
options.root.Omi.version = '4.0.0';
|
||||
var Omi = {
|
||||
|
@ -342,7 +463,8 @@
|
|||
WeElement: WeElement,
|
||||
render: render,
|
||||
options: options,
|
||||
instances: instances
|
||||
instances: instances,
|
||||
define: define
|
||||
};
|
||||
if ('undefined' != typeof module) module.exports = Omi; else self.Omi = Omi;
|
||||
}();
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -54,12 +54,12 @@ class TodoApp extends WeElement {
|
|||
|
||||
define('todo-app', TodoApp)
|
||||
|
||||
const store = {
|
||||
const store = {
|
||||
data: { items: [], text: '' },
|
||||
add:function(){
|
||||
add: function () {
|
||||
this.data.items.push({
|
||||
text:this.data.text,
|
||||
id:Date.now()
|
||||
text: this.data.text,
|
||||
id: Date.now()
|
||||
})
|
||||
this.data.text = ''
|
||||
this.update()
|
||||
|
|
Loading…
Reference in New Issue