This commit is contained in:
2022-04-11 18:37:36 +08:00
parent ec682e2aea
commit dc0129402c
43 changed files with 1244 additions and 128 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ export default memo(({onClose, styleObj = {}}:Params) => {
return (
<View
style={styleObj}
className={`iconfont icon-a-cuowuwrong ${style.icon_a_cuowuwrong_self}`}
className={`iconfont icon-cuo ${style.icon_a_cuowuwrong_self}`}
onClick={onClose}
></View>
)
@@ -0,0 +1,45 @@
.load_box{
height:40px;
line-height:40px;
position:relative;
text-align:center;
.load_box_item {
width:5px;
height:5px;
margin:0 1px;
display:inline-block;
vertical-align:middle;
background:#9b59b6;
animation:load_more_box 1.5s infinite ease-in-out;
&:nth-child(2) {
animation-delay:.2s;
}
&:nth-child(3) {
animation-delay:.4s;
}
&:nth-child(4) {
animation-delay:.6s;
}
&:nth-child(5) {
animation-delay:.8s;
}
}
}
@keyframes load_more_box {
0% {
height:5px;
background:$color_font_two;
}
25% {
height:30px;
background:$color_main;
}
50% {
height:5px;
background:$color_font_two;
}
100% {
height:5px;
background:$color_font_two;
}
}
+17
View File
@@ -0,0 +1,17 @@
import { View } from "@tarojs/components";
import { memo } from "react";
import styles from './index.module.scss'
export default memo(() => {
return (
<>
<View className={styles.load_box}>
<View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View>
<View className={styles.load_box_item}></View>
</View>
</>
)
})
@@ -0,0 +1,15 @@
.scroll_main{
height: 100%;
.infinite_scroll{
font-size: $font_size_medium;
color: $color_font_two;
width: 100%;
display: flex;
justify-content: center;
.loading_more{
display: flex;
align-items: center;
}
}
}
+41
View File
@@ -0,0 +1,41 @@
import { ScrollView, View } from "@tarojs/components"
import { memo, ReactNode, useState } from "react"
import style from "./index.module.scss"
import DotLoading from "@/components/dotLoading"
type Params = {
styleObj?: Object,
selfonScrollToLower?: () => void,
hasMore?: false|true,
children?: ReactNode,
lowerThresholdNum?: number,
}
export default memo(({styleObj, selfonScrollToLower, hasMore=true, children, lowerThresholdNum = 5}: Params) => {
const scrollToLower = () => {
selfonScrollToLower?.()
}
return (
<>
<ScrollView
style={styleObj}
className={style.scroll_main}
scrollY
onScrollToLower={() => scrollToLower()}
lowerThreshold={lowerThresholdNum}
>
<View>
{children}
</View>
<View className={style.infinite_scroll}>
{
hasMore&&<View className={style.loading_more}>加载中<DotLoading/></View>||
<View>没有更多了</View>
}
</View>
<View className="common_safe_area_y"></View>
</ScrollView>
</>
)
})
+43
View File
@@ -0,0 +1,43 @@
.loading {
display: inline-block;
position: relative;
width: 60px;
height: 60px;
z-index: 2000;
&__ring {
box-sizing: border-box;
display: block;
position: absolute;
margin: 2px;
border-width: 2px;
border-style: solid;
border-color: #6190e8 transparent transparent;
border-radius: 50%;
animation: loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
height: 100%;
width: 100%;
&:nth-child(1) {
animation-delay: -0.45s;
}
&:nth-child(2) {
animation-delay: -0.3s;
}
&:nth-child(3) {
animation-delay: -0.15s;
}
}
}
@keyframes loading {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
+25
View File
@@ -0,0 +1,25 @@
import { View } from "@tarojs/components"
import { memo, useMemo } from "react"
import style from './index.module.scss'
export default memo(({width=60, color='#6190e8'}:{width?:number, color?:string}) => {
const styleObj = useMemo(() => {
let obj = {}
if(width > 0)
obj = {width: width + 'rpx', height:width + 'rpx'}
if(color)
obj = {...obj, borderColor: color+' transparent transparent'}
return obj
}, [width, color])
console.log('loading:::')
return (
<View className={style.loading}
style={styleObj}
>
<View style={styleObj} className={style.loading__ring}></View>
<View style={styleObj} className={style.loading__ring}></View>
<View style={styleObj} className={style.loading__ring}></View>
</View>
)
})
@@ -0,0 +1,13 @@
.loadingCard_main{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
.loading_text{
font-size: 26px;
margin-top: 20px;
color: $color_font_two;
}
}
+23
View File
@@ -0,0 +1,23 @@
import { View } from "@tarojs/components"
import Loading from "@/components/loading"
import style from "./index.module.scss"
import { memo } from "react";
type Params = {
styleLoading?: Object,
title?: string
}
export default memo(({
styleLoading = {},
title = "加载中..."
}:Params) => {
console.log('loadingCard:::')
return (
<>
<View className={style.loadingCard_main}>
<Loading/>
<View className={style.loading_text}>{title}</View>
</View>
</>
)
})
+10 -3
View File
@@ -1,6 +1,6 @@
import { MovableArea, MovableView, View } from "@tarojs/components"
import Taro, { useReady } from "@tarojs/taro"
import { ReactElement, useState } from "react"
import { ReactElement, useEffect, useRef, useState } from "react"
import classnames from "classnames";
import styles from './index.module.scss'
@@ -11,18 +11,25 @@ type param = {
export default ({children = null, onClick}:param) => {
const [screenHeight, setScreenHeight] = useState(0)
const [showMoveBtn, setShowMoveBtn] = useState(false)
const screenWidthRef = useRef(0)
useReady(() => {
const res = Taro.getSystemInfoSync()
if(res.screenHeight) {
let ratio = 750 / res.screenWidth;
let ratio = 750 / res.screenWidth
setScreenHeight(res.screenHeight*ratio - 460)
screenWidthRef.current = res.screenWidth/2
}
setShowMoveBtn(true)
})
const dragEnd = (e) => {
}
return (
<MovableArea className={styles.movableItem}>
{children}
{showMoveBtn&&<MovableView onClick={onClick} className={styles.moveBtn} direction="all" inertia={true} x='650rpx' y={screenHeight+'rpx'}>
{showMoveBtn&&<MovableView onClick={onClick} className={styles.moveBtn} direction="all" inertia={true} x="750rpx" y={screenHeight+'rpx'} onTouchEnd={(e) => dragEnd(e)}>
<View className={classnames('iconfont','icon-gouwuche', styles.shop_icon) } ></View>
</MovableView>}
</MovableArea>
+79
View File
@@ -0,0 +1,79 @@
.products_list{
padding: 0 20px 20px 20px;
box-sizing: border-box;
height: 100%;
}
.products_item{
width: 100%;
background-color: #fff;
border-radius: 20px;
padding: 20px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
&:nth-child(n+2){
margin-top: 16px;
}
.item_img{
width: 198px;
height: 198px;
position: relative;
image{
width: 100%;
height: 100%;
border-radius: 10px;
}
.num{
width: 100px;
height: 36px;
font-size: $font_size_min;
position: absolute;
right:0;
bottom: 0;
background: rgba($color: #fff, $alpha: 0.3);
border-radius: 36px 0px 10px 0px;
color: #fff;
text-align: center;
line-height: 36px;
}
}
.item_con{
padding-left: 15px;
font-size: $font_size;
flex:1;
.title{
font-size: $font_size;
color: #707070;
text{
color: $color_font_one;
font-weight: bold;
}
}
.tag_list{
display: flex;
margin-top: 16px;
.tag{
padding: 3px 10px;
background-color: #CDE5FF;
font-size: $font_size_min;
border-radius: 5px;
color: $color_main;
&:nth-child(2) {
margin-left: 10px;
}
}
}
.introduce{
font-size: $font_size_medium;
color: $color_font_two;
margin-top: 16px;
}
.des{
font-size:$font_size_medium;
color: #707070;
margin-top: 16px;
@include common_ellipsis($params:2);
}
}
}
+30
View File
@@ -0,0 +1,30 @@
import { Image, View } from "@tarojs/components"
import styles from './index.module.scss'
type params = {
desStatus?: true|false
}
export default ({desStatus = true}: params) => {
return (
<View className={styles.products_list}>
{new Array(10).fill('').map(item => {
return <View className={styles.products_item}>
<View className={styles.item_img}>
<Image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp01%2F1ZZQ214233446-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651827249&t=b2fc2a3672dc8ced9e0f37ce7e2ff901"/>
<View className={styles.num}>230色</View>
</View>
<View className={styles.item_con}>
<View className={styles.title}><text>0770#</text>21S单面平纹(食毛)</View>
<View className={styles.tag_list}>
<View className={styles.tag}>160cm</View>
<View className={styles.tag}>110g</View>
</View>
<View className={styles.introduce}>67.6%棉24%涤纶6.4%氨纶</View>
{desStatus&&<View className={styles.des}>产品描述产品描述产品描述产品描述产品描述</View>}
</View>
</View>
})}
</View>
)
}
+21 -5
View File
@@ -5,9 +5,6 @@
.icon_a_sousuo1_self{
font-size: 37px;
color: $color_font_two;
margin-right: 20px;
position: absolute;
left: 10px;
}
.search_con{
position: relative;
@@ -20,7 +17,7 @@
width: 100%;
height: 60px;
border-radius: 50px;
padding: 0 60px 0 60px;
padding: 0 60px;
box-sizing: border-box;
&::-webkit-input-placeholder { /* WebKit browsers */
color: #999;
@@ -40,8 +37,27 @@
.search_closeBtn{
position: absolute;
right: 10px;
}
}
.btn{
width: 100px;
font-size: $font_size_medium;
color: $color_font_two;
display: flex;
justify-content: center;
align-items: center;
}
.icon_inner{
margin-right: 20px;
position: absolute;
left: 10px;
margin-right: 0;
}
.icon_out{
margin-right: 10px;
}
}
+20 -7
View File
@@ -1,15 +1,19 @@
import { Input, View } from "@tarojs/components";
import styles from "./index.module.scss"
import CloseBtn from "@/components/closeBtn"
import { memo, useState } from "react";
import classnames from "classnames";
import { memo, useEffect, useState } from "react";
type Params = {
clickOnSearch?: () => void
clickOnSearch?: (val: string) => void
disabled?: false|true,
placeholder?: string,
changeOnSearch?:(any) => void,
showIcon?: false|true,
style?: Object
placeIcon?: 'out'|'inner',
style?: Object,
showBtn?: false|true,
btnStyle?: Object
}
export default memo(({
@@ -18,10 +22,13 @@ export default memo(({
disabled = false,
placeholder = '输入搜索内容',
showIcon = true,
style = {}
showBtn = false,
style = {},
btnStyle = {},
placeIcon = 'inner'
}:Params) => {
const [inputCon , setInputCon] = useState('')
const onInputEven = (e) => {
const value = e.detail.value
setInputCon(value)
@@ -32,16 +39,22 @@ export default memo(({
setInputCon('')
changeOnSearch?.('')
}
const onSearch = () => {
clickOnSearch?.(inputCon)
}
return (
<>
<View className={styles.search_main} onClick={() => clickOnSearch?.()} style={style}>
<View className={styles.search_main} onClick={() => onSearch()} style={style}>
<View className={styles.search_con}>
{showIcon&&<View className={`iconfont icon-sousuo ${styles.icon_a_sousuo1_self}`}></View>}
{showIcon&&<View className={classnames('iconfont', 'icon-sousuo', styles.icon_a_sousuo1_self, placeIcon=='inner'?styles.icon_inner:styles.icon_out)}></View>}
<Input placeholderStyle='color:#ABABAB; font-size:26rpx' disabled={disabled} value={inputCon} placeholder={placeholder} onInput={(e) => onInputEven(e)}></Input>
{!!inputCon&&<View className={styles.search_closeBtn}>
<CloseBtn onClose={() => clearInput()} styleObj={{width: '20rpx', height:'20rpx', backgroundColor:'#fff', border:'0'}}/>
</View>}
</View>
{showBtn&&<View style={btnStyle} className={styles.btn} onClick = {() => onSearch()}>搜索</View>}
</View>
</>
)
+9 -3
View File
@@ -1,4 +1,9 @@
.shop_cart_main{
.popup_con{
display: flex;
flex-direction: column;
height: 80vh;
}
.header{
width: 100%;
display: flex;
@@ -35,14 +40,15 @@
}
}
.con{
padding:30px 20px 0;
padding:30px 20px 100px 0;
box-sizing: border-box;
height: 70vh;
flex:1;
height: 0;
.scroll{
height: 100%;
}
.product_list{
padding-bottom: 115px;
padding-bottom: 20px;
.product_item{
display: flex;
justify-content: space-between;
+85 -56
View File
@@ -1,9 +1,12 @@
import { Checkbox, Image, ScrollView, View } from "@tarojs/components"
import {Image, ScrollView, View } from "@tarojs/components"
import Popup from "@/components/popup"
import classnames from "classnames";
import MCheckbox from "@/components/checkbox";
import LoadingCard from "@/components/loadingCard";
import InfiniteScroll from "@/components/infiniteScroll";
import styles from "./index.module.scss"
import { useEffect, useState } from "react";
import Taro from "@tarojs/taro";
type param = {
show?: true|false,
@@ -17,15 +20,19 @@ export default ({show = false, onClose}: param) => {
}
const [list, setList] = useState<any[]>([])
const [loading, setLoading] = useState(false)
useEffect(() => {
let lists:any[] = []
for(let i = 0; i < 20; i++) {
setList((e) => [...e, {
lists = [...lists, {
title:`${i}#薄荷绿`,
subtitle: '0770# 21S单面平纹(食毛)',
tag: '剪板',
select: i%2?true: false
}])
}]
}
setList([...lists])
}, [])
const [showPopup, setShowPopup] = useState(false)
@@ -33,11 +40,13 @@ export default ({show = false, onClose}: param) => {
setShowPopup(show)
}, [show])
const [selectStatus, setSelectStatus] = useState(false)
const selectAll = () => {
console.log('123123')
list.map(item => {
item.select = true
item.select = !selectStatus
})
setSelectStatus(!selectStatus)
setList([...list])
}
@@ -58,64 +67,84 @@ export default ({show = false, onClose}: param) => {
onClose?.()
setShowPopup(false)
}
const delSelect = () => {
Taro.showModal({
content: '删除所选商品?',
success: function (res) {
if (res.confirm) {
Taro.showToast({
title: '成功',
icon: 'success',
duration: 2000
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()}>
<View className={styles.header}>
<View onClick={selectAll}>全选</View>
<View>
<text className={classnames('iconfont', 'icon-lajixiang', styles.miconfont)}></text>
删除勾选项
<View className={styles.popup_con}>
<View className={styles.header}>
<View onClick={selectAll}>{!selectStatus?'全选':'反选'}</View>
<View onClick={delSelect}>
<text className={classnames('iconfont', 'icon-lajixiang', styles.miconfont)}></text>
删除勾选项
</View>
</View>
</View>
<View className={styles.search}>
{selectList.map((item, index) => {
return <View key={index} onClick={() => selectProduct(index)} className={classnames(styles.search_item, (selectIndex==index)&&styles.search_item_select)}>{item}</View>
})}
</View>
<View className={styles.con}>
{list.length > 0&&<ScrollView scrollY className={styles.scroll}>
<View className={styles.product_list}>
{list.map((item, index) => {
return <View key={index} className={styles.product_item}>
<View className={styles.checkbox}>
<MCheckbox status={item.select} onSelect={() => selectCallBack(item)} onClose={() => colseCallBack(item)}/>
<View className={styles.search}>
{selectList.map((item, index) => {
return <View key={index} onClick={() => selectProduct(index)} className={classnames(styles.search_item, (selectIndex==index)&&styles.search_item_select)}>{item}</View>
})}
</View>
<View className={styles.con}>
{loading&&<LoadingCard/>}
{!loading&&list.length > 0&&<InfiniteScroll selfonScrollToLower={() => {console.log('触底了')}}>
<View className={styles.product_list}>
{list.map((item, index) => {
return <View key={index} className={styles.product_item}>
<View className={styles.checkbox}>
<MCheckbox status={item.select} onSelect={() => selectCallBack(item)} onClose={() => colseCallBack(item)}/>
</View>
<View className={styles.img}>
<Image src="https://bpic.588ku.com//back_origin_min_pic/22/01/11/aa3da17bab9a6556564028e4f1d77874.jpg!/fw/750/quality/99/unsharp/true/compress/true"/>
</View>
<View className={styles.des}>
<View className={styles.title}>{item.title}</View>
<View className={styles.subtitle}>0770# 21S单面平纹(食毛)</View>
<View className={styles.tag}>剪板</View>
</View>
<View className={styles.count}>
<View className={styles.price}><text>¥</text>40.5<text>/kg</text></View>
<View className={styles.long}>×12m</View>
</View>
</View>
<View className={styles.img}>
<Image src="https://bpic.588ku.com//back_origin_min_pic/22/01/11/aa3da17bab9a6556564028e4f1d77874.jpg!/fw/750/quality/99/unsharp/true/compress/true"/>
</View>
<View className={styles.des}>
<View className={styles.title}>{item.title}</View>
<View className={styles.subtitle}>0770# 21S单面平纹(食毛)</View>
<View className={styles.tag}>剪板</View>
</View>
<View className={styles.count}>
<View className={styles.price}><text>¥</text>40.5<text>/kg</text></View>
<View className={styles.long}>×12m</View>
</View>
</View>
})}
</View>
})}
</View>
</InfiniteScroll>}
{!loading&&list.length > 0&&<View className={styles.empty}>
<View className={styles.title}>暂未选择商品</View>
<View className={styles.btn}>去选购</View>
</View>}
</ScrollView>||
<View className={styles.empty}>
<View className={styles.title}>暂未选择商品</View>
<View className={styles.btn}>去选购</View>
</View>}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_con}>
<View className={styles.icon}>
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
</View>
<View className={styles.price_con}>
<View className={styles.price_real}><text>¥</text>200</View>
<View className={styles.price_forecast}>预估金额</View>
</View>
<View className={styles.goPay}>
去结算
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_con}>
<View className={styles.icon}>
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
</View>
<View className={styles.price_con}>
<View className={styles.price_real}><text>¥</text>200</View>
<View className={styles.price_forecast}>预估金额</View>
</View>
<View className={styles.goPay}>
去结算
</View>
</View>
</View>
</View>
+19 -27
View File
@@ -3,7 +3,7 @@ import { memo, ReactNode, useRef, useState } from "react"
import styles from "./index.module.scss"
import classnames from "classnames";
import Taro, { useReady } from "@tarojs/taro";
import { useCallback } from "react";
import InfiniteScroll from "../infiniteScroll";
type ListProps = {
title: string,
@@ -51,30 +51,24 @@ export default memo(({list = [], defaultValue = 0, height='100vh', sideBarOnClic
}
useReady(() => {
let query = Taro.createSelectorQuery();
query.select('.side_bar_select').boundingClientRect(rect=>{
let clientHeight = rect.height;
let clientWidth = rect.width;
let ratio = 750 / clientWidth;
let height = clientHeight * ratio;
num_half.current = Math.ceil(height/2/heightItem)
init()
}).exec();
Taro.nextTick(() => {
let query = Taro.createSelectorQuery();
query.select('.side_bar_select').boundingClientRect(rect=>{
console.log('rect::',rect)
let clientHeight = rect.height;
let clientWidth = rect.width;
let ratio = 750 / clientWidth;
let height = clientHeight * ratio;
num_half.current = Math.ceil(height/2/heightItem)
init()
}).exec();
})
})
const formatTitle = useCallback((title = '') => {
let arr: ReactNode[]= []
let str = ''
for (let i = 1; i <= title.length; i++) {
str += title[i-1]
if(i == title.length|| i%2 == 0) {
const node = <View className={styles.title_list}>{str}</View>
arr.push(node)
str = ''
}
}
return arr
}, [])
//触底事件
const onScrolltolower = () => {
console.log('触底了')
}
return (
<>
@@ -90,7 +84,6 @@ export default memo(({list = [], defaultValue = 0, height='100vh', sideBarOnClic
key={item.value}
style={{height:heightItem+'rpx'}}
>
{/* {formatTitle(item.title)} */}
<View className={styles.title_con}>
{item.title}
</View>
@@ -101,10 +94,9 @@ export default memo(({list = [], defaultValue = 0, height='100vh', sideBarOnClic
<View className="common_safe_area_y"></View>
</ScrollView>
<View className={styles.sideBar_con}>
<ScrollView className={styles.sideBar_con_scroll} style={{height}} scrollY>
<InfiniteScroll selfonScrollToLower={() => onScrolltolower()}>
{children}
<View className="common_safe_area_y"></View>
</ScrollView>
</InfiniteScroll>
</View>
</View>
+8 -3
View File
@@ -1,14 +1,16 @@
import { Image, Swiper, SwiperItem, View } from "@tarojs/components"
import Taro from "@tarojs/taro"
import styles from './index.module.scss'
type item = {title:string, img:string, url:string, id:number}
type params = {
list?: item[]
swiperOnClick?: (val: item) => void
swiperOnClick?: (val: item) => void,
style?: Object
}
export default (props:params) => {
let {list = [], swiperOnClick} = props
let {list = [], swiperOnClick, style = {}} = props
list = [
{
title:'数据',
@@ -19,9 +21,12 @@ export default (props:params) => {
]
const goLink = (item) => {
swiperOnClick?.(item)
Taro.navigateTo({
url:'/pages/search/index'
})
}
return (
<View className={styles.swiper_con}>
<View className={styles.swiper_con} style={style}>
<Swiper
className={styles.xswiper}
indicatorColor='#ccc'