- 如何正确显示接口中的文字内容?
连接接口中的数据,打印出来一堆乱码还是代码的东西,要怎么正确显示它的内容呢? [图片] [图片] [图片] 接口代码: const articleDetails = useCallback((passPage) => { return request({ url: '/articleDetails', method: 'get', data: { type:1, id:212 }, success: function(res) { console.log(res) userInfo.content=res.data.data.content console.log(userInfo.content) } }) }, [page]) 页面显示: <Text>{userInfo.content}</Text>
2022-11-14 - 使用navigateTo传递数据,报错getOpenerEventChannel,是哪句代码少了吗?
地址列表编辑修改页面,传递A页面信息到B页面进行编辑,后再返回A页面显示。 使用的wx.navigateTo进行传递,报错信息为“Cannot read property 'getOpenerEventChannel' of undefined”,是不是少了定义getOpenerEventChannel?应该怎么改呢? [图片] [图片]
2022-11-10 - 点击组件内部的按钮可以在页面中跳出弹窗吗?
地址管理页面,引用了 地址列表组件。 现在需要点击组件中的按钮,在页面中跳出弹窗继续操作。需要实现的效果如图: [图片] 目前,把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)
2022-11-09 - 自定义组件怎么获取接口中的数据?
需要实现 地址管理 功能,写了一个自定义组件<AddressItem>,目前代码能正确引用该组件,但并没有连接接口数据;若给组件列表数据替换上接口中的数据,开发者工具就报错。请问这样的组件接口参数要如何调用? 下图为需实现效果: [图片] 接口: [图片] 报错信息 [图片] 组件代码: [图片] [图片] 地址首页代码: [图片] [图片]
2022-11-07 - 底部栏部分机型不是在最底部是为什么?
开发过程中没有出现这个问题,真机调试和体验版都是好好的,发布之后发现部分机型的底部栏有bug,会有空行,这是为什么? [图片] [图片] vivo机型又是正常显示的底部栏。
2022-10-31 - 小程序关于用户点击“收藏”与“取消收藏”的问题?引用自定义组件时数据如何不出错?
做了一个关于商家动态列表的自定义组件,同时有三四个页面(商家主页、商家动态、我的收藏)引用,怎么让每个页面的“是否收藏”数据不出错? 目前, 商家主页 问题:(简单来说就是 表示“是否收藏”的数据不同步,状态与实际相反) 进入页面时全部显示“未收藏”状态(不管是否收藏) 点击第一下“收藏”按钮,按钮状态没有变化(查看后台数据为已收藏),点击第二下按钮变为“已收藏”(后台数据为取消收藏) [图片] 商家动态 页面问题: 点击页面 所有动态列表状态为 “未收藏”(不管后台数据是否为 收藏) 保留delCb(id, collect) 则商家动态页面不能正常展示 收藏 与 取消收藏 功能 删除delCb(id, collect) 则功能正常,但刷新页面后,依旧变成“未收藏”状态(后台数据为 已收藏) [图片] 我的收藏 页面:(此页面的 是否收藏 状态正常显示) 保留delCb(id, collect) 则取消收藏时列表自动删除 删除delCb(id, collect) 则取消收藏后需手动刷新一下,列表才能消失 [图片] 自定义组件代码: import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { View, Text, Image, showLoading, hideLoading, showToast, saveImageToPhotosAlbum, showModal, openSetting, getImageInfo, setClipboardData, redirectTo, navigateTo, ad } 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 styles from './index.css'; import classnames from 'classnames'; const SearchItem = memo(function (props) { const { dynamic: { dynamic_img, dynamic_title, nickname, user_id, id, head_img, date, img_url, cover_img, is_favorites }, contactCb, delCb, clearSearchBase64Url, isBusiness, userInfo, adUnitId } = props; const dynamicArr = dynamic_img.split('|'); const [collect, setCollect] = useState(); useEffect(() => { setCollect(parseInt(is_favorites)) // setCollect(is_favorites) }, [is_favorites]) const addCollect = useCallback((e) => { e.stopPropagation(); if (!userInfo) { navigateTo({ url: '/packagePagesC/pages/sub/login/index' }) return } request({ url: '/dynamicFavorites', data: { dynamic_id: id }, origin: true, method: 'post' }).then(res => { if (res.code === 0) { showToast({ title: collect ? '取消收藏' : '收藏成功', icon: 'none' }) delCb(id, collect) //注意!!!!!!!不加这一行,“我的收藏”页面取消收藏时,不能自动删除列表,需要手动刷新; //但是 加了这一行,开发者工具报错(如下图),且下一行代码不运行。 setCollect(prev => prev === 0 ? 1 : 0); return; } throw new Error('操作失败') }).catch(e => { showToast({ title: e, icon: 'none' }) }) }, [collect, userInfo]) const saveMultPicToLocal = useCallback(async (e) => { e.stopPropagation() showLoading({ title: '正在保存图片', mask: true }) try { for (let img of dynamicArr) { await getImageInfo({ src: img }).then(ret => { saveImageToPhotosAlbum({ filePath: ret.path, }) }).catch(e => { console.log(e) }) } hideLoading() showModal({ title: '商品描述已复制,图片已保存,打开朋友圈手动发布即可' }).then(res => { if (res.confirm) { setClipboardData({ data: dynamic_title }) } }) } catch (e) { if (e.errMsg === 'saveImageToPhotosAlbum:fail auth deny') { showModal({ title: '请打开保存图片到相册的权限' }).then(res => { if (res.confirm) { openSetting().then(({ authSetting }) => { if (authSetting['scope.writePhotosAlbum']) { saveMultPicToLocal() } }) } }) } else { showToast({ title: '保存失败', icon: 'none' }) } } }, [dynamic_title]) const dynamiCls = classnames([styles.dynamic], { [styles.grey]: date === '置顶' }) if (!id) { return ( <ad unit-id={adUnitId} binderror={(err) => { console.log(err) }}></ad> ) }; return ( <View className={dynamiCls} onTap={() => { clearSearchBase64Url() navigateTo({ url: '/packagePagesC/pages/sub/detail/index?dynamicId=' + id }) }}> <View className={styles.imgWrapper}> <Image src={cover_img || dynamicArr[0]} mode="aspectFill" /> <Text>{dynamicArr.length}</Text> </View> <View className={styles.info}> { !isBusiness && <View className={styles.infoHeader}> <View className={styles.infoLeft} onTap={(e) => { e.stopPropagation(); clearSearchBase64Url() navigateTo({ url: '/packagePagesC/pages/sub/business/index?userId=' + user_id }) }}> <Image src={head_img} /> <Text>{nickname}</Text> </View> <Text onTap={(e) => { e.stopPropagation(); contactCb({ ...props.dynamic, userId: props.dynamic.user_id }) }}>联系TA</Text> </View> } <View className={styles.desc} >{dynamic_title}</View> { isBusiness && <View className={styles.dynamicTime}>{date}</View> } <View className={styles.func}> <View className={styles.funcLeft}> <View onTap={saveMultPicToLocal}> <Image src="http://dxshy.duxieshe.com/uploads/applet_img/download.png" /> <Text>下载</Text> </View> <View onTap={addCollect}> <Image src={collect ? "http://dxshy.duxieshe.com/uploads/applet_img/collectActive.png" : "http://dxshy.duxieshe.com/uploads/applet_img/collect.png"} /> <Text>{collect ? '已收藏' : '收藏'}</Text> </View> </View> </View> </View> </View> ) }) SearchItem.propTypes = { dynamic: PropTypes.object.isRequired, contactCb: PropTypes.func.isRequired, delCb: PropTypes.func.isRequired } SearchItem.defaultProps = { contactCb: () => { }, delCb: () => { }, } const mapStateToProps = (state) => { const { userInfo } = state.common return { userInfo } } const mapDispatchToProps = (dispatch) => { return { clearSearchBase64Url: () => { dispatch(clearSearchBase64Url()) } } } export default connect(mapStateToProps, mapDispatchToProps)(SearchItem); 关于delCb(id, collect)的报错: [图片]
2022-10-28 - 怎么把“正在加载中”放在小程序底部?
在上拉小程序时,需要底部出现“正在加载中”的样式,而不是在页面正中间的弹窗。 如何实现它呢?可以直接用什么方法实现? 还是说只能做一个加载中的动图,配合文字自行设置样式? 下图是原有的加载中弹窗: [图片] 需要实现的效果是下图中底部的加载样式: [图片] 目前已经实现的效果是 加载中出现底部模块: [图片]
2022-10-27 - 微信小程序用户关注和取消关注的功能差异如何区分?
做的一个类似购物平台的小程序。在用户对商家店铺进行“关注”相关操作时,如何更好的区分“关注”与“取消关注”? 主要问题是 在小程序首页点进商家主页时关注按钮的状态,,以及在关注页面点进商家主页时关注按钮的状态。 现在的代码呈现的是从首页点进商家主页显示的是“已关注”(实际上未关注),点击后按钮切换为“未关注”并跳出弹窗“取消关注”(但实际与功能相反,为已关注),从关注页点进商家主页显示的也是“已关注”,点击切换为“未关注”并跳出弹窗“取消关注”(此时实际功能与操作相同,为取消关注)。 简单来说,从首页 与 从关注页进入商家主页,总会有一个页面的关注相关功能与实际情况相反。 如何让它在正确显示关注状态的情况下,也能正确呈现关注功能? 代码片段如下: [图片] [图片] [图片] [图片] 从首页进入情况如下: [图片] [图片] 此时从关注页进入的功能实现正常。
2022-10-26 - 小程序代码包超过限制怎么办?
开发完要上传时发现代码包过大,百度之后把图片换成了网络图片,也把除基础页面以外的页面移到分包中,最后虽然代码包有减小,但依旧超过了1.5M,现在不知道该怎么办了。 [图片] [图片]
2022-10-21