uniapp 开发实操一 :列表与表单提交

目前随着5g网络的不断普及以及web app 跨平台的优势,web app已经逐渐成了 普通app 开发的首选框架。uni-app基于Vue.js实现的。所以它具备了vue.js前端的所有优势。而且uniapp 有很丰富的第三方插件,可以很方便的用一套代码开发公众号与小程序。先上图,效果如下:

html5页面:

 

 小程序页面:

 

 1、列表页面代码:这里用引入了mescroll 上拉下拉第三方插件,非常好用。

<template>
    <view class="container">
    <bar :nav="setNav"></bar>
     <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" >
        <view class="notice"></view>
        <good-list :list="goods"></good-list>
    </mescroll-body>
    </view>
</template>

<script>
    import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
    import bar from '../components/bar';
    export default {
        mixins: [MescrollMixin], // 使用mixin
        components:{
            bar
        },
        data() {
            return {
                baseUrl:getApp().globalData.baseUrl,
                goods: [],
                 setNav:{
                     'bg':'yellow',  //背景色
                     'color':'red',  //字体颜色
                     'isdisPlayNavTitle':true, //是否显示返回按钮,由于导航栏是共用的,把所有的东西封装好,
                    'isdisPlayNavLeftButton':true,
                     // 然后有些页面不需要的东西通过条件控制进行显示与隐藏
                     'navTitle':'商品列表' //导航标题
                 }// 数据列表
            }
        },
        methods: {
            
            /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
            upCallback(page) {
                console.log("调用2:"+page.num);
                console.log("this.baseUrl:"+this.baseUrl);
                uni.request({
                    url: this.baseUrl+'/app/secondHand/list', //仅为示例,并非真实接口地址。
                     contentType: "application/json;charset=utf-8",
                   data : JSON.stringify({ 'page':page.num,'rows':8}),
                   dataType : "json",
                    method: "POST",
                    header: {
                        'custom-header': 'hello' //自定义请求头信息
                    },
                    success: (res) => {
                        console.log(res);
                        //this.goods=res.data.data;
                        this.mescroll.endSuccess(res.data.data.length);
                        //this.mescroll.endByPage(this.goods.length,100); //必传参数(当前页的数据个数, 总页数)
                        //设置列表数据
                        //if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
                        this.goods=this.goods.concat(res.data.data); //追加新数据
                    },
                    fail: () => {
                        this.mescroll.endErr();
                        console.log("失败");
                    }
                });
                
            }
        }
    }
</script>

<style>
    /*说明*/
    .notice{
        font-size: 26upx;
        padding: 40upx 0;
        border-bottom: 1upx solid #eee;
        text-align: center;
        color:#555;
    }
    .container{
        display: flex;
        flex-direction: colum;
    }
    mescroll-body{
        margin-top:50rpx;
    }
</style>

2、列表项组件页面:vue.js 就是组件化更方便,相比微信小程序原生代码结构会更方便些。


<template>
    <view class="good-list">
        <view :id="'good'+good.id" class="good-li" v-for="good in list" :key="good.id">
             <image class="good-img" :src="getImgUrl(good.goodPic)" mode="scaleToFill"/> 
            <view class="item_data">
                <view class="item_1">
                    <text class="good-name">{{good.goodName}}</text>
                    <text class="good-price">{{good.goodPrice}} 元</text>
                </view>
                <text class="good-desc">{{good.goodDesc}}</text>
            </view>
        </view>
    </view>
</template>

<script>
    export default { 
        props:{
            list: {
                type: Array,
                default(){
                    return []
                }
            }
        },
        methods: {
            getImgUrl(icon){
                console.log("getApp().globalData.host:"+getApp().globalData.host);
               return  getApp().globalData.host+icon;
            }
        }
    }
</script>

<style lang="scss">
    .good-list{
        background-color: #000000;
        width:750rpx;
        .good-li{
            
            display: flex;
            flex-direction:row;
            align-items: center;
            padding:20rpx;
            background-color: #fef;
            border-bottom: 1upx solid #eee;
            
            .good-img{
                width: 160upx;
                height: 160upx;
                margin-right: 20rpx;
            }
            .item_data{
                display: flex;
                flex-direction:column;
                width:100%;
                .item_1{
                    display: flex;
                    flex-direction:row;
                    justify-content:space-between;
                    width:100%;
                    .good-name{
                        font-size: 30rpx;
                        height: 80upx;
                        margin-bottom: 20upx;
                        overflow: hidden;
                    }
                    .good-price{
                        font-size: 30rpx;
                    }
                    
                    .good-sold{
                        font-size: 24upx;
                        margin-left: 16upx;
                        color: gray;
                    }
                    
                }
                .good-desc{
                    font-size: 30rpx;
                }
            }
        }
    }
</style>
3、新增页面:集成了第三方上传组件htz-image-upload

 <template>
    <view class="container">
           <bar :nav="setNav"></bar>
        
        <view class="uni-padding-wrap uni-common-mt">
            <form @submit="formSubmit" @reset="formReset">
                <view  class="row_style">
                    <text class="title">物品名称:</text>
                    <input class="uni-input" name="goodName" placeholder="请输入物品名称" />
                </view>
                <view  class="row_style">
                    <text class="title">新旧程度:</text>
                    <picker @change="bindPickerChange" :value="newLevel" :range="array" range-key="name">
                        <view class="uni-input">{{array[newLevel].name}}</view>
                    </picker>
                </view>
                <view  class="row_style">
                    <text class="title">物品价格:</text>
                    <input class="uni-input" type="number"  name="goodPrice" placeholder="请输入价格" />
                </view>
                <view  class="colum_style">
                    <text class="title">物品图片或视频:</text>
                    <htz-image-upload :max="19" v-model="ceshiData" mediaType="all" :chooseNum="9" :sourceType="['album','camera']"
                        :compress="false" :quality="80" :formData="{'businessType': 'ershou'}" :remove="true"
                        @uploadSuccess="ceshiUploadSuccess" @imgDelete="ceshiImgDelete" @uploadFail="ceshiUploadFail"
                        :action="mediaActionUrl"></htz-image-upload>
                </view>
                <view  class="colum_style">
                    <text class="title">物品描述:</text>
                    <textarea  name="goodDesc" placeholder-style="color:#666666" placeholder="请输入物品描述不少20个字"/>
                </view>
                
                <view class="uni-btn-v">
                     <button form-type="submit" plain="true">发布</button>
                </view>
            </form>
        </view>
    </view>
</template>
<script>
    // import htzImageUpload from '/components/htz-image-upload/htz-image-upload.vue'
     import bar from '@/components/bar';
      var  graceChecker = require("../../common/graceChecker.js");
    export default {
        components:{
                bar
            },
           data() {
                return {
                    baseUrl:getApp().globalData.baseUrl,
                    array: [{name:'9成新'},{name: '8成新'}, {name:'7成新'}, {name:'7成以下'}],
                    newLevel: 0,
                    ceshiData: [
                    
                    ],
                    incAttachments:"",
                    setNav:{
                        'bg':'yellow',  //背景色
                        'color':'red',  //字体颜色
                        'isdisPlayNavTitle':true, //是否显示返回按钮,由于导航栏是共用的,把所有的东西封装好,
                        'isdisPlayNavLeftButton':false,
                        // 然后有些页面不需要的东西通过条件控制进行显示与隐藏
                        'navTitle':'新增物品' //导航标题
                    },// 数据列表
                    mediaActionUrl:getApp().globalData.baseUrl+'/app/attachment/upload/Media'
                }
            },
        methods: {
            
            bindPickerChange: function(e) {
                console.log('picker发送选择改变,携带值为:' + e.detail.value)
                this.newLevel = e.detail.value;
                
                
            },
            formSubmit: function(e) {
                console.log('form发生了submit事件,携带数据为:' + JSON.stringify(e.detail.value))
                //定义表单规则
                var rule = [
                    {name:"goodName", checkType : "string", checkRule:"1,10",  errorMsg:"物品名称应为1-10个字符"},
                    {name:"goodDesc", checkType : "string", checkRule:"20,",  errorMsg:"物品描述不少20个字符"},
                    
                ];
                //进行表单检查
                var formData = e.detail.value;
                var incAttachments=this.incAttachments.substring(0,this.incAttachments.length-1);
                formData["incAttachments"]=incAttachments;
                formData["newLevel"]=this.newLevel;
                var checkRes = graceChecker.check(formData, rule);
                if(checkRes){
                    if(this.ceshiData.length <= 0){
                         uni.showToast({title:"请添加物品图片或视频!", icon:"none"});
                         return;
                    }
                    
                    if(formData['goodPrice'].length <=0){
                        uni.showToast({title:"请输入价格!", icon:"none"});
                        return;
                    }
                    
                    //uni.showToast({title:"验证通过!", icon:"none"});
                  
                    uni.request({
                            url: getApp().globalData.baseUrl+"/app/secondHand/add",
                            data: JSON.stringify(formData),
                            method: "post",
                            success:(res)=> {
                                uni.showToast({title:"提交成功!", icon:"none"});
                                console.log(JSON.stringify(res));
                                uni.navigateBack({
                                    
                                });
                                
                            },
                            fail:(res)=>{
                                uni.showToast({title:"提交成功!", icon:"none"});
                            }
                        });
                  
                  
                  
                }else{
                    uni.showToast({ title: graceChecker.error, icon: "none" });
                }
            },
            ceshiUploadSuccess(res) { //上传成功
                console.log('res', this)
                /****************
                因为上传接口返回的结构不一致,所以以下代码需要根据实际的接口返回结构开发,在此只是展示如果给数组里添加的过程,仅供参考
                ***************/
                var _res = JSON.parse(res.data);
                console.log('_res', _res)
                if (_res.success) {
                    
                    this.ceshiData.push(getApp().globalData.host+"/" + _res.data.path);
                    this.incAttachments+=_res.data.id+",";
                }
                /*******************************/
            },
            ceshiUploadFail(err) { //上传失败
                console.log('err', err)
            },
            ceshiImgDelete(e) {
                console.log('ceshiImgDelete', e)
            },
            formReset: function(e) {
                console.log('清空数据')
            }
        }
    }
</script>

<style>
    .uni-form-item .title {
        width: 150rpx;
        text-align: right;
    }
    .uni-input{
        width:560rpx;
        margin-left: 10rpx;
    }
    .row_style{
        display: flex;
        flex-direction: row;
        margin-left: 15rpx;
        margin-right: 15rpx;
        margin-top: 30rpx;
        
    }
    .colum_style{
        display: flex;
        flex-direction: column;
        margin-left: 15rpx;
        margin-right: 15rpx;
        margin-top: 30rpx;
        
    }
</style>
 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值