taro/taro3,H5动态加载自定义组件
一、taro-H5,在html上加div
const div = document.createElement('div')
div.id = 'testdiv'
document.body.append(div)
这样就是最简单的在body下创建一个div。
然后去除这个div:
document.body.removeChild(document.getElementById(id))
document.body._component = undefined
二、自定义taro组件动态加载到div下
1、taro3之前
taro的源码,如showToast、showModal都是用document.createElement()然后document.append()方式将自定义的样式组件加载到body里,但对于编译过后的taro项目,可以用Nerv.render(),如:
import Nerv from 'nervjs'
Nerv.render(selfDfnView, targetView)
其中selfDfnView为自定义的taroview,如:
class TestPop extends TQPrism.Component{
render () {
return (
<View>
测试pop组件
</View>
)
}
}
通过
Nerv.render(<TestPop/>, document.body)
通过position:fixed样式,就可以把自定义的组件通过方法动态渲染到页面上了。其中targetView可以通过document.getElementById(id)指定到当前页面,防止当前页面跳转了,组件还是显示在页面上。
2、taro3之后:
由于taro3集成了react,view的加载渲染不能通过Nerv.render,可以换成react自带的:
import ReactDOM from 'react-dom'
ReactDOM.render(selfDfnView, targetView)
其中targetView不能用document.body,整个body下的路由组件都会被替换为自定义的组件,可以在body下先加个div,再在这个div下渲染自定义组件,但是一般情况下,组件应当指定到当前页面,防止当前页面跳转了,组件还是显示在页面上。
showDiyView: (view, id) => {
let page = document.getElementById(Taro.getCurrentInstance().page.path)
let cell = document.createElement('div')
cell.id = `cell-${id}`
ids.push(id)
page.appendChild(cell)
ReactDOM.render(view, cell)
},
三、改变组件的状态(触发componentWillReceiveProps)
自定义组件,一般都是要动态显示,操作更改数据状态,然后关闭。若要通过组件的props去改变组件的state或重新渲染组件,即触发组件的componentWillReceiveProps。
1、taro3之前:
可以直接重新Nerv.render(selfDfnView, targetView)去渲染组件触发;
2、taro3之后:
ReactDOM.render(selfDfnView, targetView),注意targetView一定要与初始渲染时指定id一致,要不会重新渲染一个组件。
四、隐藏或去除组件
通过targetView.removeChild()方法将渲染的自定义组件去除
targetView.removeChild(document.getElementById(id))
targetView._component = undefined
五、方法集成
1、taro3之前
showDiyView: (view) => {
Nerv.render(view, document.body)
}
hiddenDiyView: (id) => {
document.body.removeChild(document.getElementById(id))
document.body._component = undefined
}
2、taro3之后
showDiyView: (view, id) => {
let page = document.getElementById(Taro.getCurrentInstance().page.path)
let cell = document.createElement('div')
cell.id = `cell-${id}`
ids.push(id)
page.appendChild(cell)
ReactDOM.render(view, cell)
},
changeDiyView: (view, id)=> {
let cell = document.getElementById(`cell-${id}`)
ReactDOM.render(view, cell)
}
hiddenDiyView: id => {
let page = document.getElementById(Taro.getCurrentInstance().page.path)
page.removeChild(document.getElementById(`cell-${id}`))
}
3、例子
selOrg: () => {
return new Promise((resolve, reject) => {
const view = (isOpen) => {
return (
<SelOrgPopup
isOpen={isOpen}
id={'selorg'}
onClickClose={() => close()}
onClickSure={value => {
resolve(value)
close()
}}
/>
)
}
const close = () => {
PrismUtil.showDiyView(view(false))
setTimeout(() => {
document.body.removeChild(document.getElementById('selorg'))
document.body._component = undefined
}, 300)
}
PrismUtil.showDiyView(view(false))
PrismUtil.showDiyView(view(true))
})
}
taro3在更改组件状态用changeDiyView()方法
/**
* 显示用户信息
*/
showUserModal: (userName: string) => {
const viewId = 'usermodal'
const view = (isOpen: boolean) => {
return (
<UserModal
isOpen={isOpen}
id={viewId}
onClose={() => close()}
userName={userName}
/>
)
}
const close = () => {
ComponentUtil.changeDiyView(view(false), viewId)
setTimeout(() => {
ComponentUtil.hiddenDiyView(viewId)
}, 300)
}
ComponentUtil.showDiyView(view(false), viewId)
setTimeout(() => {
ComponentUtil.changeDiyView(view(true), viewId)
}, 1)
},