Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b8b87fa

Browse files
committed
Merge remote-tracking branch 'origin/bifrost-react-provider' into master
2 parents 958abfb + 9d37a17 commit b8b87fa

File tree

6 files changed

+111
-45
lines changed

6 files changed

+111
-45
lines changed

README.md

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ vuereact-combined将融合做到了极致,支持了大部分的Vue和React组
3030
normal prop (vue / react) | ✔ | ✔ |
3131
event (vue / react) | ✔ | ✔ |
3232
children (vue / react) | ✔ | ✔ |
33+
Provider/Consumer in vue (react) | ✔ | |
3334
named slots (vue) | ✔ | |
3435
scope slots (vue) | ✔ | |
3536
v-model (vue) | ✔ | |
@@ -248,14 +249,17 @@ export default function() {
248249
<template>
249250
<ReactComponentInVue>
250251
我是普通children
252+
<!-- 等同于向react组件传入 slotA={<span>我是ReactNode类型的slotA属性</span>} -->
251253
<template v-slot:slotA>
252-
我是ReactNode类型的slotA属性
254+
<span>我是ReactNode类型的slotA属性</span>
253255
</template>
256+
<!-- 等同于向react组件传入 slotB={<span>我是ReactNode类型的slotA属性</span>} -->
254257
<template v-slot:slotB>
255-
我是ReactNode类型的slotB属性
258+
<span>我是ReactNode类型的slotB属性</span>
256259
</template>
260+
<!-- 等同于向react组件传入 slotC={(context) => <span>我是renderProps类型:{{context.value}}</span>} -->
257261
<template v-slot:slotC="context">
258-
我是renderProps类型:{{context.value}}
262+
<span>我是renderProps类型:{{context.value}}</span>
259263
</template>
260264
</ReactComponentInVue>
261265
</template>
@@ -265,14 +269,45 @@ import { applyReactInVue } from 'vuereact-combined'
265269
// 一个开放ReactNode类型属性和renderProps类型属性的React组件
266270
import ReactComponent from './ReactComponent'
267271
export default {
268-
name: 'demo2',
269272
components: {
270273
ReactComponentInVue: applyReactInVue(ReactComponent)
271274
}
272275
}
273276
</script>
274277
```
275278
applyReactInVue会将ReactNode类型的属性转会为Vue的具名插槽,将renderProps类型的属性转换为作用域插槽,具名插槽和作用域插槽的插槽名就是属性名
279+
## 在Vue组件中调用React组件的Context/Provider
280+
```vue
281+
<!--Vue File-->
282+
<template>
283+
<MyProvider :value="content">
284+
<Button>Vue按钮</Button>
285+
<!-- React组件中可以正常的使用Consumer消费Context -->
286+
<ReactComponentInVue/>
287+
</MyProvider>
288+
</template>
289+
290+
<script>
291+
import { applyReactInVue } from 'vuereact-combined'
292+
// React Context
293+
import MyContext from "./MyContext"
294+
import {Button} from 'element-ui'
295+
import ReactComponent from './ReactComponent'
296+
export default {
297+
data() {
298+
return {
299+
content: 'hahahahaha!'
300+
}
301+
},
302+
components: {
303+
Button,
304+
ReactComponentInVue: applyReactInVue(ReactComponent),
305+
// 把Provider当作React组件直接转换
306+
MyProvider: applyReactInVue(MyContext.Provider),
307+
}
308+
}
309+
</script>
310+
```
276311
## 在React组件中使用Vue的动态组件
277312
```jsx
278313
// React JSX File
@@ -505,13 +540,17 @@ const VueComponentInReact = applyVueInReact(VueComponent, {
505540
// react.componentWrapAttrs代表是vue组件在react组件中的组件包囊层的标签设置
506541
// 以下设置将设置组件的包囊层div的display为inline-block
507542
componentWrapAttrs: {
508-
style: 'display:inline-block',
543+
style: {
544+
display: 'inline-block'
545+
},
509546
class: 'react-wrap-vue-component-1'
510547
},
511548
// react.slotWrapAttrs代表是vue组件在react组件中的插槽包囊层的标签设置
512549
// 以下设置将设置插槽的包囊层div的display为inline-block
513550
slotWrapAttrs: {
514-
style: 'display:inline-block'
551+
style: {
552+
display: 'inline-block'
553+
}
515554
},
516555
},
517556
})
@@ -525,9 +564,15 @@ const originOptions = {
525564
slotWrap: 'div',
526565
componentWrapAttrs: {
527566
__use_react_component_wrap: '',
567+
style: {
568+
all: 'unset'
569+
}
528570
},
529571
slotWrapAttrs: {
530572
__use_react_slot_wrap: '',
573+
style: {
574+
all: 'unset'
575+
}
531576
}
532577
},
533578
vue: {
@@ -540,9 +585,15 @@ const originOptions = {
540585
},
541586
componentWrapAttrs: {
542587
'data-use-vue-component-wrap': '',
588+
style: {
589+
all: 'unset',
590+
}
543591
},
544592
slotWrapAttrs: {
545593
'data-use-vue-slot-wrap': '',
594+
style: {
595+
all: 'unset'
596+
}
546597
}
547598
}
548599
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vuereact-combined",
33
"private": false,
4-
"version": "0.4.2",
4+
"version": "1.0.0",
55
"description": "Vue和React快捷集成的工具包,并且适合复杂的集成场景",
66
"main": "dist/vuereact.umd.js",
77
"scripts": {

src/applyReactInVue.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ const createReactContainer = (Component, options, wrapInstance) => class applyRe
120120
if ((Object.getPrototypeOf(Component) !== Function.prototype && !(typeof Component === "object" && !Component.render)) || applyReact.catchVueRefs()) {
121121
refInfo.ref = this.setRef
122122
return (
123-
<Component {...props}
124-
{...{ "data-passed-props": __passedProps }} {...refInfo}>
125-
{children}
126-
</Component>
123+
<Component {...props}
124+
{...{ "data-passed-props": __passedProps }} {...refInfo}>
125+
{children}
126+
</Component>
127127
)
128128
}
129129
const newProps = { ...props, ...{ "data-passed-props": __passedProps } }
@@ -225,14 +225,14 @@ export default function applyReactInVue(component, options = {}) {
225225
if (!update) {
226226
const Component = createReactContainer(component, options, this)
227227
let reactRootComponent = <Component
228-
{...__passedPropsRest}
229-
{...this.$attrs}
230-
{...__passedProps.on}
231-
{...{ children }}
232-
{...lastNormalSlots}
233-
{...scopedSlots}
234-
{...{ "data-passed-props": __passedProps }}
235-
ref={(ref) => (this.reactInstance = ref)}
228+
{...__passedPropsRest}
229+
{...this.$attrs}
230+
{...__passedProps.on}
231+
{...{ children }}
232+
{...lastNormalSlots}
233+
{...scopedSlots}
234+
{...{ "data-passed-props": __passedProps }}
235+
ref={(ref) => (this.reactInstance = ref)}
236236
/>
237237
// 必须通过ReactReduxContext连接context
238238
if (this.$redux && this.$redux.store && this.$redux.ReactReduxContext) {
@@ -246,6 +246,10 @@ export default function applyReactInVue(component, options = {}) {
246246
let reactWrapperRef
247247
// 向上查找react包囊层
248248
while (parentInstance) {
249+
if (parentInstance.parentReactWrapperRef) {
250+
reactWrapperRef = parentInstance.parentReactWrapperRef
251+
break
252+
}
249253
if (parentInstance.reactWrapperRef) {
250254
reactWrapperRef = parentInstance.reactWrapperRef
251255
break
@@ -258,15 +262,15 @@ export default function applyReactInVue(component, options = {}) {
258262
this.parentReactWrapperRef = reactWrapperRef
259263
// 存储portal引用
260264
this.reactPortal = () => ReactDOM.createPortal(
261-
reactRootComponent,
262-
container
265+
reactRootComponent,
266+
container
263267
)
264268
reactWrapperRef.pushPortal(this.reactPortal)
265269
return
266270
}
267271
ReactDOM.render(
268-
reactRootComponent,
269-
container
272+
reactRootComponent,
273+
container
270274
)
271275
})
272276
} else {

src/applyVueInReact.js

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const VueContainer = React.forwardRef((props, ref) => {
6060
const TargetComponent = reactRouterInfo.withRouter(GetReactRouterPropsCom)
6161
// withRouter方法是通过wrappedComponentRef来传递ref的
6262
return (
63-
<TargetComponent {...{...props, [optionsName]: globalOptions}} forwardRef={ref} />
63+
<TargetComponent {...{...props, [optionsName]: globalOptions}} forwardRef={ref} />
6464
)
6565
} else {
6666
return <VueComponentLoader {...{...props, [optionsName]: globalOptions}} ref={ref}/>
@@ -353,12 +353,12 @@ class VueComponentLoader extends React.Component {
353353
}, ...props } = this.$data
354354
filterNamedSlots(__passedPropsScopedSlots, __passedPropsSlots)
355355
// 作用域插槽的处理
356-
let scopedSlots = this.getScopedSlots(createElement, { ...__passedPropsScopedSlots, ...$scopedSlots })
357-
let lastChildren = this.getChildren(createElement, this.children || __passedPropsChildren)
356+
const scopedSlots = this.getScopedSlots(createElement, { ...__passedPropsScopedSlots, ...$scopedSlots })
357+
const lastChildren = this.getChildren(createElement, this.children || __passedPropsChildren)
358358
// 获取插槽数据(包含了具名插槽)
359-
let namedSlots = this.getNamespaceSlots(createElement, { ...__passedPropsSlots, ...$slots })
359+
const namedSlots = this.getNamespaceSlots(createElement, { ...__passedPropsSlots, ...$slots })
360360
if (lastChildren) namedSlots.default = lastChildren
361-
let lastSlots = [
361+
const lastSlots = [
362362
(lastChildren || []),
363363
...Object.keys(namedSlots).map((key) => {
364364
if (key === 'default') {
@@ -367,12 +367,13 @@ class VueComponentLoader extends React.Component {
367367
return namedSlots[key]
368368
})
369369
]
370-
let lastOn = { ...__passedPropsOn, ...on }
370+
const lastOn = { ...__passedPropsOn, ...on }
371+
const nativeOn = {}
371372

372373
// 解决原生事件
373374
Object.keys(props).forEach((keyName) => {
374375
if (REACT_ALL_HANDLERS.has(keyName) && typeof props[keyName] === 'function') {
375-
lastOn[keyName.replace(/^on/, '').toLowerCase()] = props[keyName]
376+
nativeOn[keyName.replace(/^on/, '').toLowerCase()] = props[keyName]
376377
delete props[keyName]
377378
}
378379
})
@@ -393,21 +394,19 @@ class VueComponentLoader extends React.Component {
393394

394395
// 手动把props丛attrs中去除,
395396
// 这一步有点繁琐,但是又必须得处理
396-
let attrs = filterAttrs({ ...lastProps })
397-
// setTimeout(() => {
398-
// this.$children[0] && this.$children[0] && this.$children[0].$forceUpdate()
399-
// },500)
397+
const attrs = filterAttrs({ ...lastProps })
400398
return createElement(
401-
'use_vue_wrapper',
402-
{
403-
props: lastProps,
404-
on: lastOn,
405-
attrs,
406-
'class': className,
407-
style,
408-
scopedSlots: { ...scopedSlots }
409-
},
410-
lastSlots
399+
'use_vue_wrapper',
400+
{
401+
props: lastProps,
402+
on: lastOn,
403+
nativeOn,
404+
attrs,
405+
'class': className,
406+
style,
407+
scopedSlots: { ...scopedSlots }
408+
},
409+
lastSlots
411410
)
412411
},
413412
components: {

src/options.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ const originOptions = {
66
slotWrap: 'div',
77
componentWrapAttrs: {
88
__use_react_component_wrap: '',
9+
style: {
10+
all: 'unset'
11+
}
912
},
1013
slotWrapAttrs: {
1114
__use_react_slot_wrap: '',
15+
style: {
16+
all: 'unset'
17+
}
1218
}
1319
},
1420
vue: {
@@ -21,9 +27,15 @@ const originOptions = {
2127
},
2228
componentWrapAttrs: {
2329
'data-use-vue-component-wrap': '',
30+
style: {
31+
all: 'unset',
32+
}
2433
},
2534
slotWrapAttrs: {
2635
'data-use-vue-slot-wrap': '',
36+
style: {
37+
all: 'unset'
38+
}
2739
}
2840
}
2941
}

0 commit comments

Comments
 (0)