地址管理页面,引用了 地址列表组件。
现在需要点击组件中的按钮,在页面中跳出弹窗继续操作。需要实现的效果如图:
目前,把popup的相关代码放在组件中,可以实现其效果及功能,但弹窗出现在组件的框架范围内,而不是出现在页面中。(代码在下面)
如果把popup代码写在页面中,点击组件时不会跳出弹窗,组件中的点击操作没有传到页面中,这里的操作可以怎么做吗?组件内的数据传到页面中可以怎么写代码呢?
列表组件代码(AddressItem):
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import {
View,
Text,
Image,
navigateTo,
} from 'remax/wechat';
import request from '@/utils/request'
import { clearSearchBase64Url } from '@/actions/common'
import { connect } from 'react-redux';
import * as utils from '@/utils/common';
import useSysInfo from '../../hooks/sysInfo'
import { Popup } from 'annar';
import styles from './index.css';
import classnames from 'classnames';
const AddressItem = memo(function (props) {
const {
delCb,
} = props;
const { id, user_id, phone, name, area, address, is_default } = props;
const [isShowModal, setIsShowModal] = useState(false);
const [ShowModal, setShowModal] = useState(false);
const sysInfo = useSysInfo();
const defaults = parseInt(is_default)
const getdelUserAddress = useCallback(() => {
return request({
url: '/delUserAddress',
method: 'post',
data: {
id: id
},
success: function () {
delCb(id)
wx.showToast({
title: '删除成功',
icon: 'success'
})
}
})
})
return (
<View className={styles.have}>
<View className={styles.addchoose}>
<Text>{name}</Text><Text>{phone}</Text>
{
(defaults)
? <View className={styles.default}>默认</View>
: null
}
<View className={styles.details}>{area}{address}</View>
<Image src='http://dxshy.duxieshe.com/uploads/applet_img/more.png'
onTap={() => {
setIsShowModal(true)
}}
/>
</View>
<Popup
position="bottom"
open={isShowModal}
onClose={() => {
setIsShowModal(false)
}}>
<View style={{ paddingBottom: sysInfo.safeBottomHeight + 'PX' }}>
<View className={styles.background}>
<View className={styles.operate}
style={{ "color": "#000000" }}
onTap={() => {
navigateTo({
url: '/packagePagesE/address/editadr/index?userId=' + id
})
setIsShowModal(false)
}}
>编辑</View>
<View className={styles.smaline}></View>
<View className={styles.operate}
style={{ "color": "#FF0000" }}
onTap={() => {
setShowModal(true)
setIsShowModal(false)
}}
>删除</View>
<View className={styles.larline}></View>
<View className={styles.operate}
style={{ "color": "#000000" }}
onTap={() => {
setIsShowModal(false)
}}>取消</View>
</View>
</View>
</Popup>
<Popup
open={ShowModal}
onClose={() => {
setShowModal(false)
}}>
<View className={styles.Modal}>
<View className={styles.wxts}>温馨提示</View>
<Text>删除后数据不可恢复,</Text>
<Text>确定要删除吗?</Text>
<View className={styles.btn}>
<View className={styles.left} onTap={() => {
setShowModal(false)
}}>取消</View>
<View className={styles.right} onTap={() => {
setShowModal(false)
getdelUserAddress()
}}>确认删除</View>
</View>
</View>
</Popup>
</View>
)
})
AddressItem.propTypes = {
id: PropTypes.string.isRequired,
user_id: PropTypes.string.isRequired,
phone: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
area: PropTypes.string.isRequired,
address: PropTypes.string.isRequired,
is_default: PropTypes.string.isRequired
}
AddressItem.defaultProps = {
address: ''
}
const mapStateToProps = (state) => {
const { userInfo } = state.common
return {
userInfo
}
}
const mapDispatchToProps = (dispatch) => {
return {
clearSearchBase64Url: () => {
dispatch(clearSearchBase64Url())
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AddressItem);
地址管理主页代码(address.js):
import React, { useEffect, memo, useState, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {
View,
Text,
Image,
ScrollView,
setClipboardData,
navigateTo,
showLoading,
hideLoading,
} from 'remax/wechat';
import { connect } from 'react-redux';
import { Popup } from 'annar';
import Nav from '@/components/nav';
import Tabbar from '@/components/tabbar';
import request from '@/utils/request';
import useSysInfo from '../../../hooks/sysInfo'
import useBackEvent from '@/hooks/navEvent'
import AddressItem from '@/components/addressItem';
import styles from './index.css';
import { getSysConf } from '../../../actions/common';
import { setList, setCollectStatus } from '../../../actions/dynamic'
const Address = function (props) {
const { currentTab } = props;
const [refreshTriggered, setRefreshTriggered] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const { getSysConf, sysConf, userInfo } = props;
const [isShowModal, setIsShowModal] = useState(false);
const [ShowModal, setShowModal] = useState(false);
const [hasData, setHasData] = useState(true);
const [list, setList] = useState();
const [page, setPage] = useState(1);
const sysInfo = useSysInfo();
useEffect(() => {
getSysConf()
}, [])
const {
homeAction,
backAction
} = useBackEvent(currentTab);
// const Cancel = () => {
// setShowModal(false)
// wx.showToast({
// title: '删除成功',
// icon: 'success'
// })
// }
const loadList = useCallback((passPage) => {
return request({
url: '/getUserAddressList',
method: 'get',
data: {
page: passPage ? passPage : page,
limit: 10
}
})
}, [page])
const init = useCallback(async () => {
if (isLoading) return;
const page = 1;
setPage(page);
setHasData(true);
setIsLoading(true);
const list = await loadList(page);
setIsLoading(false);
setPage(prevPage => prevPage + 1);
setList(list);
setRefreshTriggered(false)
if (list.length < 10) {
setHasData(false);
}
console.log('list', list);
}, [isLoading, page]);
const loadMore = useCallback(() => {
if (isLoading) return;
if (hasData) {
setIsLoading(true)
loadList().then(moreData => {
setList(preList => preList.concat(moreData))
setPage(prev => prev + 1);
setIsLoading(false)
})
} /* else {
wx.showToast({
title: '没有更多了~',
icon: 'none'
})
} */
}, [page, hasData, isLoading])
useEffect(() => {
init();
}, [])
useEffect(() => {
if (isLoading) {
showLoading({
title: '加载中',
mask: true
})
} else {
hideLoading()
}
}, [isLoading])
return (
sysConf &&
<View className={styles.personal} style={{ height: sysInfo.safeArea.bottom + 'PX' }}>
<Nav
title="地址管理"
goIndex={homeAction}
onBack={backAction}
showLeftFunc={true} />
<View className={styles.main}>
<View className={styles.add} onTap={() => {
navigateTo({
url: '/packagePagesE/address/addadr/index'
})
}}>
<Image src='http://dxshy.duxieshe.com/uploads/applet_img/add_green.png' />
<Text>添加收货地址</Text>
</View>
{
(list && list.length > 0) ?
<ScrollView
className={styles.list}
scrollY
refresherEnabled
refresherTriggered={refreshTriggered}
lowerThreshold={60}
bindscrolltolower={loadMore}
bindrefresherrefresh={() => {
setRefreshTriggered(true)
init();
}}>
<View className={styles.have}>
<View className={styles.txt}>轻触以选择地址</View>
{
list.map((v, i) => {
return (
<AddressItem key={i} {...v} />
)
})
}
</View>
</ScrollView>
: Array.isArray(list) ?
<View className={styles.none}>
<Image src='http://dxshy.duxieshe.com/uploads/applet_img/none_02.png' />
<Text>暂无收货地址~</Text>
</View>
: null
}
</View>
//弹窗
{/* <Popup
position="bottom"
open={isShowModal}
onClose={() => {
setIsShowModal(false)
}}
>
<View style={{ paddingBottom: sysInfo.safeBottomHeight + 'PX' }}>
<View className={styles.background}>
<View className={styles.operate}
style={{ "color": "#000000" }}
onTap={() => {
navigateTo({
url: '/packagePagesE/address/editadr/index'
})
setIsShowModal(false)
}}
>编辑</View>
<View className={styles.smaline}></View>
<View className={styles.operate}
style={{ "color": "#FF0000" }}
onTap={() => {
setShowModal(true)
setIsShowModal(false)
}}
>删除</View>
<View className={styles.larline}></View>
<View className={styles.operate}
style={{ "color": "#000000" }}
onTap={() => {
setIsShowModal(false)
}}>取消</View>
</View>
</View>
</Popup>
<Popup
open={ShowModal}
onClose={() => {
setShowModal(false)
}}>
<View className={styles.Modal}>
<View className={styles.wxts}>温馨提示</View>
<Text>删除后数据不可恢复,</Text>
<Text>确定要删除吗?</Text>
<View className={styles.btn}>
<View className={styles.left} onTap={() => {
setShowModal(false)
}}>取消</View>
<View className={styles.right} onTap={() => {
Cancel()
}}>确认删除</View>
</View>
</View>
</Popup> */}
</View >
)
}
const mapStateToProps = (state) => {
const { sysConf, userInfo } = state.common;
return {
sysConf,
userInfo
}
}
const mapDispatchToProps = (dispatch) => {
return {
getSysConf: (conf) => {
dispatch(getSysConf(conf))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Address)
用的Taro 就简单了,组件写在页面,点击其他组件 事件传到父组件就可以了
看起来是子组件向父组件传值的问题。
1.父组件里写弹窗的函数,比如说 showModal()
2.子组件里调用 this.props.showModal(data),把数据传过去。
showModal(data){
console.log('获取子组件数据',data)
setIsShowModal(true)
}