一个在线运行的Taro小程序完整实例
一个完整的基于taro3版本开发的微信小程序案例。我们要实现的基本功能,在微信小程序选择产品,然后系统显示产品与国家标准的对比情况,具体功能可以扫码查查看演示。
1、文件结构
src
│ │ ├─ pages
│ │ │ ├─ composition.jsx
│ │ │ ├─ gbnew.js
│ │ │ ├─ gbold.js
│ │ │ └─ index
│ │ │ ├─ index.jsx
│ │ │ └─ index.scss
│ │ ├─ components
│ │ │ ├─ AtTable.js
│ │ │ ├─ AtTable.scss
│ │ │ ├─ banner.js
│ │ │ ├─ banner.scss
│ │ │ ├─ ColorFlag.js
│ │ │ ├─ ConstructTable.js
│ │ │ ├─ ConstructTable.scss
│ │ │ ├─ milkimage.js
│ │ │ ├─ milkimage.scss
│ │ │ ├─ PagePicker.js
│ │ ├─ project.config.json
│ │ ├─package.json
│ │ ├─ app.config.js
│ │ ├─ app.js
│ │ ├─ app.scss
│ │ ├─ index.html
2、app.config.js 页面配置
export default {pages: ['pages/index/index','pages/gbnew','pages/gbold','pages/composition',],window: {backgroundTextStyle: 'light',navigationBarBackgroundColor: '#fff',navigationBarTitleText: '奶粉国标比对',navigationBarTextStyle: 'black'}
}
3、index.jsx
import { Component } from 'react'
import { View,Picker } from '@tarojs/components'
import './index.scss'
import { AtButton ,AtList, AtListItem ,AtToast } from 'taro-ui'
import Banner from '../../components/banner'
import MilkImage from '../../components/milkimage'
import ConstructTable from '../../components/ConstructTable'//产品
const procuts=[
]//图片URL,顺序与产品名称对应
const procutsImageUrl = []const baseData_dtz_old = []
const baseData_mineral_old = []
const baseData_choose_old = []const baseData_dtz_new = []
const baseData_mineral_new = []
const baseData_choose_new = []export default class Index extends Component {state = {selector: [procuts[0],procuts[1][0]],selectorChecked:[], //选择的品牌及产品selectorProcuts:'', selectorProcutsIsShow:false, //点击了比对后就显示表格isOpened:false, //请先选择产的提示isNewFlag:false, //显示新国标还是老国标 false 老 true 新baseData_dtz:[], //数据集送给表格展示baseData_vitamin:[],baseData_mineral:[],baseData_choose:[],isoldgb:true, //显示老国标isnewgb:false, //显示新国标imageurl:procutsImageUrl[0][0], //用于记录选择的产品序数组下标,然后取图片URL}componentWillMount () { }componentDidMount () { }componentWillUnmount () { }componentDidShow () { }componentDidHide () { }//筛选菜单点击确定onChange = e => {this.setState({selectorChecked:[this.state.selector[0][e.detail.value[0]],this.state.selector[1][e.detail.value[1]]],selectorProcuts:this.state.selector[1][e.detail.value[1]],isOpened:false,imageurl:procutsImageUrl[e.detail.value[0]][e.detail.value[1]],})//如果经过第一次点击对比后以后的切换产品不需要再点对比按钮,由于setState是异步的,所以要用下面的写法将onConstruct放到setState后执行if (this.state.selectorProcutsIsShow){this.setState({selectorChecked:[this.state.selector[0][e.detail.value[0]],this.state.selector[1][e.detail.value[1]]],selectorProcuts:this.state.selector[1][e.detail.value[1]],isOpened:false,imageurl:procutsImageUrl[e.detail.value[0]][e.detail.value[1]],},function(){this.onConstruct();})}}//筛选过程两级级联动作onColumnChange = e => {let {column,value} = e.detail;//判断是第几列改变了,如果是第一列变化,那么就要级联调动第二列if (column===0) {this.setState({selector: [procuts[0],procuts[1][value]],})} else {}}//点击对比按钮onConstruct = e =>{//判断产品是否已经选择if(this.state.selectorProcuts===''){this.setState({isOpened:true})}else{this.onChooseData(false) //查询按钮永远查老国标this.setState({selectorProcutsIsShow:true,isOpened:false,isoldgb:true,isnewgb:false})}}//对数据选择的处理onChooseData = (e)=>{//根据选择的品牌及产品名称判断该返回的字段if (!e){baseData_dtz_old.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){console.log("item.dataSource",item.dataSource)this.setState({baseData_dtz:item.dataSource})}})baseData_vitamin_old.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_vitamin:item.dataSource})}})baseData_mineral_old.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_mineral:item.dataSource})}})baseData_choose_old.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_choose:item.dataSource})}})}else {baseData_dtz_new.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_dtz:item.dataSource})}})baseData_vitamin_new.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_vitamin:item.dataSource})}})baseData_mineral_new.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_mineral:item.dataSource})}})baseData_choose_new.map((item,index)=>{if(item.brandName==this.state.selectorChecked[0] && item.prodcutName==this.state.selectorChecked[1]){this.setState({baseData_choose:item.dataSource})}})}}//切换新旧国标onClickNewOld = (e)=>{this.onChooseData(e)if(e){this.setState({isNewFlag:e,isoldgb:false,isnewgb:true})}else {this.setState({isNewFlag:e,isoldgb:true,isnewgb:false})} }render () {return (<View className='index'><View className='main'>{this.state.selectorProcutsIsShow?<MilkImage imageurl={this.state.imageurl}/>:<Banner/>}<View className='pick'><View className='page-section'><View><Picker mode='multiSelector' range={this.state.selector} onChange={this.onChange}onColumnChange={this.onColumnChange}><AtList><AtListItemtitle='请选择产品'extraText={this.state.selectorChecked}/></AtList></Picker></View></View><AtButton className="querybutton" type='primary' onClick={this.onConstruct}>奶粉国标比对</AtButton></View><View><AtToast isOpened={this.state.isOpened} text="请先选择产品"></AtToast>{this.state.selectorProcutsIsShow?<View><ConstructTable baseData_dtz={this.state.baseData_dtz}baseData_vitamin={this.state.baseData_vitamin}baseData_mineral={this.state.baseData_mineral}baseData_choose={this.state.baseData_choose}onClickNewOld={this.onClickNewOld}isoldgb={this.state.isoldgb}isnewgb={this.state.isnewgb}/></View>:null}</View></View></View>)}
}
4、composition.jsx
import { Component } from 'react'
import { View,Image ,Text } from '@tarojs/components'
import './composition.scss'
import { AtCard } from 'taro-ui'
import { Current } from '@tarojs/taro'export default class GbOld extends Component {state = {params:'',contentUsefor:'',contentLower:'',contentUpper:'',contentComposition:'',contentOther:''}componentWillMount () {var params = Current.router.params.nameswitch(params){case '蛋白质':this.setState({params:params,contentUsefor:'作用:提供生长发育所需氨基酸;有助于免疫力形成和提高;参与和调节新陈代谢;\n',contentLower:'缺乏:生长发育迟缓、智力发育障碍;免疫力降低等;\n',contentUpper:'过量:消化不良;腹泻;加重肾脏负担,导致肥胖;\n',contentComposition:'配料:脱脂牛奶、生牛乳、脱脂乳粉、全脂乳粉;\n',contentOther:'优质蛋白:a-乳白蛋白、a-乳清蛋白、免疫球蛋白、乳铁蛋白、酪蛋白'})breakcase '二十二碳六烯酸(DHA)':this.setState({params:params,contentUsefor:'作用:促进胎儿大脑发育、促进视力发育;\n',contentLower:'缺乏:智力低下、弱视;\n',contentUpper:'过量:降低免疫能力;\n'})break }}componentDidMount () { }componentWillUnmount () { }componentDidShow () { }componentDidHide () { }render () {return (<View className='index'><View className='constructtable'><AtCardclassName="at-card"// extra='点击营养素名可查看详解'title={this.state.params}><View className='content'><Text>{this.state.contentUsefor}</Text></View><View className='content'><Text >{this.state.contentLower}</Text></View> <View className='content'><Text >{this.state.contentUpper}</Text></View> <View className='content'><Text>{this.state.contentComposition}</Text></View> <View className='content'><Text>{this.state.contentOther}</Text></View> </AtCard></View></View> )}
}
5、gbnew.jsx
import { Component } from 'react'
import { View,Image } from '@tarojs/components'
import './gbnew.scss'export default class Gbnew extends Component {state = {}componentWillMount () { }componentDidMount () { }componentWillUnmount () { }componentDidShow () { }componentDidHide () { }render () {return (<View className='gbnew'><Image className='gbnew' src="https://i.niupic.com/images/2021/09/23/9CyY.jpg" mode='aspectFit'></Image></View>)}
}
6、gbold.jsx
import { Component } from 'react'
import { View,Image } from '@tarojs/components'
import './gbold.scss'export default class GbOld extends Component {state = {}componentWillMount () { }componentDidMount () { }componentWillUnmount () { }componentDidShow () { }componentDidHide () { }render () {return (<View className='gbold'><Image className='gbold' src="https://i.niupic.com/images/2021/09/23/9Czx.jpg" mode='aspectFit'></Image></View>)}
}
7、AtTable.js
// 自己简单封装的表格组件,taro 和微信都没有table组件
import { Component } from 'react'
import { View} from '@tarojs/components'
import './AtTable.scss'//需要传进来的数据示例
const exampledataSource = [{username: '小红',count: '123',gb:'321',dbd:'30%'}
]
//需要传进来的表头数据示例
const examplecolumns = [{title: '名称',dataIndex: 'username',width:'20%',},{title: '含量',dataIndex: 'count',width:'20%',},{title: '标准',dataIndex: 'gb',width:'40%',},{title: '达标度',dataIndex: 'dbd',width:'20%',},
]//原理 循环生成表头,循环数据根据表头填入每一列
export default class AtTable extends Component {render () {return (<View className="table"><View className="tr bg-header">{this.props.columns.map((item,index)=>{return (<View className="th" style={{ width:item.width}}>{item.title}</View>)})}</View>{this.props.dataSource.map((item,index)=>{return (<View className="tr bg-line">{this.props.columns.map((item2,index2)=>{if(item2.render){return (<View className="td" style={{ width:item2.width}}>{ item2.render(item[item2.dataIndex]) //判断表头是不是有render 有就执行render}</View>)}else {return ( <View className="td" style={{ width:item2.width}}>{ item[item2.dataIndex] //根据表头填数据}</View>)}})}</View>)})}</View> )}
}
8、banner.js
import { Component } from 'react'
import { View,Image,Swiper, SwiperItem } from '@tarojs/components'
import './banner.scss'export default class Banner extends Component {render () {return (<SwiperclassName='test-h'indicatorColor='#999'indicatorActiveColor='#333'circularindicatorDotsautoplay><SwiperItem><View className='demo-text-1'><Image className='banner' src='https://s3.bmp.ovh/imgs/2021/10/ef753b5e66170d46.jpg'></Image></View></SwiperItem><SwiperItem><View className='demo-text-2'><Image className='banner' src='https://s3.bmp.ovh/imgs/2021/10/a364e41d09535144.jpg'></Image></View></SwiperItem></Swiper>)}}
9、ColorFlag.js
// 自己简单封装的表格组件,taro 和微信都没有table组件
import { Component } from 'react'
import { View} from '@tarojs/components'export default class ColorFlag extends Component {// onHandleClick=()=>{// console.log("colorflag:",this.props.record)// };//根据props判断组件应该显示什么颜色。不能用state来保存值,会引起前端刷新不改变,只能直接使用传过来的propsgetColorNum=(e)=>{var background="#30cc00"if(e<0){background="#FF4949";}else if(e == 0){background="#ffc701";}else if(e>0 && e<30){background="#30cc004b";}else if(e>=30 && e<50){background="#30cc0080";}else if(e>=50 && e<70){background="#30cc00bc";}else if(e>=70){background="#30cc00";}else if (e =='未标注'){background="#ffc701";}return background}render(){return (<View onClick={this.onHandleClick} style={{width:'18px',height:'18px',borderRadius:'50%',background:this.getColorNum(this.props.record)}}></View>)}
}
10、ConstructTable.js
import { Component } from 'react'
import { View } from '@tarojs/components'
import { AtCard,AtTag,AtIcon , } from 'taro-ui'
import './ConstructTable.scss'
import AtTable from './AtTable'
import Taro from '@tarojs/taro';
import ColorFlag from './ColorFlag'
//taro 和 微信都没有table 组件 安装 taro3-table https://taro-ext.jd.com/plugin/view/604d7cde39b51f165cbfb11c 适配不好,不好用
// import Table from 'taro3-table';export default class ConstructTable extends Component {//数据放到class中才能使用内部自定义的函数//蛋白质、碳水化合物、脂肪columns_dtz = [{title:'营养素',dataIndex:'composition',width:'20%',render:(record)=>{return(<View onClick={()=>this.onClickInfo(record)}>{record}</View>) //这里注意一定要用这个胖箭头,否则当组件加载时,会自动执行onClick}},{title:'单位',dataIndex:'unit',width:'20%'},{title:'100千焦含量',dataIndex:'content',width:'20%'},{title:'标准值',dataIndex:'standard',width:'30%'},{title:'达标度',dataIndex:'reachfor',width:'10%',render:(record)=>{return(<ColorFlag record={record}/>)}}]//维生素columns_vitamin = [{title:'维生素',dataIndex:'composition',width:'20%',render:(record)=>{return(<View onClick={()=>this.onClickInfo(record)}>{record}</View>) //这里注意一定要用这个胖箭头,否则当组件加载时,会自动执行onClick}},{title:'单位',dataIndex:'unit',width:'20%'},{title:'100千焦含量',dataIndex:'content',width:'20%'},{title:'标准值',dataIndex:'standard',width:'30%'},{title:'达标度',dataIndex:'reachfor',width:'10%',render:(record)=>{return(<ColorFlag record={record}/>)}}]//矿物质columns_mineral = [{title:'矿物质',dataIndex:'composition',width:'20%',render:(record)=>{return(<View onClick={()=>this.onClickInfo(record)}>{record}</View>) //这里注意一定要用这个胖箭头,否则当组件加载时,会自动执行onClick}},{title:'单位',dataIndex:'unit',width:'20%'},{title:'100千焦含量',dataIndex:'content',width:'20%'},{title:'标准值',dataIndex:'standard',width:'30%'},{title:'达标度',dataIndex:'reachfor',width:'10%',render:(record)=>{return(<ColorFlag record={record}/>)}}]//可选成分columns_choose = [{title:'可选成分',dataIndex:'composition',width:'20%',render:(record)=>{return(<View onClick={()=>this.onClickInfo(record)}>{record}</View>) //这里注意一定要用这个胖箭头,否则当组件加载时,会自动执行onClick}},{title:'单位',dataIndex:'unit',width:'20%'},{title:'100千焦含量',dataIndex:'content',width:'20%'},{title:'标准值',dataIndex:'standard',width:'30%'},{title:'达标度',dataIndex:'reachfor',width:'10%',render:(record)=>{return(<ColorFlag record={record}/>)}}]componentWillMount () { }//切换为旧国标onClickOldTag=()=>{if(this.props.isoldgb!=true)this.props.onClickNewOld(false)}//切换新国标onClickNewTag=()=>{if(this.props.isnewgb!=true)this.props.onClickNewOld(true)}//跳转配方解析?id=2&type=test
onClickInfo=(record)=>{ console.log("onClickInfo被点击",record)var url = '/pages/composition?name=' + recordTaro.navigateTo({url:url})
}//显示新国标onClickGbNew=()=>{Taro.navigateTo({url:'/pages/gbnew'})}
//显示旧国标onClickGbOld=()=>{Taro.navigateTo({url:'/pages/gbold'})}render () {return (<View className='constructtable'><View className='gboldnew'><AtTag name="现版国标"active={this.props.isoldgb}onClick={this.onClickOldTag}>现版国标</AtTag><AtIcon className="helpicon" value='message' size='20' color='#5f6642'onClick={this.onClickGbOld}> </AtIcon><AtTag name="新版国标"active={this.props.isnewgb}onClick={this.onClickNewTag}>新版国标</AtTag><AtIcon className="helpicon" value='message' size='20' color='#5f6642'onClick={this.onClickGbNew}></AtIcon></View><AtCardclassName="at-card"extra=''title='点击营养素名查看详解'> <AtTable dataSource={this.props.baseData_dtz} columns={this.columns_dtz}/> <AtTable dataSource={this.props.baseData_vitamin} columns={this.columns_vitamin}/> <AtTable dataSource={this.props.baseData_mineral} columns={this.columns_mineral}/> <AtTable dataSource={this.props.baseData_choose} columns={this.columns_choose}/> </AtCard> </View> )}}
11、milkimage.js
//奶粉的图片
import { Component } from 'react'
import { View,Image } from '@tarojs/components'
import './milkimage.scss'export default class MilkImage extends Component {
// componentWillMount () {
// console.log("地址",this.props.imageurl)
// }render () {return (<View className='milkimage1'><Image className='milkimage2' src={this.props.imageurl}></Image></View>)}
}
12、pagePicker.js
import { Component } from 'react'
import { View, Text, Picker } from '@tarojs/components'
import { AtList, AtListItem } from 'taro-ui'export default class PagePicker extends Component {state = {selector: [procuts[0],procuts[1][0]],selectorChecked:[],selectorProcuts:'',selectorProcutsIsShow:false,}//筛选菜单点击确定
onChange = e => {this.setState({selectorChecked: [this.state.selector[0][e.detail.value[0]],this.state.selector[1][e.detail.value[1]]],selectorProcuts:this.state.selector[1][e.detail.value[1]]})}//筛选过程两级级联动作
onColumnChange = e => {console.log("onColumnChange获取到的值value:",e.detail.value)console.log("onColumnChange获取到的值column:",e.detail.column)let {column,value} = e.detail;//判断是第几列改变了,如果是第一列变化,那么就要级联调动第二列if (column===0) {this.setState({selector: [procuts[0],procuts[1][value]],})} else {}}render () {return (<View className='page-section'><View><Picker mode='multiSelector' range={this.state.selector} onChange={this.onChange}onColumnChange={this.onColumnChange}><AtList><AtListItemtitle='请选择产品'extraText={this.state.selectorChecked}/></AtList></Picker></View></View>)}
}
一个在线运行的Taro小程序完整实例相关推荐
- 如何制作一个在线订酒店的小程序
互联网时代,客户普遍习惯线上预订酒店.酒店方面自然也需要拓展多个线上渠道卖房间,除了OTA渠道.酒店官网.APP等,小程序也是重要途径. 如何制作一个在线订酒店的小程序? 1. 让客户能够快速订房,满 ...
- 制作了一个在线查询席位的小程序
11-6号制作了一个在线查询席位的小程序 声明:本人小白一个纯分享,写出来巩固思路,不足之处,大佬多指教,谢谢! 用的是webapi使用 大致的思路是先webapi写一个查询数据库的程序, 再sqli ...
- python聊天小程序支持私聊和多人_利用Python打造一个多人在线匿名聊天的小程序!(前后端完整开发)...
用Python打造一个多人在线匿名聊天的小程序(附代码) 最近看到好多设计类网站, 都提供了多人在线匿名聊天的小功能, 感觉很有意思, 于是自己就用django框架写了一个, 支持手动实时更名, py ...
- Taro小程序跨端开发入门实战
背景 一开始我们只做微信小程序,随着我们的业务不断扩张和各大小程序平台的崛起,针对每个平台都去写一套代码是不现实的.而且原生的小程序开发模式有很多弊端. 为了让小程序开发更简单,更高效,我们采用 Ta ...
- Taro 小程序开发大型实战(六):尝鲜微信小程序云(上篇)
欢迎继续阅读<Taro 小程序开发大型实战>系列,前情回顾: 熟悉的 React,熟悉的 Hooks[1]:我们用 React 和 Hooks 实现了一个非常简单的添加帖子的原型 多页面跳 ...
- Springboot校园在线打印预约系统小程序【纯干货分享,附源码91740】
摘 要 本文设计了一种基于微信支付的校园在线打印预约系统小程序,系统为人们提供了方便快捷的线上打印服务,包括打印预约.注册登录.打印平台.校园资讯等,用户不仅能够方便快捷在线搜索打印方式.还能进行打印 ...
- taro 小程序转h5之后报错_记录微信小程序转Taro中遇到的问题
环境 系统:windows 开发工具:微信开发工具RC V1.02.1907301 + vscode 微信基础库版本:2.8.1 Taro:v1.3.15 npm: 6.4.1 node: v8.12 ...
- 应用程序初次运行数据库配置小程序(Java版)
应用程序初始化数据库配置小程序 之前写过一个Java版的信息管理系统,但部署系统的时候还需要手动的去配置数据库和导入一些初始化的数据才能让系统运行起来,所以我在想是不是可以写一个小程序在系统初次运行的 ...
- 计算机毕业设计 在线免费小说微信小程序(源码+论文)
文章目录 0 项目说明 1 系统介绍 1.1 业务层面 1.2 产品层面 1.3 技术层面 2 项目运行 3 项目截图 3.1 小程序 3.2 后台管理系统 3.3 论文概览 0 项目说明 在线免费小 ...
- Taro 小程序开发大型实战(三):实现微信和支付宝多端登录
欢迎继续阅读<Taro 小程序开发大型实战>系列,前情回顾: 熟悉的 React,熟悉的 Hooks[1]:我们用 React 和 Hooks 实现了一个非常简单的添加帖子的原型 多页面跳 ...
最新文章
- List和List的区别?
- 《爱上统计学》读书笔记
- WNetAddConnection2 映射网络驱动器
- 大型网站架构利器-CDN技术
- MSDN 教程短片 WPF 20(绑定3-ObjectDataProvider)
- mysql 触发器 sql日志_mysql日志触发器实现代码
- QQ文件上传不了:什么年代了,还使用简单的关键词过滤,智能一点可好
- 穿越计算机的迷雾总结
- 学习笔记-OS - Exploits
- APP抓包教程 windows + mimtproxy +夜神模拟器 + XposedInstaller + JustTrustMe
- Linux 查看网络流量 iftop
- 2021年美赛准备大全
- 为什么使用对象指针而不是使用对象本身?
- 用Java写倒叙数字输出
- pcap头文件位置 Linux,pcap文件头的组织格式
- 分享抖音账号初期运营技巧,直接可复制的运营流程
- 泛微协同OA 园区管理新动力
- 网络关键设备和网络安全专用产品目录
- 零基础如何开始学编程
- CMakeCache.txt is different 错误