parent
b54bef42d4
commit
ea84453d97
|
@ -308,7 +308,7 @@
|
|||
* @param {boolean} isSvg Are we currently diffing inside an svg?
|
||||
* @private
|
||||
*/
|
||||
function setAccessor(node, name, old, value, isSvg) {
|
||||
function setAccessor(node, name, old, value, isSvg, store) {
|
||||
if (name === 'className') name = 'class';
|
||||
|
||||
if (name === 'key') {
|
||||
|
@ -342,7 +342,7 @@
|
|||
} else {
|
||||
node.removeEventListener(name, eventProxy, useCapture);
|
||||
}
|
||||
(node._listeners || (node._listeners = {}))[name] = value;
|
||||
(node._listeners || (node._listeners = {}))[name] = value.bind(store);
|
||||
} else if (name !== 'list' && name !== 'type' && !isSvg && name in node) {
|
||||
// Attempt to set a DOM property to the given value.
|
||||
// IE & FF throw for certain property-value combinations.
|
||||
|
@ -408,7 +408,7 @@
|
|||
* @returns {import('../dom').PreactElement} The created/mutated element
|
||||
* @private
|
||||
*/
|
||||
function diff(dom, vnode, context, mountAll, parent, componentRoot) {
|
||||
function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
||||
// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
|
||||
if (!diffLevel++) {
|
||||
// when first starting the diff, check if we're diffing an SVG or within an SVG
|
||||
|
@ -418,7 +418,7 @@
|
|||
hydrating = dom != null && !(ATTR_KEY in dom);
|
||||
}
|
||||
|
||||
var ret = idiff(dom, vnode, context, mountAll, componentRoot);
|
||||
var ret = idiff(dom, vnode, context, mountAll, componentRoot, store);
|
||||
|
||||
// append the element if its a new parent
|
||||
if (parent && ret.parentNode !== parent) parent.appendChild(ret);
|
||||
|
@ -442,7 +442,7 @@
|
|||
* @param {boolean} [componentRoot] ?
|
||||
* @private
|
||||
*/
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot) {
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
||||
var out = dom,
|
||||
prevSvgMode = isSvgMode;
|
||||
|
||||
|
@ -517,11 +517,11 @@
|
|||
}
|
||||
// otherwise, if there are existing or new children, diff them:
|
||||
else if (vchildren && vchildren.length || fc != null) {
|
||||
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML != null);
|
||||
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML != null, store);
|
||||
}
|
||||
|
||||
// Apply attributes/props from VNode to the DOM Element:
|
||||
diffAttributes(out, vnode.attributes, props);
|
||||
diffAttributes(out, vnode.attributes, props, store);
|
||||
|
||||
// restore previous SVG mode: (in case we're exiting an SVG namespace)
|
||||
isSvgMode = prevSvgMode;
|
||||
|
@ -539,7 +539,7 @@
|
|||
* @param {boolean} isHydrating if `true`, consumes externally created elements
|
||||
* similar to hydration
|
||||
*/
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) {
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating, store) {
|
||||
var originalChildren = dom.childNodes,
|
||||
children = [],
|
||||
keyed = {},
|
||||
|
@ -597,7 +597,7 @@
|
|||
}
|
||||
|
||||
// morph the matched/found/created DOM child to match vchild (deep)
|
||||
child = idiff(child, vchild, context, mountAll);
|
||||
child = idiff(child, vchild, context, mountAll, null, store);
|
||||
|
||||
f = originalChildren[_i];
|
||||
if (child && child !== dom && child !== f) {
|
||||
|
@ -671,20 +671,20 @@
|
|||
* @param {object} old Current/previous attributes (from previous VNode or
|
||||
* element's prop cache)
|
||||
*/
|
||||
function diffAttributes(dom, attrs, old) {
|
||||
function diffAttributes(dom, attrs, old, store) {
|
||||
var name = void 0;
|
||||
|
||||
// remove attributes no longer present on the vnode by setting them to undefined
|
||||
for (name in old) {
|
||||
if (!(attrs && attrs[name] != null) && old[name] != null) {
|
||||
setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
|
||||
setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode, store);
|
||||
}
|
||||
}
|
||||
|
||||
// add new & update changed attributes
|
||||
for (name in attrs) {
|
||||
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);
|
||||
setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode, store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -715,6 +715,8 @@
|
|||
inst = new Component(props, context);
|
||||
inst.constructor = Ctor;
|
||||
inst.render = doRender;
|
||||
inst.store = Ctor.store();
|
||||
inst.store && (inst.store.update = inst.forceUpdate.bind(inst));
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
|
@ -729,8 +731,8 @@
|
|||
}
|
||||
|
||||
/** The `.render()` method for a PFC backing instance. */
|
||||
function doRender(props, state, context) {
|
||||
return this.constructor(props, context);
|
||||
function doRender(props) {
|
||||
return this.constructor(props, this.store);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -876,7 +878,7 @@
|
|||
|
||||
if (initialBase || renderMode === SYNC_RENDER) {
|
||||
if (cbase) cbase._component = null;
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true);
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true, component.store);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1108,7 +1110,7 @@
|
|||
* render(<Thing name="one" />, document.querySelector('#foo'));
|
||||
*/
|
||||
function render(vnode, parent, merge) {
|
||||
return diff(merge, vnode, {}, false, parent, false);
|
||||
return diff(merge, vnode, {}, false, typeof parent === 'string' ? document.querySelector(parent) : parent, false);
|
||||
}
|
||||
|
||||
function createRef() {
|
||||
|
@ -1136,7 +1138,7 @@
|
|||
Omi.h(
|
||||
'button',
|
||||
{ onClick: store.sub },
|
||||
'sub'
|
||||
'-'
|
||||
),
|
||||
Omi.h(
|
||||
'text',
|
||||
|
@ -1146,7 +1148,7 @@
|
|||
Omi.h(
|
||||
'button',
|
||||
{ onClick: store.add },
|
||||
'add'
|
||||
'+'
|
||||
)
|
||||
);
|
||||
};
|
||||
|
@ -1156,11 +1158,13 @@
|
|||
data: {
|
||||
count: 1
|
||||
},
|
||||
add: function add() {
|
||||
add: function add(e) {
|
||||
this.data.count++;
|
||||
this.update();
|
||||
},
|
||||
sub: function sub() {
|
||||
this.data.count--;
|
||||
this.update();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -3,9 +3,9 @@ import { render } from '../../src/omi'
|
|||
//逻辑store外置,UI只负责渲染
|
||||
const Counter = (props, store) => {
|
||||
return <div>
|
||||
<button onClick={store.sub}>sub</button>
|
||||
<button onClick={store.sub}>-</button>
|
||||
<text>{store.data.count}</text>
|
||||
<button onClick={store.add}>add</button>
|
||||
<button onClick={store.add}>+</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,13 @@ Counter.store = _ => {
|
|||
data: {
|
||||
count: 1
|
||||
},
|
||||
add() {
|
||||
this.data.count++
|
||||
add(e) {
|
||||
this.data.count++
|
||||
this.update()
|
||||
},
|
||||
sub() {
|
||||
this.data.count--
|
||||
this.data.count--
|
||||
this.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ export function removeNode(node) {
|
|||
* @param {boolean} isSvg Are we currently diffing inside an svg?
|
||||
* @private
|
||||
*/
|
||||
export function setAccessor(node, name, old, value, isSvg) {
|
||||
export function setAccessor(node, name, old, value, isSvg, store) {
|
||||
if (name==='className') name = 'class';
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ export function setAccessor(node, name, old, value, isSvg) {
|
|||
else {
|
||||
node.removeEventListener(name, eventProxy, useCapture);
|
||||
}
|
||||
(node._listeners || (node._listeners = {}))[name] = value;
|
||||
(node._listeners || (node._listeners = {}))[name] = value.bind(store);
|
||||
}
|
||||
else if (name!=='list' && name!=='type' && !isSvg && name in node) {
|
||||
// Attempt to set a DOM property to the given value.
|
||||
|
|
|
@ -18,5 +18,5 @@ import { diff } from './vdom/diff';
|
|||
* render(<Thing name="one" />, document.querySelector('#foo'));
|
||||
*/
|
||||
export function render(vnode, parent, merge) {
|
||||
return diff(merge, vnode, {}, false, parent, false);
|
||||
return diff(merge, vnode, {}, false, typeof parent === 'string' ? document.querySelector(parent) : parent, false);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ export function createComponent(Ctor, props, context) {
|
|||
inst = new Component(props, context);
|
||||
inst.constructor = Ctor;
|
||||
inst.render = doRender;
|
||||
inst.store = Ctor.store()
|
||||
inst.store && (inst.store.update = inst.forceUpdate.bind(inst))
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,6 +45,6 @@ export function createComponent(Ctor, props, context) {
|
|||
|
||||
|
||||
/** The `.render()` method for a PFC backing instance. */
|
||||
function doRender(props, state, context) {
|
||||
return this.constructor(props, context);
|
||||
function doRender(props) {
|
||||
return this.constructor(props, this.store);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ export function renderComponent(component, renderMode, mountAll, isChild) {
|
|||
|
||||
if (initialBase || renderMode===SYNC_RENDER) {
|
||||
if (cbase) cbase._component = null;
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true);
|
||||
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true, component.store);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export function flushMounts() {
|
|||
* @returns {import('../dom').PreactElement} The created/mutated element
|
||||
* @private
|
||||
*/
|
||||
export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
|
||||
export function diff(dom, vnode, context, mountAll, parent, componentRoot, store) {
|
||||
// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
|
||||
if (!diffLevel++) {
|
||||
// when first starting the diff, check if we're diffing an SVG or within an SVG
|
||||
|
@ -54,7 +54,7 @@ export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
|
|||
hydrating = dom!=null && !(ATTR_KEY in dom);
|
||||
}
|
||||
|
||||
let ret = idiff(dom, vnode, context, mountAll, componentRoot);
|
||||
let ret = idiff(dom, vnode, context, mountAll, componentRoot, store);
|
||||
|
||||
// append the element if its a new parent
|
||||
if (parent && ret.parentNode!==parent) parent.appendChild(ret);
|
||||
|
@ -79,7 +79,7 @@ export function diff(dom, vnode, context, mountAll, parent, componentRoot) {
|
|||
* @param {boolean} [componentRoot] ?
|
||||
* @private
|
||||
*/
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot) {
|
||||
function idiff(dom, vnode, context, mountAll, componentRoot, store) {
|
||||
let out = dom,
|
||||
prevSvgMode = isSvgMode;
|
||||
|
||||
|
@ -158,12 +158,12 @@ function idiff(dom, vnode, context, mountAll, componentRoot) {
|
|||
}
|
||||
// otherwise, if there are existing or new children, diff them:
|
||||
else if (vchildren && vchildren.length || fc!=null) {
|
||||
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML!=null);
|
||||
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML!=null, store);
|
||||
}
|
||||
|
||||
|
||||
// Apply attributes/props from VNode to the DOM Element:
|
||||
diffAttributes(out, vnode.attributes, props);
|
||||
diffAttributes(out, vnode.attributes, props, store);
|
||||
|
||||
|
||||
// restore previous SVG mode: (in case we're exiting an SVG namespace)
|
||||
|
@ -183,7 +183,7 @@ function idiff(dom, vnode, context, mountAll, componentRoot) {
|
|||
* @param {boolean} isHydrating if `true`, consumes externally created elements
|
||||
* similar to hydration
|
||||
*/
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) {
|
||||
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating, store) {
|
||||
let originalChildren = dom.childNodes,
|
||||
children = [],
|
||||
keyed = {},
|
||||
|
@ -238,7 +238,7 @@ function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) {
|
|||
}
|
||||
|
||||
// morph the matched/found/created DOM child to match vchild (deep)
|
||||
child = idiff(child, vchild, context, mountAll);
|
||||
child = idiff(child, vchild, context, mountAll, null, store);
|
||||
|
||||
f = originalChildren[i];
|
||||
if (child && child!==dom && child!==f) {
|
||||
|
@ -318,20 +318,20 @@ export function removeChildren(node) {
|
|||
* @param {object} old Current/previous attributes (from previous VNode or
|
||||
* element's prop cache)
|
||||
*/
|
||||
function diffAttributes(dom, attrs, old) {
|
||||
function diffAttributes(dom, attrs, old, store) {
|
||||
let name;
|
||||
|
||||
// remove attributes no longer present on the vnode by setting them to undefined
|
||||
for (name in old) {
|
||||
if (!(attrs && attrs[name]!=null) && old[name]!=null) {
|
||||
setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
|
||||
setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode, store);
|
||||
}
|
||||
}
|
||||
|
||||
// add new & update changed attributes
|
||||
for (name in attrs) {
|
||||
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);
|
||||
setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode, store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue