微信小程序(笔记)

第一天

文档地址 https://www.showdoc.com.cn/128719739414963

01

在全局app.js中,输入app选择第三个,可以把常用方法补出来

在项目index.js中,输入的是page

02

把阿里图标库的代码放到styles的icon.wxss中,在全局app.wxss中引入

@import “./styles/icon.wxss”;

03

在app.json中输tabBar然后自动补全

其中pagePath是路径,text为文字,iconPath是未选中的图标,selectedIconPath是选中的图标

其中在tabBar下的属性中,color是未选中的字体颜色,selectedColor是选中时的颜色,backgroundColor是整体的背景颜色

"tabBar": {
    "color":"#999",
    "selectedColor":"#ff2d4a",
    "backgroundColor":"#fafafa",
    "list": [
      {
      "pagePath": "pages/index/index",
      "text": "首页",
      "iconPath": "./icons/首页.png",
      "selectedIconPath": "./icons/首页-o.png"
    },
    {
      "pagePath": "pages/category/index",
      "text": "分类",
      "iconPath": "./icons/分类.png",
      "selectedIconPath": "./icons/分类-o.png"
    },
    {
      "pagePath": "pages/cart/index",
      "text": "购物车",
      "iconPath": "./icons/购物车空.png",
      "selectedIconPath": "./icons/购物车空-o.png"
    },
    {
      "pagePath": "pages/user/index",
      "text": "我的",
      "iconPath": "./icons/我的.png",
      "selectedIconPath": "./icons/我的-o.png"
    }
  ]
  }

04

在微信小程序中 不支持 通配符 * ,所以要使用这种写法

page,view,text,swiper,swiper-item,image,navigator{
  padding:0;
  margin:0;
  box-sizing:border-box;
}

主题颜色,通过变量来实现

  1. less 中 存在 变量这个知识
  2. 原生的css和wxss也是支持 变量

在全局app.wxss中定义,字体默认直接使用

page{
	/* 定义主题颜色 */
	--themeColor:#eb4450;
    /*
    	定义统一字体大小 假设设计稿大小时  375px
   	 	1px=2rpx
   	 	14px = 28rpx
    */
  font-size:28rpx;
}

在index.wxss中使用

view{
	color:var(--themeColor)
}

在app.json中的window下

navigationBarBackgroundColor 是背景颜色

navigationBarTextStyle 是字体颜色

"window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#eb4450",
    "navigationBarTitleText": "收购阿里计划",
    "navigationBarTextStyle":"white"
}

05 搜索框

先注册组件,在components文件夹中新建一个目录,名字为SearchInput,再右键文件夹创建component,名字与文件夹名字相同

之后在要使用该组件的index.json中使用usingComponents,进行注册

{
  "usingComponents": {
    "SearchInput":"../../components/SearchInput/SearchInput"
  },
  "navigationBarTitleText":"首页"
}

components中SearchInput.wxml

<view class="search_input">
/* url是跳转地址,open-type="navigate"是跳转到非tabBar页面 */
  <navigator url="/pages/search/index" open-type="navigate">
    搜索
  </navigator>
</view>

SearchInput.wxss

.search_input{
  height:90rpx;
  padding:10rpx;
  background-color:var(--themeColor)
}
.search_input navigator{
  display:flex;
  justify-content: center;
  align-items: center;
  background-color:#fff;
  color:#666;
  height:100%;
  border-radius:15rpx;
}

06 轮播图请求数据

Page({
  data: {
    swiperList:[]
  },
  /* 页面一加载就会触发 */
  onLoad: function (options) {
    wx.request({
      url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata',
      success:(result)=>{
        this.setData({
          swiperList:result.data.message
        })
      }
    })
  }
})

将数据传输给data

this.setData({
swiperList:result.data.message
})

07 轮播图渲染

先进行for循环,除了key以外,其他调用都需要 {{}} 括号,并且循环时,默认item是数据,index是下标

<!--
	1 swiper标签存在默认的宽度和高度
	  100% * 150px
	2 image标签也存在默认的宽度和高度
	  320px * 240px
	3 设计图片和轮播图
	  1 先看一下原图的宽高  750 * 340
	  2 让图片的高度自适应 宽度 等于100%
	  3 让swiper标签的高度 变成和图片的高一样即可
	4 图片标签
	  mode属性 渲染模式
	  	widthFix 让图片的标签宽高 和 图片标签的内容的宽高等比
-->
<view class="index_swiper">
    <swiper indicator-dots autoplay circular>
    <swiper-item wx:for="{{swiperList}}" wx:key="goods_id">
      <navigator>
        <image src="{{item.image_src}}" mode="widthFix"></image>
      </navigator>
    </swiper-item>
  </swiper>
  </view>

其中swiper中的其他属性分别是:

indicator-dots 是否显示面板指示点

indicator-color 指示点颜色

indicator-active-color 当前选中的指示点颜色

autoplay 是否自动切换

circular 是否循环轮播

/* 轮播图 */
.index_swiper swiper{
  width:750rpx;
  height:340rpx;
}
.index_swiper swiper image{
  width:100%;
}

08 导航渲染

通过flex布局,每一个for循环出来的都占比份1,之后用padding把盒子挤过去

  <view class="index_cate">
    <navigator wx:for="{{cateList}}" wx:key="name">
      <image mode="widthFix" src="{{item.image_src}}"></image>
    </navigator>
  </view>
/* 导航 */
.index_cate {
  display:flex;
}
.index_cate navigator{
  flex:1;
  padding:15rpx;
}
.index_cate navigator image{
  width:100%;
}
data: {
    cateList:[]
  },
getCateList(){
    wx.request({
      url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/catitems',
      success:(result)=>{
        this.setData({
          cateList:result.data.message
        })
      }
    })
  }

第二天

09 楼层

获取数据

  getFloorList(){
    wx.request({
      url:"https://api-hmugo-web.itheima.net/api/public/v1/home/floordata",
      success:(result)=>{
        this.setData({
          floorList:result.data.message
        })
      }
    })
  }

wxml

<!-- 楼层开始 -->
  <view class="index_floor">
    <view class="floor_group" wx:for="{{floorList}}" wx:for-item="item1" wx:for-index="index1" wx:key="floor_title">
      <!-- 标题 -->
      <view class="floor_title">
        <image src="{{item1.floor_title.image_src}}" mode="widthFix"></image>
      </view>
      <!-- 内容 -->
      <view class="floor_list">
        <navigator wx:for="{{item1.product_list}}" wx:for-item="item2" wx:for-index="index2" wx:key="name">
        <image src="{{item2.image_src}}" mode="{{index2===0?'widthFix':'scaleToFill'}}"></image>
        </navigator>
      </view>
    </view>
  </view>
  <!-- 图片的scaleToFill是根据高度自适应 -->
  <!-- 楼层结束 -->

wxss

.floor_gourp .floor_title image{
  width:100%;
}
.floor_title{
  padding:10rpx 0;
}
.floor_list{
  overflow:hidden;
}
.floor_list navigator{
  float: left;
  width:33.33%;
}
.floor_list navigator:nth-last-child(-n+4){
  height:27.72711207vw;
  border-left:10rpx solid #fff;
}
.floor_list navigator:nth-child(2),
.floor_list navigator:nth-child(3){
  border-bottom:10rpx solid #fff;
}
.floor_list navigator image{
  width:100%;
  height:100%;
}

10 分类页获取数据

js代码

// pages/category/index.js
Page({

  data: {
    //左侧的菜单数据
    leftMenuList:[],
    //右侧的商品数据
    rightContent:[]
  },
  Content:[],
  onLoad: function (options) {
    this.getMenuList();
  },
  getMenuList(){
    wx.request({
      url: 'https://api-hmugo-web.itheima.net/api/public/v1/categories',
      success:(result)=>{
        this.Content=result.data.message
        let leftMenuList = this.Content.map(v=>v.cat_name)
        let rightContent = this.Content[0].children
        console.log(rightContent);
        this.setData({
          leftMenuList,
          rightContent
        })
        console.log(result);
      }
    })
  }

})

11 分类页布局

这个是微信小程序提供给我们的能够上下拉动,左右拉动的标签

wxss vh和vw是手机屏幕的宽高,总占100份

page{
  height:100%;
}
.cates{
  height:100%;
}
.cates .cates_container{
  height:calc(100vh - 90rpx);
  display:flex;
}
.cates .cates_container .left_menu{
  flex:2;
  background-color: aqua;
}
.cates .cates_container .right_content{
  flex:5;
  background-color: lawngreen;
}

wxml scroll-y是可以让纵向滚动

<view class="cates">
  <SearchInput></SearchInput>
  <view class="cates_container">
    <!-- 左侧菜单 --> 
    <scroll-view scroll-y class="left_menu">

    </scroll-view>
    <!-- 右侧商品内容 -->
    <scroll-view class="right_content"></scroll-view>
  </view>

</view>

第三天

12 分类页面布局2

学习布局方法

wxss完整代码

page{
  height:100%;
}
.cates{
  height:100%;
}
.cates .cates_container{
  height:calc(100vh - 90rpx);
  display:flex;
}
.cates .cates_container .left_menu{
  flex:2;
}
.cates .cates_container .right_content{
  flex:5;
}


/* 第三天 */
.active{
  color:var(--themeColor);
  border-left:5rpx solid currentColor;
  width:95%;
  background-color: rgba(224, 224, 224, 0.3);
}
.left_menu .menu_list{
  height:80rpx;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:30rpx;
}
.right_content .goods_group .goods_list{
  display:flex;
  flex-wrap:wrap;
}
.right_content .goods_group .goods_list navigator{
  width:33.33%;
  text-align:center;
}
.right_content .goods_group .goods_list navigator image{
  width:50%;
}
.goods_title{
  display:flex;
  justify-content:center;
  align-items:center;
  height:80rpx;
}
.goods_title .delimiter{
  color:#ccc;
  padding:0 10rpx;
}

wxml完整代码

<view class="cates">
  <SearchInput></SearchInput>
  <view class="cates_container">
    <!-- 左侧菜单 -->
    <scroll-view scroll-y class="left_menu">
      <view class="menu_list {{index===currentIndex?'active':''}}" wx:for="{{leftMenuList}}" wx:for-item="item1" wx:key="*this">
        <view>{{item1}}</view>
      </view>
    </scroll-view>
    <!-- 右侧商品内容 -->
    <scroll-view scroll-y class="right_content">
      <view class="goods_group"
      wx:for="{{rightContent}}"
      wx:for-item="item1"
      wx:for-index="index1"
      wx:key="cat_id"
      >
        <view class="goods_title">
          <text class="delimiter">/</text>
          <view class="title">{{item1.cat_name}}</view>
          <text class="delimiter">/</text>
        </view>
        <view class="goods_list">
          <navigator
          wx:for="{{item1.children}}"
          wx:for-item="item2"
          wx:for-index="index2"
          wx:key="cat_id"
          >
            <image mode="widthFix" src="{{item2.cat_icon}}"></image>
            <view>{{item2.cat_name}}</view>
          </navigator>
        </view>
    </view>
    </scroll-view>
  </view>

</view>

js中多加了一个

data:{
	//实时点击切换
    currentIndex:0
}

13 点击实时切换

bindtap 点击事件,相当于绑定了@onclick

**data-index ** 传参 数据就会传到点击事件的e.currentTarget.dataset中

例:data-index="{{index}}"

实现原理 :

  1. 获取被点击的标题身上的索引
  2. 给data中的currentIndex赋值就可以了

js代码

// pages/category/index.js
Page({

  data: {
    //左侧的菜单数据
    leftMenuList:[],
    //右侧的商品数据
    rightContent:[],
    //实时点击切换
    currentIndex:0
  },
  Content:[],
  onLoad: function (options) {
    this.getMenuList();
  },
  getMenuList(){
    wx.request({
      url: 'https://api-hmugo-web.itheima.net/api/public/v1/categories',
      success:(result)=>{
        this.Content=result.data.message
        let leftMenuList = this.Content.map(v=>v.cat_name)
        let rightContent = this.Content[0].children
        this.setData({
          leftMenuList,
          rightContent
        })
      }
    })
  },
  handleItemTap(e){
    const {index} = e.currentTarget.dataset;
    let rightContent = this.Content[index].children;
    this.setData({
      currentIndex:e.currentTarget.dataset.index,
      rightContent
    })
  }
})

14 缓存技术

  1. 先判断一下本地存储中有没有旧的数据
  2. 没有旧数据 直接发送新请求
  3. 有旧的数据 同时 旧的数据也没有过期 就是用 本地存储中的数据

wx.setStorageSync(“key”,“value”); 设置数据

wx.getStorageSync(“key”); 获取数据

// 获取本地存储中的数据(小程序中也是存在本地存储 技术)  
const Cates = wx.getStorageSync("cates");
// 判断 不存在,就发送请求
if(!Cates){
   	this.getMenuList();
}

getMenuList函数中的success下加入

// 把接口的数据存入到本地存储中
wx.setStorageSync("cates",{time:Date.now(),data:this.Content});

//cates是名称,time是时间戳,

onLoad完整代码

onLoad: function (options) {
    // 获取本地存储中的数据(小程序中也是存在本地存储 技术)
    const Cates = wx.getStorageSync("cates");
    // console.log(Cates);
    if(!Cates){
      this.getMenuList();
    }else{
      //  有旧的数据 定义过期时间 5s 
      if(Date.now()-Cates.time>1000*10){
        // 重新发送请求
        this.getMenuList();
      }else{
        this.Content = Cates.data;
        let leftMenuList = this.Content.map(v=>v.cat_name)
        let rightContent = this.Content[0].children
        this.setData({
          leftMenuList,
          rightContent
        })
      }
    }
  }

15 点击菜单,右侧列表置顶,优化

scroll-top 设置竖向滚动条位置

data中设置一个值num,然后在点击事件那里传值num:0,动态传参到前面

scroll-top="{{num}}"

16 商品列表 获取分类id

在navigator的url中传参

url="/pages/goods_list/index.wxml?cid={{item2.cat_id}}"

页面参数在左侧最下面点击看

参数获取:

在跳转页面中的onLoad中options就是cid参数

onLoad: function (options) {
	console.log(options);
}

17 实现搜索框与tabs组件

要想把引用的wxml中js的值传入components组建中,就使用名字相同的方法如下:

<Tabs tabs="{{tabs}}" bindtabsItemChange="TabsChange"></Tabs>
<!-- tabsItemChange这个是Tabs.js中定义的方法,前面加上bind就是用来监听页面的,TabsChange是自己起的名字 -->

Tabs.js的接受方法:

  /**
   * 组件的属性列表
   */
  properties: {
    tabs:{
      type:Array,
      value:[]
    }
  }

引入页面(goods_list的index.js)的js数据

data: {
    tabs:[
      {
        id:0,
        value:"综合",
        isActive:true
      },
      {
        id:1,
        value:"销量",
        isActive:false
      },
      {
        id:2,
        value:"价格",
        isActive:false
      }
    ]
  },
    // 标题点击事件 从子组件传递过来
  TabsChange(e){
    //1 获取被点击的标题索引、
    const {index} = e.detail;
    //2 修改源数组
    let {tabs} = this.data;
    tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
    //3 赋值到data中
    this.setData({
      tabs
    })
  }

Tabs.js

methods: {
    handleItemTap(e){
      
      const {index} = e.currentTarget.dataset;
      //触发父组件中的事件
      this.triggerEvent("tabsItemChange",{index})
    }

在当前页面想要获取组件中的某一状态,需要使用到

this.triggerEvent(’ ',{},{}) components父组件需要传参,需要用到

第一个参数是自定义事件名称,这个名称是在页面调用组件时bind的名称,第二个对象就可以将想要的属性拿到,第三个参数文档中有介绍,有机会再做补充

第四天(21.03.28)

18 静态商品列表样式

可以让文字显示几行,剩下的变成…样式,css中的内容

.name{
    display:-webkit-box;
    overflow:hidden;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:2;   // 2就是显示两行
}

如:

卡奇莱德(katald)车载空气净化器除甲醛汽车内用负离子氧吧PM2.5除味器消除异味过滤灰尘吸收TVOC气体-灰色

就会显示为:卡奇莱德(katald)车载空气净化器除甲醛汽车内用负离子氧吧PM2.5除…

在静态商品这里有个小bug,页面在使用组件里的slot中,不能在wxss中使用class样式,只能使用行内样式或标签选择器navigator这种

<SearchInput></SearchInput>
<Tabs tabs="{{tabs}}" bindtabsItemChange="TabsChange">
  <block wx:if="{{tabs[0].isActive}}">
    <view class="goods_first">
      <navigator name="goods_item" style="display:flex;" wx:for="{{5}}">
        <!-- 左侧图片 -->
        <view class="goods_image" style="flex:2;display:flex;justify-content:center;align-items:center;">
          <image mode="widthFix" style="width:70%;" src="http://image1.suning.cn/uimg/b2c/newcatentries/0070134290-000000000149003877_1_800x800.jpg"></image>
        </view>
        <!-- 右侧内容 -->
        <view class="goods_info_wrap" style="flex:3;display:flex;justify-content:space-around;flex-direction:column;">
          <view class="name" style="display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2;">卡奇莱德(katald)车载空气净化器除甲醛汽车内用负离子氧吧PM2.5除味器消除异味过滤灰尘吸收TVOC气体-灰色</view>
          <view class="price" style="color:var(--themeColor);font-size:32rpx;">¥3999</view>
        </view>
      </navigator>

    </view>
  </block>
  <block wx:elif="{{tabs[1].isActive}}">1</block>
  <block wx:elif="{{tabs[2].isActive}}">2</block>
</Tabs>

19 动态渲染

goods_list 中 index.js

// pages/goods_list/index.js
Page({
  data: {
    goodsList:{}
  },
  QueryParams:{
    query:"",
    cid:"",
    pagenum:1,
    pagesize:10
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.QueryParams.cid = options.cid
    this.getGoodsList();
  },
  getGoodsList(){
    const that = this;
    // console.log(this.QueryParams.cid);
    wx.request({
      url:`https://api-hmugo-web.itheima.net/api/public/v1/goods/search?cid=${that.QueryParams.cid}&pagenum=${that.QueryParams.pagenum}&pagesize=${that.QueryParams.pagesize}&query=${that.QueryParams.query}`,
      success:(result)=>{
        console.log(result);
        this.setData({
          goodsList:result.data.message.goods
        })
      }
    })

  }
})

注:get传值时,自己加完参数别忘了前面加它自己本身pagenum=${that.QueryParams.pagenum}

index.wxml

注意的点只有一个,就是图片没有的时候,用三元运算符,把没有图片的数据加上一个默认图片,其他的直接个数据就好

src="{{item.goods_small_logo?item.goods_small_logo:'https://ww1.sinaimg.cn/large/007rAy9hgy1g24by9t530j30i20i2glm.jpg'}}"

20 加载下一页

  1. 用户上滑页面 滚动条触底 开始加载下一页

    1. 找到滚动条触底事件

    2. 判断还有没有下一页数据

      1. 获取到总页数 只有总条数

        总页数 = Math.ceil(总条数 / 页容量 pagesize)

        总页数 = Math.ceil(23 / 10) = 3

      2. 获取当前的页码

      3. 判断一下 当前的页码是否大于等于 总页数

    3. 假如没有下一页数据,弹出一个提示

    4. 假如还有下一页数据 加载下一页

      1. 当前的页码 ++
      2. 重新发送请求
      3. 数据请求回来 要对data中的数组 进行 拼接 而不是全部替换!!!

onReachBottom 监听用户上拉触底事件

在page中定义一个全局参数

toTalPages:1,

在请求的success中,写入

const total = result.data.message.total;
that.toTalPages = Math.ceil(total/that.QueryParams.pagesize)
console.log(that.toTalPages);  // 3
this.setData({
  goodsList:[...this.data.goodsList,...result.data.message.goods]
  // 使用解构赋值方法,否则数据会覆盖
})

onReachBottom()

// 下拉事件
  onReachBottom(){
    // console.log(132);
    if(this.QueryParams.pagenum>=this.toTalPages){
      // 没有下一页数据了
      wx.showToast({
        title: '没有数据了',
      })
    }else{
      this.QueryParams.pagenum++;
      this.getGoodsList();
    }
  },

21 下拉刷新

  1. 下拉刷新页面
    1. 触发下拉刷新事件 需要在页面的json文件中开启一个配置项 enablePullDownRefresh,backgroundTextStyle
      1. 找到 触发下拉刷新的事件 onPullDownRefresh
    2. 重置 数据 数组
    3. 重置页码 设置为1
    4. 重新发送请求
    5. 数据请求回来 需要手动的关闭 等待效果 wx.stopPullDownRefresh(),设置在监听用户下拉动作中

json中

enablePullDownRefresh Boolean false 是否全局开启下拉刷新

backgroundTextStyle String dark 下拉loading的样式,仅支持dark/light

js中

onPullDownRefresh function 监听用户下拉动作

js中的某个方法中

wx.stopPullDownRefresh()

 onPullDownRefresh(){
    // console.log(11);
    // 重置数组
    this.setData({
      goodsList:[]
    })
    //设置页码为1
    this.QueryParams.pagenum=1;
    //重新请求数据
    this.getGoodsList();
    //关闭下拉
    wx.stopPullDownRefresh();
  }
})

22 全局加载图标

wx.showLoading() 显示加载中的效果

wx.showLoading({
	title:"加载中",
	mask:true     //在加载中的时候,无法点击其他标签
})

wx.hideLoading() 关闭加载中的效果

23 商品详情

先修改名称

json中"navigationBarTitleText":“商品详情”

在跳转的页面中url="/pages/goods_list/index?goods_id={{item.goods_id}}"

detail获取数据

Page({

  data: {
    goodsObj:{}
  },
  goods_id:{},
  onLoad: function (options) {
    const {goods_id} = options;
    this.goods_id = goods_id
    this.getGoodsDetail();

  },
  getGoodsDetail(){
    wx.showLoading({
      title: '加载中',
      mark:true
    })
    wx.request({
      url:"https://api-hmugo-web.itheima.net/api/public/v1/goods/detail?goods_id="+this.goods_id,
      success:(result)=>{
        this.setData({
          goodsObj:result.data.message
        })
        console.log(result);
      }
    })
    wx.hideLoading();
  }
  
})

24 轮播图渲染

wxml

<view class="detail_swiper">
  <swiper indicator-dots autoplay circular>
    <swiper-item wx:for="{{goodsObj.pics}}" wx:key="pics_id">
      <image mode="widthFix" src="{{item.pics_mid}}"></image>
    </swiper-item>
  </swiper>
</view>

wxss

.detail_swiper swiper{
  height:65vw;    //vw  vh  
  text-align:center;
}
.detail_swiper swiper image{
  width:60%;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值