tab中使用datepick不显示
NutUI React 包名
@nutui/nutui-react
NutUI React 版本号
2.6.22
平台
weapp
重现链接
https://codesandbox.io/p/devbox/blissful-panna-4cl8kf?file=%2Fsrc%2FApp.tsx%3A32%2C28
重现步骤
- 新增多个tab及tabpane
- 在非首个tabpane中新增datepicker
- 点击弹出datepicker不显示
期望的结果是什么?
在当前tabpane正常弹出datepicker或者popup及ActionSheet。
实际的结果是什么?
当前tabpane中datepick不显示且只在首个tabpane中显示。
环境信息
Taro CLI 4.0.6 environment info: System: OS: macOS 10.15.7 Shell: 5.7.1 - /bin/zsh Binaries: Node: 16.20.2 - ~/.volta/tools/image/node/16.20.2/bin/node Yarn: 3.8.6 - ~/.volta/tools/image/yarn/3.8.6/bin/yarn npm: 8.19.4 - ~/.volta/tools/image/node/16.20.2/bin/npm npmPackages: @tarojs/cli: 4.0.6 => 4.0.6 @tarojs/components: 4.0.6 => 4.0.6 @tarojs/helper: 4.0.6 => 4.0.6 @tarojs/plugin-framework-react: 4.0.6 => 4.0.6 @tarojs/plugin-html: 4.0.6 => 4.0.6 @tarojs/plugin-platform-alipay: 4.0.6 => 4.0.6 @tarojs/plugin-platform-h5: 4.0.6 => 4.0.6 @tarojs/plugin-platform-jd: 4.0.6 => 4.0.6 @tarojs/plugin-platform-qq: 4.0.6 => 4.0.6 @tarojs/plugin-platform-swan: 4.0.6 => 4.0.6 @tarojs/plugin-platform-tt: 4.0.6 => 4.0.6 @tarojs/plugin-platform-weapp: 4.0.6 => 4.0.6 @tarojs/react: 4.0.6 => 4.0.6 @tarojs/runtime: 4.0.6 => 4.0.6 @tarojs/shared: 4.0.6 => 4.0.6 @tarojs/taro: 4.0.6 => 4.0.6 @tarojs/taro-loader: 4.0.6 => 4.0.6 @tarojs/webpack5-runner: 4.0.6 => 4.0.6 babel-preset-taro: 4.0.6 => 4.0.6 eslint-config-taro: 4.0.6 => 4.0.6 react: ^18.0.0 => 18.3.1
其他补充信息
No response
popup 系列组件都这样
猜测应该是 fixed 定位的元素在父元素存在 transform 等属性时降级成 absolute 定位了...可以通过手动设置 portal 解决。
对于 DatePicker:
<DatePicker
pickerProps={{
popupProps: {
portal: () => document.body,
},
}}
/>
对于其他popup类组件,都只要设置 portal 属性即可,在线调试:https://codesandbox.io/p/devbox/young-water-stcf2t。
才发现这个问题之前已经有了 #2405
如果是taro开发小程序的话可以类似这样,应该适用于所有popup类组件:
import { useState } from 'react';
import { DatePicker } from '@nutui/nutui-react-taro';
export default function Demo() {
const [dom, setDom] = useState(null);
useEffect(() => {
const _dom = document.getElementById("mount-container");
setDom(_dom);
}, []);
return (
<DatePicker
pickerProps= {dom ? {
popupProps: {
portal: () => dom,
},
} : undefined}
/>
)
}
然后就是挂载的节点 mount-container 最好放置到当前使用 DatePicker 的小程序页面的最外层,且确保 mount-container 本身没有设置 transform perspective 之类的样式
<>
<Demo />
<OtherComponents/ >
<View id="mount-container"></View>
</>
如果是taro开发小程序的话可以类似这样,应该适用于所有popup类组件:
import { useState } from 'react'; import { DatePicker } from '@nutui/nutui-react-taro'; export default function Demo() { const [dom, setDom] = useState(null); useEffect(() => { const _dom = document.getElementById("mount-container"); setDom(_dom); }, []); return ( <DatePicker pickerProps= {dom ? { popupProps: { portal: () => dom, }, } : undefined} /> ) }然后就是挂载的节点
mount-container最好放置到当前使用DatePicker的小程序页面的最外层,且确保mount-container本身没有设置transformperspective之类的样式<> <Demo /> <OtherComponents/ > <View id="mount-container"></View> </>
DatePicker放到Tabs同一层级即可,但是TabPane内是组件还需要多一步传递参数才行比较麻烦。另外如果不同TabPane高度不同,来回切换TabPane由于外出被撑开了只会有最大TabPane的高度也会有问题,为什么不考虑用display: block|none控制,非得translate不可呢。
这是我司在Taro平台用的RootPortal,提供一个参考
const RyanRootPortal = (props: { children: ReactNode }) => {
const router = useRouter();
const [dom, setDom] = useState<TaroElement | HTMLElement>();
useLayoutEffect(() => {
if (router.$taroPath) {
const _dom = document.getElementById(router.$taroPath);
_dom && setDom(_dom);
}
return () => setDom(undefined);
}, [router.$taroPath]);
return <>{dom && createPortal(props.children, dom as TaroElement)}</>;
};