diff --git a/src/app.config.ts b/src/app.config.ts index 9870f49..42010f0 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -7,5 +7,21 @@ export default { navigationBarBackgroundColor: '#fff', navigationBarTitleText: 'WeChat', navigationBarTextStyle: 'black' - } + }, + tabBar: { + list: [ + { + pagePath: 'pages/index/index', + text: '首页' + }, + { + pagePath: 'pages/index/index', + text: '我的' + } + ], + 'color': '#707070', + 'selectedColor': '#2680EB', + 'backgroundColor': '#fff', + 'borderStyle': 'white' + }, } diff --git a/src/app.scss b/src/app.scss index f13e53a..fdf4521 100644 --- a/src/app.scss +++ b/src/app.scss @@ -1 +1,5 @@ -@import './styles/common.scss' \ No newline at end of file +@import './styles/common.scss'; +@import './styles/iconfont.scss'; +page{ + height: 100%; +} \ No newline at end of file diff --git a/src/components/closeBtn/index.module.scss b/src/components/closeBtn/index.module.scss new file mode 100644 index 0000000..7c001f4 --- /dev/null +++ b/src/components/closeBtn/index.module.scss @@ -0,0 +1,12 @@ +.icon_a_cuowuwrong_self { + height: 20px; + width: 20px; + font-size: 27px; + padding: 10px; + border-radius: 50%; + border: #ccc 1px solid; + color: #ccc; + display: flex; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/src/components/closeBtn/index.tsx b/src/components/closeBtn/index.tsx new file mode 100644 index 0000000..4657216 --- /dev/null +++ b/src/components/closeBtn/index.tsx @@ -0,0 +1,18 @@ +import { View } from "@tarojs/components" +import { memo } from "react" +import style from "./index.module.scss" + +type Params = { + onClose?: () => void, + styleObj?: Object +} + +export default memo(({onClose, styleObj = {}}:Params) => { + return ( + + ) +}) \ No newline at end of file diff --git a/src/components/search/index.module.scss b/src/components/search/index.module.scss new file mode 100644 index 0000000..4de09f8 --- /dev/null +++ b/src/components/search/index.module.scss @@ -0,0 +1,47 @@ +.search_main{ + display: flex; + align-items: center; + position: relative; + .icon_a_sousuo1_self{ + font-size: 37px; + color: $color_font_two; + margin-right: 20px; + position: absolute; + left: 10px; + } + .search_con{ + position: relative; + display: flex; + align-items: center; + width: 100%; + input{ + font-size: 27px; + background: #eee; + width: 100%; + height: 60px; + border-radius: 50px; + padding: 0 60px 0 60px; + box-sizing: border-box; + &::-webkit-input-placeholder { /* WebKit browsers */ + color: #999; + font-size: 16px; + } + + &::-moz-placeholder { /* Mozilla Firefox 19+ */ + color: #999; + font-size: 16px; + } + + &::-ms-input-placeholder { /* Internet Explorer 10+ */ + color: #999; + font-size: 16px; + } + } + .search_closeBtn{ + position: absolute; + right: 10px; + + } + } + +} \ No newline at end of file diff --git a/src/components/search/index.tsx b/src/components/search/index.tsx new file mode 100644 index 0000000..68e671a --- /dev/null +++ b/src/components/search/index.tsx @@ -0,0 +1,48 @@ +import { Input, View } from "@tarojs/components"; +import styles from "./index.module.scss" +import CloseBtn from "@/components/closeBtn" +import { memo, useState } from "react"; + +type Params = { + clickOnSearch?: () => void + disabled?: false|true, + placeholder?: string, + changeOnSearch?:(any) => void, + showIcon?: false|true, + style?: Object +} + +export default memo(({ + clickOnSearch, + changeOnSearch, + disabled = false, + placeholder = '输入搜索内容', + showIcon = true, + style = {} +}:Params) => { + const [inputCon , setInputCon] = useState('') + + const onInputEven = (e) => { + const value = e.detail.value + setInputCon(value) + changeOnSearch?.(value) + } + + const clearInput = () => { + setInputCon('') + changeOnSearch?.('') + } + return ( + <> + clickOnSearch?.()} style={style}> + + {showIcon&&} + onInputEven(e)}> + {!!inputCon&& + clearInput()} styleObj={{width: '20rpx', height:'20rpx', backgroundColor:'#fff', border:'0'}}/> + } + + + + ) +}) \ No newline at end of file diff --git a/src/components/sideBar/index.module.scss b/src/components/sideBar/index.module.scss new file mode 100644 index 0000000..ec8061b --- /dev/null +++ b/src/components/sideBar/index.module.scss @@ -0,0 +1,43 @@ +.sideBar_main{ + display: flex; + height: 100%; + .sideBar_select{ + width: 150px; + height: 100%; + background-color: #eaeaea; + border-radius: 0 10px 10px 0; + ::-webkit-scrollbar { + display:none; + width:0; + height:0; + color:transparent; + } + .sideBar_select_title{ + height: 100px; + width: 100%; + font-size: $font_size; + color: #727272; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-weight: 400; + .title_con{ + width: 74px; + @include common_ellipsis($params:4); + } + + } + .sideBar_select_title_select{ + background-color: $color_bg_one; + color: $color_font_one; + } + } + .sideBar_con{ + flex: 1; + .sideBar_con_scroll{ + width: 100%; + height: 100%; + } + } +} \ No newline at end of file diff --git a/src/components/sideBar/index.tsx b/src/components/sideBar/index.tsx new file mode 100644 index 0000000..c93b64f --- /dev/null +++ b/src/components/sideBar/index.tsx @@ -0,0 +1,113 @@ +import { ScrollView, View } from "@tarojs/components" +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"; + +type ListProps = { + title: string, + value: number +} + +type Params = { + list?: ListProps[], + defaultValue?: number|string, + children?: ReactNode, + height?: string, + heightItem?: number, + sideBarOnClick?: (ListProps) => void +} + +export default memo(({list = [], defaultValue = 0, height='100vh', sideBarOnClick, children, heightItem = 100}: Params) => { + + let num_half = useRef(0) + + const [selected, setSelected] = useState(defaultValue) + const [tabId, setTabId] = useState('') + + const init = () => { + const index = list?.findIndex(item => { + return item.value == defaultValue + }) + if(index !== -1) { + computeSelectTab(index) + } + } + + const clickEvent = ({item, index}: {item:ListProps, index:number}) => { + setSelected(item.value) + sideBarOnClick?.(item) + computeSelectTab(index) + } + + const computeSelectTab = (index) => { + if((index + 1) > num_half.current) { + let num = index + 1 - num_half.current + setTabId(list[num].value.toString()) + } else { + setTabId(list[0].value.toString()) + } + } + + 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(); + }) + + 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 = {str} + arr.push(node) + str = '' + } + } + return arr + }, []) + + return ( + <> + + + { + list?.map((item, index) => { + return( + clickEvent({item, index})} + id={`tab_${item.value}`} + key={item.value} + style={{height:heightItem+'rpx'}} + > + {/* {formatTitle(item.title)} */} + + {item.title} + + + ) + }) + } + + + + + {children} + + + + + + + ) +}) \ No newline at end of file diff --git a/src/components/swiper/index.module.scss b/src/components/swiper/index.module.scss new file mode 100644 index 0000000..db835a6 --- /dev/null +++ b/src/components/swiper/index.module.scss @@ -0,0 +1,18 @@ +.swiper_con{ + padding:0 20px; + height: 178px; + .xswiper { + height: 100% !important; + border-radius: 20px; + .image_item{ + width: 100%; + height: 100%; + + image{ + width: 100%; + height: 100%; + border-radius: 20px; + } + } + } +} \ No newline at end of file diff --git a/src/components/swiper/index.tsx b/src/components/swiper/index.tsx new file mode 100644 index 0000000..239f384 --- /dev/null +++ b/src/components/swiper/index.tsx @@ -0,0 +1,45 @@ +import { Image, Swiper, SwiperItem, View } from "@tarojs/components" +import styles from './index.module.scss' + +type item = {title:string, img:string, url:string, id:number} + +type params = { + list?: item[] + swiperOnClick?: (val: item) => void +} +export default (props:params) => { + let {list = [], swiperOnClick} = props + list = [ + { + title:'数据', + img:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F811%2F021315104H2%2F150213104H2-3-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651817947&t=5467a207f845ddfc7737d55934e6b26d', + url:'', + id:1 + } + ] + const goLink = (item) => { + swiperOnClick?.(item) + } + return ( + + + { + list.map(item => { + return + goLink(item)}> + + + + }) + } + + + ) + +} \ No newline at end of file diff --git a/src/pages/index/components/product/index.module.scss b/src/pages/index/components/product/index.module.scss new file mode 100644 index 0000000..f8a815c --- /dev/null +++ b/src/pages/index/components/product/index.module.scss @@ -0,0 +1,65 @@ + +.products_list{ + padding: 0 20px 20px 20px; + box-sizing: border-box; + +} +.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; + image{ + width: 100%; + height: 100%; + border-radius: 10px; + } + } + .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); + } + } +} diff --git a/src/pages/index/components/product/index.tsx b/src/pages/index/components/product/index.tsx new file mode 100644 index 0000000..8b70b14 --- /dev/null +++ b/src/pages/index/components/product/index.tsx @@ -0,0 +1,79 @@ +import { Image, View } from "@tarojs/components" +import styles from './index.module.scss' + +export default () => { + return ( + + + + + + + 0770#21S单面平纹(食毛) + + 160cm + 110g + + 67.6%棉24%涤纶6.4%氨纶 + 产品描述产品描述产品描述产品描述产品描述 + + + + + + + + 0770#21S单面平纹(食毛) + + 160cm + 110g + + 67.6%棉24%涤纶6.4%氨纶 + 产品描述产品描述产品描述产品描述产品描述 + + + + + + + + 0770#21S单面平纹(食毛) + + 160cm + 110g + + 67.6%棉24%涤纶6.4%氨纶 + 产品描述产品描述产品描述产品描述产品描述 + + + + + + + + 0770#21S单面平纹(食毛) + + 160cm + 110g + + 67.6%棉24%涤纶6.4%氨纶 + 产品描述产品描述产品描述产品描述产品描述 + + + + + + + + 0770#21S单面平纹(食毛) + + 160cm + 110g + + 67.6%棉24%涤纶6.4%氨纶 + 产品描述产品描述产品描述产品描述产品描述 + + + + ) +} diff --git a/src/pages/index/index.config.ts b/src/pages/index/index.config.ts index be3ab00..0b7f3f1 100644 --- a/src/pages/index/index.config.ts +++ b/src/pages/index/index.config.ts @@ -1,3 +1,3 @@ export default { - navigationBarTitleText: '首页' + navigationBarTitleText: '电子商城' } diff --git a/src/pages/index/index.module.scss b/src/pages/index/index.module.scss index 0da20fe..b0dadc3 100644 --- a/src/pages/index/index.module.scss +++ b/src/pages/index/index.module.scss @@ -1,3 +1,29 @@ -.index{ - color: $color; +.main{ + background-color: $color_bg_one; + min-height: 100%; + display: flex; + flex-direction: column; + .search{ + width: 100%; + display: flex; + justify-content: space-between; + padding: 20px 20px 30px 20px; + box-sizing: border-box; + align-items: center; + .search_collect{ + font-size: 26px; + border: 2px solid #007AFF; + color: #007AFF; + border-radius: 50px; + width: 132px; + height: 44px; + text-align: center; + line-height: 44px; + } + } + .products{ + flex:1; + height: 0; + } + } \ No newline at end of file diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 4668621..bfd3e07 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1,13 +1,45 @@ -import { View, Text } from '@tarojs/components' -import Test from '@/components/test' +import { Image, View} from '@tarojs/components' +import Swiper from '@/components/swiper' +import Search from '@/components/search' +import SideBar from '@/components/sideBar' +import Product from './components/product' import styles from './index.module.scss' - export default () => { + const tabs_list = [ + {title:'平纹系列', value: 1}, + {title:'平纹系列', value: 2}, + {title:'平纹系列', value: 3}, + {title:'平纹系列', value: 4}, + {title:'平纹系列', value: 5}, + {title:'平纹系列', value: 6}, + {title:'平纹系列', value: 7}, + {title:'平纹系列', value: 8}, + {title:'平纹系列', value: 9}, + {title:'平纹系列', value: 10}, + {title:'平纹系列', value: 11}, + {title:'平纹系列', value: 12}, + {title:'平纹系列', value: 13}, + {title:'平纹系列', value: 14}, + {title:'平纹系列', value: 15}, + {title:'平纹系列', value: 16}, + {title:'平纹系列', value: 17}, + ] return ( - - Hello world123! - + + + + 我的收藏 + + + + + + + + + + ) } diff --git a/src/styles/common.scss b/src/styles/common.scss index e8b1e3c..2ad10a4 100644 --- a/src/styles/common.scss +++ b/src/styles/common.scss @@ -1,2 +1,28 @@ -$color: #ccc; \ No newline at end of file +$color_bg_one: #F8F8F8; +$color_font_one: #3C3C3C; +$color_font_two: #ABABAB; +$color_main: #007AFF; + +$font_size: 28px; +$font_size_medium: 24px; +$font_size_min: 22px; + +//安全底部距离 +.common_safe_area_y { + width: 100%; + height: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */ + height: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */ +} + +//省略号 +@mixin common_ellipsis($params:1) { + overflow: hidden; + display: -webkit-box; + white-space:normal; + word-break:break-all; + -webkit-box-orient: vertical; + -webkit-line-clamp: $params; + text-overflow:ellipsis; + +} \ No newline at end of file diff --git a/src/styles/iconfont.scss b/src/styles/iconfont.scss new file mode 100644 index 0000000..a78eec5 --- /dev/null +++ b/src/styles/iconfont.scss @@ -0,0 +1,50 @@ +@font-face { + font-family: "iconfont"; /* Project id 2987621 */ + src: + url('iconfont.ttf?t=1649229905782') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-sousuo:before { + content: "\e633"; +} + +.icon-tick_gou:before { + content: "\e62e"; +} + +.icon-bianji_bianji:before { + content: "\e630"; +} + +.icon-jian:before { + content: "\e632"; +} + +.icon-lajixiang:before { + content: "\e634"; +} + +.icon-jia:before { + content: "\e635"; +} + +.icon-gouwuche:before { + content: "\e636"; +} + +.icon-fenlei:before { + content: "\e638"; +} + +.icon-wode:before { + content: "\e639"; +} + diff --git a/src/styles/iconfont.ttf b/src/styles/iconfont.ttf new file mode 100644 index 0000000..29b6c0c Binary files /dev/null and b/src/styles/iconfont.ttf differ