微信小程序开发--首页及详情页开发

news/2024/7/20 4:13:26 标签: 小程序

一、常用组件

在之前的封装请求数据的模块中请求轮播图的数据

1.首页轮播图数据的请求以及渲染

1.轮播图数据的请求pages/index/index.js

data: {
    bannerlist:[]  //存放轮播图数据的列表
},
onLoad: function () {
    //请求首页轮播图的数据
    request({
        url : '/banner' //注意接口不要写错
    }).then(res => {
        console.log(res)
        // 在Vue中,this.bannerist = res.data.data
        // 在React中,this.setState(bannerlist: res.data.data)
        // 在小程序中修改状态的方式就是this.setData
        this.setData({ //将获取到的数据保存到本地变量中
          bannerlist: res.data.data
        })
    })
}

同理之前通过/pro接口获取到的商品列表的数据也可以通过this.setData来保存本地:

data: {
    bannerlist:[],  //存放轮播图数据的列表
    prolist:[] //存放商品数据的列表
},
...
this.setData({ 
    prolist: res.data.data
})

为了代码更加直白美观,可以将获取商品列表数据和请求轮播图数据另外封装在自定义方法中,然后在onLoad中调用就可以了:

onLoad: function () {
    // 请求轮播图数据
    this.getBannerlistData()
    // 请求商品列表数据
    this.getProlistData()
},
...
//请求轮播图数据
getBannerlistData () {
    request({
    url : '/banner' 
    }).then(res => {
    console.log(res)
    // 在Vue中,this.bannerist = res.data.data
    // 在React中,this.setState(bannerlist: res.data.data)
    // 在小程序中修改状态的方式就是this.setData
    this.setData({ //将获取到的数据保存到本地变量中
    bannerlist: res.data.data
    })
    })  //可以省略catch方法,。没有关系
},
  //请求商品列表数据
  getProlistData () {
      request({
      url : '/pro',
      data : {}
      }).then((res) => { //then是请求成功后的处理方法
      console.log(res)
      this.setData({ 
      prolist: res.data.data
      })
      }).catch((err) => { //catch是请求失败后的处理方法
      console.log(err)
      })
  }

3.使用组件 - 视图容器 - swiper

滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。 一些属性见官方文档:小程序官方文档–swiper

<swiper
  indicator-dots="{{true}}" autoplay="{{true}}" circular="{{true}}" 
  duration="{{500}}">
  <!-- wx:key=""不知道写啥的话可以写*this,指的就是自己 -->
  <block wx:for="{{bannerlist}}" wx:key="index">
    <swiper-item >
      <image src="{{item.img}}"></image>
    </swiper-item>
  </block>
</swiper>
<prolist></prolist>

注意:上面的item.img是根据获取到的数据结构来判断的,不能直接写item,因为item指的是每一行的数据,我们要的仅仅是图片数据,所以只需要选取其路径item.img就可以了。
在这里插入图片描述

如果碰到图片显示不全或者没有铺满屏幕的情况,在wxss中设置一下即可,例如铺满屏幕:

image {
  width: 100%;
}

更多设置图片格式的方法:关于图片的其它一些属性

轮播图的使用就到此为止。

二、自定义组件 - 产品列表

1.自定义组件的布局

components/prolist/prolist.wxml列表组件prolist的布局:

<view class="prolist">
  <view class="proitem">
    <view class="itemimg">
      <image class="img" src=""></image>
    </view>
    <view class="iteminfo">
      <view class="title">
        产品名称
      </view>
      <view class="price">
        ¥199
      </view>
    </view>
  </view>
</view>

2.自定义组件的样式

components/prolist/prolist.wxss列表组件prolist的样式:

.prolist .proitem{
  width: 100%;
  display: flex;
  height: 100px;
  box-sizing: border-box;
  border-bottom: 1px solid #ccc;
}

.prolist .proitem .itemimg{
  width: 100px;
  height: 100px;
  padding: 5px;
}

.prolist .proitem .itemimg .img{
  width: 90px;
  height: 90px;
  box-sizing: border-box;
  border: 1px solid #ccc;
}

.prolist .proitem .iteminfo {
  padding: 3px;
}

.prolist .proitem .iteminfo .title{
  font-size: 18px;
  font-weight: bold;
}

.prolist .proitem .iteminfo .price{
  font-size: 12px;
}

3.首页请求数据,并且传递给子组件

pages/index/index.js

首页请求数据就是之前自定义的两个方法getBannerlistData ()getProlistData ()

pages/index/index.wxml

<prolist prolist="{{prolist}}"></prolist>

vue父组件给子组件传值:

父组件调用子组件的地方,添加一个自定义的属性,属性的值就是父组件要传递给子组件的值

如果属性的值是变量booleannumder,就需要绑定属性

子组件定义的地方,添加一个 props选项,props的值是一个数组或者对象

  1. 如果是数组,数组的元素就是添加的属性名,可以在组件中通过此属性名访问数据

  2. 如果是对象,有两种形式:

    2.1.key值为自定义的属性名,value值为数据类型

    2.2.key值为自定义的属性名,value值为一个对象,该对象有两个选项,一个为type(数据类型),另一个为default(默认值),如果默认值是对象或者数组,需要把default写成一个函数,返回对象或数组

小程序中:

父组件调用子组件的地方,添加一个自定义的属性,属性的值就是父组件要传递给子组件的值

如果属性的值是变量booleannumder,就需要用{{}}包裹

<prolist prolist="{{ prolist }}"/>

子组件定义的地方,添加一个 properties选项,properties的值是一个数组或者对象

key为自定义的属性名,value值为数据类型:

properties: {
	prolist:Array 
}

可以在组件中通过此属性名访问数据

4.子组件接收数据

components/prolist/prolist.js

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    prolist: Array
  },
})

5.子组件渲染数据

components/prolist/prolist.wxml

<view class="prolist">
  <view class="proitem" wx:for="{{prolist}}" wx:key="item.proid">
    <view class="itemimg">
      <image class="img" src="{{item.proimg}}"></image>
    </view>
    <view class="iteminfo">
      <view class="title">
        {{item.proname}}
      </view>
      <view class="price">
        ¥{{item.price}}
      </view>
    </view>
  </view>
</view>

三、实现下拉刷新上拉加载

1.开启首页的下拉刷新功能

pages/index/index.json

{
  "usingComponents": {
    "prolist": "/components/prolist/prolist"
  },
  "enablePullDownRefresh": true, //实现下拉刷新
  "backgroundColor": "#efefef",
  "backgroundTextStyle": "dark"
}

2.完善相关的下拉刷新函数

pages/index/index.js

//页面相关事件处理函数---监听用户下拉刷新事件(重新请求了第一页的页面数据)
  onPullDownRefresh: function() {
    console.log("刷新了当前页面")
    this.getRefreshData() //下拉刷新之后重新请求第一页的数据
  },
  //上拉触底事件函数
  /**
   * 上拉加载---分页效果,例如开始是第一页10条数据,下拉到底之后再向数据库中请求后10条数据显示出来,这个过程需要页码
   */
  onReachBottom: function() {
    console.log("对不起已经到底了")
    this.requestMoreData()
  },
...
// 下拉刷新后重新请求第一页的数据
  getRefreshData () {
    request({
      url : '/pro',
      data : {
        pageCode: 0, // 页码默认从0开始
        limitNum: 10 //每一页默认10条数据
      }
    }).then((res) => { //then是请求成功后的处理方法
      console.log(res)
      this.setData({ 
        prolist: res.data.data,
        pageCode: 1 //下拉刷新之后切记 要将页码重新置为0
      })
      // 真机测试的时候,在下拉刷新结束后需要 停止 下拉刷新的操作
      wx.stopPullDownRefresh();
    }).catch((err) => { //catch是请求失败后的处理方法
      console.log(err)
    })
  },
  // 上拉触底后再次请求更多的数据显示(翻页)
  requestMoreData () {
    request({
      url : '/pro',
      data : {
        pageCode: this.data.pageCode, // 页码默认从0开始
        limitNum: 10 //每一页默认10条数据
      }
    }).then((res) => { //then是请求成功后的处理方法
      console.log(res)
      // 请求之后需要判断
      // 1.判断还有没有数据
      if (res.data.code === '10000') {
        // 没有更多数据了,要给用户提示信息
        toast({title: '没有更多数据了'}) // 这里toast的参数必须是对象类型
      } else {
        // 2.如果有数据---请求到的数据追加到之前的数据上
        // vue 中, thisprolist = [...this.prolist,res.data.data]
        // 小程序中 修改数据的方式类似于 React
        // React 获取数据  处理数据  修改数据(状态)
        // 3.每一次请求完成页码要+1
        let arr = this.data.prolist //获取数据 
        let num = this.data.pageCode //获取页码
        let list = [...arr,...res.data.data] //处理数据
        num += 1
        this.setData({  //修改数据
          prolist: list,
          pageCode: num
        })
      }
    })
  }

四、返回顶部功能实现

<!-- 返回顶部按钮 -->
<!-- 绑定事件 -->
<!-- 小程序中有两种绑定事件的方法---移动端尽量不使用click事件,建议使用tap事件,或者用touch代替click事件 
  bindtap:
  catchtap:组织冒泡
-->
<button class="backtop" bindtap="backtop">返回顶部</button>

CSS样式文件:

.backtop {
  position: fixed;
  bottom: 20px;
  right: 10px;
  border-radius: 5px;
  background-color: #f66;
}

pages/index/index.js

backtop: function () {
    // 小程序api 的界面 - 滚动
    wx.pageScrollTo({
        scrollTop: 0,
        duration: 300
    })
}

五、实现点击商品列表进入产品的详情页面

1.构建详情页面

"pages": [
  "pages/detail/detail"
],

2.声明式导航跳转

<!-- 首页商品列表点击进入详情页面vue和React
 1.声明式导航
   vue <router-Link></router-Link>
   React <Link></Link>  <NavLink></NavLink>
 2.编程式导航
   new Vue ({router ,store ,el:' ' })
   vue  this.$router.push()  replace()  go()  back()
   React this.props.history.push()
-->
<!-- 小程序中的点击进入详情页面
   1.声明式导航---标签跳转---<a></a>
   https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html
   格式为:<navigator url=" " open-type=" " ></navigator>
   open-type:
     navigate:保留当前页面,新添加一个页面,不能添加tab页面--push
     redirect:替换当前页面,不能替换tab页面--replace
     switchTab:切换当前的tab页面--小程序特有
     navigateBack:返回--back,goBack
   2.编程式导航---JS跳转---window.location.href=""
   https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab.html
 -->

小程序 组件-导航-navigator

<!-- 声明式导航 -->
<view class="prolist">
  <!-- 因为每一个商品列表都有跳转功能,循环遍历时要用在navigator上面 -->
  <navigator url="/pages/detail/detail" wx:for="{{prolist}}" wx:key="item.proid">
    <view class="proitem">
      <view class="itemimg">
        <image class="img" src="{{item.proimg}}"></image>
      </view>
      <view class="iteminfo">
        <view class="title">{{item.proname}}</view>
        <view class="number">目前已售出{{item.sales}}件 / 剩余{{item.stock}}件</view>
        <view class="price">¥{{item.price}}</view>
      </view>
    </view>
  </navigator>
</view>

3.详情页面接收数据并且渲染数据

小程序向目标页面传递参数使用的是:/../..?+参数,例如:

url="{{'/pages/detail/detail?proid='+item.proid}}"

在目标页面的onLoad函数中的参数options就是传递过来的参数。pages/detail/detail.js

import { request } from './../../utils/index.js'
Page({
...
  data: {
    proid: '', // 在商品加入购物车时必须要用到的proid
    proname: '',
    proimg: '',
    desc: '',
    price: 0
  },
  onLoad: function (options) {
    console.log(options)
    // 获取传递过来的参数值proid
    const { proid } = options
    // 请求产品详情的数据
    request({
      url:'/pro/detail?proid=' + proid
      // url:'/pro/detail?proid=${proid}'

    }).then(res => {
      console.log(res.data)
      // 解构赋值
      const { proid, proname, price, proimg, desc} = res.data.data
      // const { data:{proid, proname, price, proimg, desc}} = res.data
      // 修改状态
      this.setData({
        proid, proname, price, proimg, desc
      })
    })
  },
...
})

pages/detail/detail.wxml

<image src="{{proimg}}" style="width: 100px;height: 100px;"></image>
<view>{{proname}}</view>
<view>¥{{price}}</view>
<view>{{desc}}</view>

4.编程式导航渲染

使用小程序提供的api实现编程式路由的跳转:

wx.switchTab(Object object)

跳转到tabBar页面,并关闭其他所有非tabBar页面。

wx.reLaunch(Object object)

关闭所有页面,打开到应用内的某个页面。

wx.redirectTo(Object object)

关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到tabbar页面。

wx.navigateTo(Object object)

保留当前页面(会保存在页面栈中),跳转到应用内的某个页面。但是不能跳到tabbar页面。使用wx.navigateBack可以返回到原页面。小程序页面栈最多十层。

wx.navigateBack(Object object)

关闭当前页面,返回上一页面或多级页面。可通过getCurrentPages获取当前的页面栈,决定需要返回几层。

小程序传递数据使用data-params形式,可以在事件中根据event获取该参数,用bindtap来绑定单击事件

<view class="prolist">
  <view class="proitem" bindtap="toDetail" data-proid="{{item.proid}}" wx:for="{{prolist}}" wx:key="item.proid">
    <view class="itemimg">
      <image class="img" src="{{item.proimg}}"></image>
    </view>
    <view class="iteminfo">
      <view class="title">{{item.proname}}</view>
      <view class="number">目前已售出{{item.sales}}件 / 剩余{{item.stock}}件</view>
      <view class="price">¥{{item.price}}</view>
    </view>
  </view>
</view>

components/prolist/prolist.js

Component({
...
  methods: {
    toDetail (event) {
      console.log('跳转到详情页面',event)
      // 获取到产品id
      const { proid } = event.currentTarget.dataset
      // 编程式导航
      // 如果跳转的是tab页面,可以使用switchTab 或者 reLuanch
      // 如果跳转的是非tab页面,可以使用 redirectTo 或者 navigateTo 或者 reLuanch
      //1.navigateTo
      wx.navigateTo({
        url: '/pages/detail/detail?proid=' + proid
        // url: '/pages/detail/detail?proid=${proid}'   这种写法无法解析
      })
      //2.redirectTo  页面的左上角没有了返回按钮
      // wx.redirectTo({
      //   url: '/pages/detail/detail?proid=' + proid
      // })
      //3.reLuanch
      // wx.reLaunch({
      //   url: '/pages/detail/detail?proid=' + proid
      // })
    }
  }
})

关于getCurrentPages的用法:

detail.js

onShow: function () {
console.log(getCurrentPages())
// console.log(getCurrentPages()[getCurrentPages().length-1])  输出当前页面(即当前自己页面)
// console.log(getCurrentPages()[getCurrentPages().length-2])  输出首页(即上一个页面)
// console.log(getCurrentPages()[getCurrentPages().length-3])  undefined,因为数组中只有两个元素
},

length-1对应的就是当前页面,length-2就是(页面栈)上一个页面,以此类推。

如果详情页面的数据量处理特别多,可以将获取数据抽离出来,封装成方法

request({
    url:'/pro/detail?proid=' + proid
    // url:'/pro/detail?proid=${proid}'  这种写法无法解析
}).then(res => {this.getDetailData(res,proid)})
...
// 将then之后获取数据成功后的方法进行封装
getDetailData (res,proid) {
    console.log(res.data)
    // 解构赋值
    // 此处proid不需要从接口中获取自己内部已经有了
    const { proname, price, proimg, desc} = res.data.data
    // const { data:{proid, proname, price, proimg, desc}} = res.data
    // 修改状态
    this.setData({
        proid, proname, price, proimg, desc
    })
},

六.使用第三方组件库

1.WeUI

WeUI 是微信官方出品的组件库,它沿用了微信的视觉设计与交互设计,提供了各类原生组件的基础样式,风格简约大方。选用这一套组件库,可以让你的小程序与微信本身保持一致的界面风格。

2.iViewUI

iViewUI 是由TalkingData发布的组件库。iViewUI开发文档

3.Vant Weapp

Vant Weapp官方地址

Vant 是由有赞发布的,轻量的小程序 UI 组件库。如果你想制作一款电商、餐饮、外卖平台、票务预订等购物类小程序,选用 Vant 是较为合适的。Vant Weapp里边的组件是基于小程序自定义组件开发的。

Vant Weapp快速上手步骤

1.安装

,如果后面出现无法构建的情况,安装之前可以使用一下:

npm init
npm i @vant/weapp -S --production

2.构建npm包

打开微信开发者工具,点击 工具 -> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件。

img

3.使用组件

在使用之前将app.json中的 "style": "v2" 去除,小程序的新版基础组件强行加上了许多样式,难以去除,不关闭将造成部分组件样式混乱。

首先在全局配置文件app.json或者页面配置文件index.json中引入:

"usingComponents": {
  "van-goods-action": "@vant/weapp/goods-action/index",
  "van-goods-action-icon": "@vant/weapp/goods-action-icon/index",
  "van-goods-action-button": "@vant/weapp/goods-action-button/index"
}

接着在detail.wxml中添加:

<van-goods-action>
  <van-goods-action-icon icon="chat-o" text="客服" />
  <van-goods-action-icon icon="cart-o" text="购物车" />
  <van-goods-action-button
    text="加入购物车"
    type="warning"
  />
  <van-goods-action-button text="立即购买" />
</van-goods-action>

如果出现 json: ["usingComponents"]["van-goods-action"]未找到,再次点击 工具 -> 构建 npm即可。如果最终的实现效果和文档中的不一致,那么或许是详情–本地设置–调式基础库的原因。

"usingComponents": {
  "van-goods-action": "@vant/weapp/goods-action/index",
  "van-goods-action-icon": "@vant/weapp/goods-action-icon/index",
  "van-goods-action-button": "@vant/weapp/goods-action-button/index"
}

接着在detail.wxml中添加:

<van-goods-action>
  <van-goods-action-icon icon="chat-o" text="客服" />
  <van-goods-action-icon icon="cart-o" text="购物车" />
  <van-goods-action-button
    text="加入购物车"
    type="warning"
  />
  <van-goods-action-button text="立即购买" />
</van-goods-action>

如果出现 json: ["usingComponents"]["van-goods-action"]未找到,再次点击 工具 -> 构建 npm即可。如果最终的实现效果和文档中的不一致,那么或许是详情–本地设置–调式基础库的原因。


http://www.niftyadmin.cn/n/909619.html

相关文章

HDU 1061 Rightmost Digit解决问题的方法

求大量N^N的值最右边的数字&#xff0c;即最低位。 它将能够解决一个简单二分法。 只是要注意溢出&#xff0c;只要把N % 10之后。我不会溢出&#xff0c;代替使用的long long。 #include <stdio.h> int rightMost(int n, int N) {if (n 0) return 1;int t rightMost(n…

微信小程序开发--分类页面实现

微信小程序开发–分类页面实现 之前在详情页面利用Vant Weapp的UI库构建出了GoodsAction 商品导航功能&#xff0c;接着需要在分类页面(kind.wxml)实现商品分类。 1.引入第三方组件 用到的是Tab标签页 在kind.json中写入&#xff1a; "usingComponents": {"…

HDU 1711 Number Sequence

在nnext数组保存前面的字符的前缀与后缀的最大匹配&#xff0c;即nnext[i]保存的是当i匹配不成功时应带回朔到的位置 #include <iostream> #include <cstdio> #include <cstring>using namespace std;#define maxn 1000050int s1[maxn]; int s2[maxn]; int n…

Android得到一个闹钟在第三方

收集报警信息 闹铃时间,闹铃备注信息 闹铃引起系统变化的点&#xff1a; 1. Send Notification (正点闹钟能够设置不发送) 2. Play audio 闹铃信息结构体 ClockInfo{ String apkName; String startTime; String backup; } SendNotification SystemUI BaseStatusBar.java 在Base…

微信支付之内置浏览器的H5页面支付

微信支付之内置浏览器的H5页面支付 因为项目需要&#xff0c;要在H5页面中加入微信支付&#xff0c;所以便去尝试&#xff0c;只想说真的很坑&#xff0c;尤其调试起来不方便 这是微信的官方API文档 微信API 微信支付的准备工作 申请公众号&#xff0c;申请开通支付&#xff0c…

uni-app个人中心页开发

uni-app个人中心页开发 1.拍照&#xff0c;选择图片 user.vue&#xff1a; <template><view><view class"takephoto" click"takephoto">拍照</view><image v-for"(item,index) of imglist" :src"item" …

多态的理解

面向对象三原则&#xff1a;继承、封装、多态。 必要条件&#xff1a;继承、重写、父类引用指向子类对象。 重载是类中多态性的表现&#xff0c;重写是父类和子类间多态性的表现。 如果在子类中定义某方法与其父类有相同的名称和参数&#xff0c;我们说该方法被重写 。 子类的对…

uni-app购物车页面开发

uni-app购物车页面开发 1.加入购物车功能 detail.vue&#xff1a; <template><view><view><image :src"proimg" mode""></image><view>产品名称: {{proname}} </view><view>价格: {{price}} RMB</v…