微信小程序开发学习(上强度):从0开始写项目

前置知识

1、配置插件

微信小程序 基础模板引入sass的两种方法_微信小程序使用sass-CSDN博客

之后在对应页面里新建一个scss文件,写css

2、注册小程序,有个自己的appid,不用测试号了

5.1.注册小程序账号获取appid及个人和企业版差异_哔哩哔哩_bilibili

微信公众平台

3、微信小程序开发学习(基础)-CSDN博客

4. Promise用法

异步相关,看完了有点蒙,不看也可以往下进行,但是会不知道原理

ES6 Promise的用法,async/await异步处理同步化 - 哔哩哔哩

5. 图

6. 第三方UI库使用

用的这个:Vant Weapp - 轻量、可靠的小程序 UI 组件库

安装:https://vant-contrib.gitee.io/vant-weapp/#/quickstart

5.9.第三方UI组件库vant weapp和TDesign_哔哩哔哩_bilibili

以icon为例,app.json导入组件,直接用

"usingComponents": {"van-icon": "@vant/weapp/icon/index"}

直接用 

        <van-icon name="contact-o"/>

----- 上手干项目 -----

 项目所需材料:https://gitee.com/qingnian8/weixinNative

0. 先写个网络请求接口之后用

建文件 /utils/request.js

第一个网址访问超限换第二个,但是第二个是测试用的脏数据

const baseURL = 'https://tea.qingnian8.com';
// const baseURL = 'https://www.fastmock.site/mock/13998300dc7574018c16109b0ef56a56/xzs';export function request(params){let dataObj = params.data || {};let headerObj = {			"content-type": "application/json"}return new Promise((resolve,reject)=>{wx.request({url: baseURL + params.url,method:params.method || "GET",data:dataObj,header:headerObj,success:res=>{if(res.data.errCode!=0){reject(res.data);wx.showToast({title: res.data.errMsg,mask:true,icon:"error"})return;}resolve(res.data)},fail:err=>{reject(err)}})})
}

1. app.*设置全局

设置全局最常用的view样式,使内填充padding不向外扩充,而是向内扩充,保证全局样式的不变

在app.wxss中设置view样式,之后在哪里用都不会改变了

view,text{/* 可以使padding往内扩展,使原有定义宽度不变 */box-sizing: border-box;  
}

定义全局配色(其实还不够灵活,有的json文件需要用颜色,无法导入变量)

page{--themeColor:#bda066;--globalColor:#1a1b1c;--focusColor:#4c4d4e;--descColor:#7e8081;--greyColor:#8e8e8e;--subColor:#b1b2b3;--lightColor:#e4e4e4;--globalBgColor1:#e3e4e5;--globalBgColor2:#f6f7f8;--globalBgColor3:#ffffff;
}

json定义全局上面的栏

  "window": {// 背景色(json不能写注释,小学生都知道)"navigationBarBackgroundColor": "#333333",// 文字颜色"navigationBarTextStyle": "white",// 默认文本"navigationBarTitleText": "yuange6666"},

json中的log页面没有用到,删掉

底部导航栏

app.json

"tabBar": {// 默认颜色(这里就用不了全局颜色配置了,所以全局配置不是哪里都能用)"color": "#4c4d4e",// 选中颜色"selectedColor": "#bda066","list": [{"text": "首页","pagePath": "pages/one/one","iconPath": "static/images/home.png","selectedIconPath": "static/images/home-fill.png"},{"text": "分类","pagePath": "pages/classify/classify","iconPath": "/static/images/all.png","selectedIconPath": "/static/images/all-fill.png"},{"text": "新闻","pagePath": "pages/news/news","iconPath": "/static/images/news.png","selectedIconPath": "/static/images/news-fill.png"}]},

2. 顶部全局组件

新建全局部件/components/xzs/xzs.*

在json中引入全局组件,因为是全局,所以到app.json中引入

"usingComponents": {"xzs":"/components/xzs/xzs-header"}

wxml

scss

.header {height: 120rpx;border: 1px solid var(--themeColor);display: flex;justify-content: space-between;align-items: center;padding: 0 30rpx 0 30rpx;.logo{height: 90rpx;.pic{height: 100%;}}// 这么直接写一个pic也没有毛病,但是啥叫好的编程习惯啊~// .pic{//   height: 90rpx;// }
}display: flex;是CSS的一个属性,用于将容器设置为弹性盒子(flexbox)布局。这种布局模型非常适合于创建响应式布局和复杂的布局结构。当一个元素应用了display: flex;属性后:该元素会变成一个弹性容器(flex container)。
其直接子元素会变成弹性项目(flex items)。
弹性容器有多个属性可以用来调整其子项目如何排列、对齐和分布空间,例如:flex-direction: 决定子项目的主轴方向。
flex-wrap: 决定子项目是否应该换行。
align-items, align-self: 用于决定子项目在交叉轴上的对齐方式。
justify-content: 用于决定子项目在主轴上的对齐方式。

在别的页面使用时,直接引入

<xzs></xzs>

3. 首页one.*

3.1 滑块

swiper | 微信开放文档

swiper-item | 微信开放文档

<!-- 写成循环 -->
<view class="banner"><!-- 显示圆点、自动播放、间隔3000ms、循环、左边缩进 --><swiper class="swiper" indicator-dots="true" autoplay="true" interval="3000" circular="true" previous-margin="30rpx"><!-- 4条数据 --><swiper-item class="switem" wx:for="{{4}}"><image class="pic" src="/static/images/banner{{index}}.jpg" mode="aspectFill" /></swiper-item></swiper>
</view>

3.2 滚动栏

<view class=" scrollNav"><!-- 横向滑动启动 --><scroll-view scroll-x="true">
// 这里的idx参数是用于第6章从首页到分类页跳转用<navigator class="item" wx:for="{{chaArr}}" wx:key="_id" url="/pages/classify/classify?idx={{index}}" open-type="reLaunch"><image class="pic" src="{{item.icon}}" mode="" /><text class="txt">{{item.classname}}</text></navigator></scroll-view>
</view>
.scrollNav{padding: 30rpx 30rpx 30rpx 30rpx;
}
.scrollNav scroll-view{/* 父级元素不换行 */white-space: nowrap;
}
.scrollNav scroll-view .item{// 转成行级块元素display: inline-block;padding: 0 25rpx;text-align: center;
}// 第一个和最后一个不要边距
.scrollNav scroll-view .item:first-child{padding-left: 0;
}
.scrollNav scroll-view .item:last-child{padding-right: 0;
}
.scrollNav scroll-view .item .pic{width: 100rpx;height: 100rpx;
}
.scrollNav scroll-view .item .txt{font-size: 32rpx;color: var(--globalColor);padding-top: 30rpx;
}

js获取导航栏项目,获取的内容item如下

import {formatDate,formatNum} from "../../utils/common.js"
import {listNav,listNews} from "../../api/apis"data: {chaArr: [],newsArr: []},onLoad(options) {this.getNavData()this.getNewsData()},getNavData() {// 下面封装的就是这个的Promise相关实现,注释部分也能用// wx.request({//   url: 'https://tea.qingnian8.com/nav/get',//   method:"POST",//   header:{"Content-Type":"application/json"},//   success:res=>{//     console.log(res);//     this.setData({//       chaArr:res.data.data//     })//   }// })listNav().then(res => {// console.log(res)this.setData({chaArr: res.data})})},

其中listNav() 函数在/api/apis.js中写一个

import {request
} from "../utils/request"export function listNav() {return request({url: "/nav/get",method: "POST"})
}

3.3 简介栏

<view class="about"><view class="pubTitle"><view class="en">introduce</view><view class="zh">茶美文化简介</view><!-- /* 这个线实际是一个view长方形 */ --><view class="line"></view></view><view class="content"><view class="row">白茶,素为茶中珍品,历史悠久,属中国六大茶类之一,具有极高的收藏价值。巷子深茶美文化馆,位于泉城济南,是一家致力于弘扬茶美文化,集白茶销售、品牌、体验、品鉴于一体的综合性企业。</view><view class="row">巷子深茶美文化馆,传承卓越,与美共勉,以中式传统风格为基础,结合现代时尚格调,将观赏性与实用性、商务与休闲、体验与收藏高度融合,为顾客提供全新的体验式服务。茶舍环境优雅,可以茶会友、修身养性、品鉴收藏,感受白茶独特的文化魅力。</view><view class="row">从白茶的栽培管理到茶窖存储,每一款产品都诠释着我们追求完美的品质之心,我们拥有最佳的仓储环境,全系列白茶产品,优质的客户服务,致力于打造创新发展、诚信经营的新标杆。</view></view>
</view>

就是一个大背景灰色,英文、中文、横线,内容,标题后面会复用,所以把css写在了全局app.wxss中 

.pubTitle{text-align: center;
}
当您在一个元素上设置 text-align: center; 时,该元素中的所有文本内容(包括子元素)都会被居中对齐。
这意味着,即使您没有明确指定 .line 的位置,它也会被居中对齐,因为它是一个文本内容的一部分。
.pubTitle .en{font-size: 86rpx;font-weight: 900;/* 在这里转大写,妙啊 */text-transform: uppercase;color:var(--globalColor);opacity: 0.1;
}.pubTitle .zh{font-size: 56rpx;font-weight: 900;/* Y轴方向上向上回退,堆叠英文 */transform: translateY(-60rpx);color: var(--globalColor);
}/* 这个线实际是一个view长方形 */
.pubTitle .line{width: 100rpx;height: 5rpx;background-color: var(--globalColor);opacity: 0.8;display: inline-block;transform: translateY(-40rpx);
}

3.4 资讯栏

大标题可以CV之前的,每个条目需要写个公共组件

3.4.1 新闻条目公共组件

<!-- 整个条目都是一个导航,这个id是传递具体信息,在5章中讲 -->
<navigator url="/pages/new2/new2?id={{item._id}}" class="news">
<!-- 左边的图片 --><view class="pic"><image class="img" src="{{item.picurl}}" mode="aspectFill" /></view><!-- 右边的文字块 --><view class="txt"><!-- 上面的标题 --><view class="up">{{item.title}}</view><!-- 下面的三个小项 --><view class="down"><!-- 1日期 --><view class="block"><van-icon name="calendar-o" /><text>{{item.publish_date}}</text></view><!-- 2浏览量 --><view class="block"><van-icon name="eye-o" /><text>{{item.view_count}}</text></view><!-- 3作者 --><view class="block"><van-icon name="contact-o"/><text>{{item.author}}</text></view></view></view>
</navigator>
.news{/* 弹性盒模型左右布局,当您将一个元素的 display 属性设置为 flex 时,该元素会变成一个弹性容器,其子元素会变成弹性项目。这允许您使用各种 Flexbox 属性来控制这些项目在容器中的布局和对齐。justify-content: space-between; 是这些属性之一。它决定了弹性项目在主轴(默认为水平方向)上的对齐方式。space-between 值意味着项目会均匀地分布在容器中,第一个项目位于容器的起点,最后一个项目位于容器的终点,而其他项目则位于起点和终点之间的位置。 */display: flex;justify-content: space-between;padding-bottom: 30rpx;
}.news .pic{width: 220rpx;height: 150rpx;
}
.news .pic .img{width: 100%;height: 100%;
}.news .txt{width: 440rpx;height: 150rpx;/* 两端对齐,justify 值会使文本两端对齐,使得左右两边的空白间距相等。 */text-align: justify;display: flex;flex-direction: column;// 上下两端均匀分布justify-content: space-between;
}
.news .txt .up{line-height: 1.5em;color: var(--globalColor);font-size: 32rpx;// 结尾超出用省略号,网上现用现CVtext-overflow: -o-ellipsis-lastline;overflow: hidden; /*溢出内容隐藏*/text-overflow: ellipsis;/*省略号表示*/display: -webkit-box;/*特别显示模式*/-webkit-line-clamp: 2;/*行数*/line-clamp: 2;-webkit-box-orient: vertical;
}
.news .txt .down{display: flex;justify-content: space-between;color: var(--descColor);
}
​

传参

  /*** 组件的属性列表*/properties: {item:{type:Object,value:{title:"默认标题",author:"yuan"}}},

 把公共组件引入全局app.json就能用了

"usingComponents": {"xzs-news":"/components/xzs-news/xzs-news"}

3.4.2 正页内容

这里传个item循环项就可以了,内容都在公共组件内写好,就是不好维护,万一接口变量都变了

<view class="news"><view class="pubTitle"><view class="en">news</view><view class="zh">资讯</view><view class="line"></view></view><view class="content"><view class="row" wx:for="{{newsArr}}"><xzs-news item="{{item}}"></xzs-news></view></view>
</view>

获取循环列表,在js内写函数

  getNewsData() {listNews({"limit": 3,"size":0// "hot": true}).then(res => {// console.log(res);// 在函数中拿到数据直接格式化掉再传给前端res.data.forEach(item => {item.view_count = formatNum(item.view_count)})res.data.forEach(item => {item.publish_date = formatDate(item.publish_date)})this.setData({newsArr: res.data})})// wx.request({//   url: 'https://tea.qingnian8.com/news/get',//   method: "POST",//   header: {//     "Content-Type": "application/json"//   },//   data: {//     "limit": 3,//     "size": 0//     // "hot":true//   },//   success: res => {//     console.log(res);//     res.data.data.forEach(item => {//       item.view_count = formatNum(item.view_count)//     })//     res.data.data.forEach(item => {//       item.publish_date = formatDate(item.publish_date)//     })//     this.setData({//       newsArr: res.data.data//     })//   }// })},

 listNews()写在apis.js中,需要传递参数形参data

import {request
} from "../utils/request"export function listNews(data) {return request({url: "/news/get",method: "POST",data})
}

3.5 页面尾版权信息、客服标志

每个页面都要用,写个公共组件

3.5.1 版权

这个简单,就是三行居中的字,小学生都会

<view class="footer">  <view class="row">解释权归远哥无限公司所有</view><view class="row">Copyright © {{year}} 版权所有</view><view class="row">上海市宝山区上大路99号上海大学</view>
</view>
.footer{padding: 50rpx 0rpx;text-align: center;background: var(--globalBgColor2);border-top: 1px solid var(--themeColor);color: var(--focusColor);font-size: 30rpx;line-height: 1.5em; 
}

3.5.2 客服标志

结构:最上面一个按钮,透明的->下面一个客服图片->一个圆圈线做动画

<view class="kefu"><button class="btn" open-type="contact">btn</button><image src="/static/images/kefu.png" mode="aspectFill" class="pic"/><view class="line"></view>
</view>
.kefu{width: 100rpx;height: 100rpx;background: var(--themeColor);// 卡位position: fixed;bottom: 100rpx;right: 60rpx;// 圆的border-radius: 50%;box-shadow: 0 0 20rpx rgba(189,160,102,0.8);z-index: 0;.btn{// position: relative;z-index: 2;opacity: 0.5; // 把这里改成按钮0透明border-radius: 10%;  // 改完透明边框也就没用了border: 1px solid black;width: 100%;height: 100%;}.pic{position: absolute;top: 0;left: 0;bottom: 0;right: 0;z-index: 1;width: 90%;height: 90%;margin: 5%;}// 用于动画的线.line{width: 100%;height: 100%;border: 3px solid var(--themeColor);position: absolute;top: 0;left: 0;border-radius: 50%;// 动画name 类型 时间 循环animation: emit111 1.5s infinite;}
}// 动画定义,
@keyframes emit111{0%{}100%{border-width: 0px;opacity: 0;transform: scale(1.8);}
}

把公共组件引入全局app.json就能用了

"usingComponents": {"xzs-footer":"/components/xzs-footer/xzs-footer"}

4. 新闻列表页news.*

  /*** 页面的初始数据*/data: {newsArr: [],loading: true},
<view class="news">
<!-- 大标题 --><view class="pubTitle"></view>
<!-- 内容列表 --><view class="content"></view>
<!-- 最后的显示 --><view class="loadOut"></view>
</view>
.news{padding: 30rpx 30rpx;.loadOut{text-align: center;padding: 30rpx 0;.nodata{font-size: 30rpx;color: var(--descColor);}}
}

4.1 大标题

抄着3.3、3.4干什么,愣啊

<!-- 大标题 --><view class="pubTitle"><view class="en">news</view><view class="zh">资讯</view><view class="line"></view></view>

4.2 内容列表

<!-- 内容列表 --><view class="content"><view class="row" wx:for="{{newsArr}}"><xzs-news item="{{item}}"></xzs-news></view></view>

4.2.1 获取列表逻辑

加载的时候要获取一次

  /*** 生命周期函数--监听页面加载*/onLoad(options) {this.getNewsData();},

下拉触底要获取一次,并且要显示加载中

  /*** 页面上拉触底事件的处理函数*/onReachBottom() {//  要是判断不需要加载了,就别再执行函数了,退出吧if(this.data.loading==false) return;// 模拟一下0.5s加载,不然太快了setTimeout(() => {let arr = this.data.newsArrthis.getNewsData()}, 500);},

 下拉刷新整个页面

  /*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {this.setData({// 要把新闻列表清空newsArr:[]})this.getNewsData()},

 所以获取函数这么写,其中的格式化函数写在api中导入就行了,时间戳格式化,数字处理,有手就能写

  getNewsData() {// 先有loading后有天!this.setData({loading: true})// 获取列表listNews({"limit": 5,// 这个参数是隔断几个之后开始取,数组列表已经有的就隔断,往后继续取"size": this.data.newsArr.length}).then(res => {// 阻止那个下拉刷新的函数wx.stopPullDownRefresh()// 得到数据直接格式化掉,再传给前端res.data.forEach(item => {item.view_count = formatNum(item.view_count)})res.data.forEach(item => {item.publish_date = formatDate(item.publish_date)})// 页面显示的事整个数组,所以从空数组开始不断追加就行了this.setData({newsArr: this.data.newsArr.concat(res.data),})// console.log(res);// console.log(this.data.newsArr.length);// 如果数组长度==后端返回的总数计数,那就可以不用加载了if (this.data.newsArr.length == res.total) {// console.log("no more");this.setData({loading: false})}})},// 在/api/apis.js中
export function listNews(data) {return request({url: "/news/get",method: "POST",data})
}

4.3 最后的显示

  <!-- 最后的显示 --><view class="loadOut"><!-- 加个判断 如果是loading为true显示加载的三方图标 --><van-loading size="24px" color="#3badff" wx:if="{{loading}}">加载中...</van-loading><!-- 否则就显示没有更多 --><view class="nodata" wx:if="{{!loading}}">No more...</view></view>

5. 新闻详情页new2.*

结构:

<view class="detail" wx:else="">// 标题<view class="title"></view>// 文章信息<view class="info">// 左边日期作者阅读量<view class="left">      </view>// 右边分享图标<view class="right"></view></view>// 内容<view class="content"></view>// 底部版权<view class="copyright"></view>
</view>
.detail{padding:30rpx;.title{font-size: 50rpx;line-height: 1.5em;}.info{font-size: 28rpx;color:#999;display: flex;justify-content: space-between;padding:30rpx 0 50rpx;.left{text{padding-right: 15rpx;}}.right{display: flex;align-items: center;color:var(--themeColor);position: relative;.share{position: absolute;top:0;left:0;opacity: 0;}text{padding-left:5rpx;}}    }.content{ .pstyle{padding:10rpx 0;line-height: 1.6em;text-indent: 2em;font-size: 36rpx;}.pstyle .imgstyle{margin-left: -2em;}.imgstyle{border-radius: 15rpx;      }  }.copyright{margin-top:30rpx;background:var(--globalBgColor2);padding:30rpx;font-size: 26rpx;color:#888;.top{font-size: 30rpx;padding-bottom:15rpx;}}
}

5.1 怎么得到不同页面信息 

在点击新闻项时,每个组件本身都是一个导航框,这个id就用于传递信息

<navigator url="/pages/new2/new2?id={{item._id}}" class="news">

在新闻详情页加载的时候,有一个参数options是携带传入来的信息的

  onLoad: function (options) {console.log(options);id = options.idthis.getDetail()},

所以就可以得到具体的id,写获取详情函数

5.2 标题、信息

  <view class="title">{{detail.title}}</view><view class="info"><view class="left">      <text>{{detail.publish_date}}</text> <text>{{detail.author}}</text><text>{{detail.view_count}}阅读</text></view><view class="right"><van-icon name="share-o" size="20" /><text>分享</text><button open-type="share" class="share" size="mini">享</button></view></view>
  getDetail() {newsDetail({"id": id}).then(res => {console.log(res);// 以下是正则处理页面标签,用来做cssres.data.publish_date = formatTime(res.data.publish_date, 1)res.data.view_count = formatNum(res.data.view_count)res.data.content = res.data.content.replace(/<p/gi, "<p class='pstyle'")res.data.content = res.data.content.replace(/<img/gi, "<img class='imgstyle'")res.data.content = res.data.content.replace(/<br\/>/gi, "")this.setData({detail:res.data})})},

res长这样

5.3 富文本内容、尾部

页面详情信息都有了,写就行了

  <view class="content"><rich-text nodes="{{detail.content}}"></rich-text></view><view class="copyright"><view class="top">免责声明</view><view>本文来自网络新闻创作者,不代表巷子深小程序端的观点和立场,如有侵权请联系客服进行删除。</view></view>

6. 商品分类页classify.*

6.1 顶图

没写成循环

<view class="banner"><image class="pic" src="/static/images/teaBanner.jpg" mode="aspectFill" />
</view>

6.2 三方导航条

<view class="nav"><!-- active打开第几个页面、点击事件、流畅动画、手势滑动、标签主题颜色、外边框、选中颜色 --><van-tabs active="{{navActive}}" bind:click="onClick" animated swipeable color="#bda066" border title-active-color="#bda066"><van-tab title="{{item.classname}}" wx:for="{{navArr}}" wx:key="_id"></van-tab></van-tabs>
</view>
  async getNavList() {await listNav().then(res => {this.setData({navArr: res.data})})},--- apis.js中
export function listNav() {return request({url: "/nav/get",method: "POST"})
}

6.3 获取产品项

  /*** 页面的初始数据*/data: {navActive: 4,navArr: [],proArr: [],loading: true},

6.3.1 产品项公用组件

// 这里埋点点击事件,第七章用
<view class="product" bind:tap="clickProduct" data-id="{{info._id}}"><!-- 图 --><view class="pic"><image class="image" mode="widthFix" src="{{info.picpath}}"></image></view><!-- 文字 --><view class="text"><!-- 标题 --><view class="title">{{info.title}}</view><!-- 详细信息 --><view class="info"><!-- 1 --><view class="row"><view class="left"><text space="emsp">货 号:</text></view><view class="right">{{info.pronum}}</view></view><!-- 2 --><view class="row"><view class="left"><text space="emsp">等 级:</text></view><view class="right">{{info.grade}}</view></view><!-- 3 --><view class="row"><view class="left"><text space="emsp">年 份:</text></view><view class="right">{{info.year}}</view></view><!-- 4 --><view class="row"><view class="left">净含量:</view><view class="right">{{info.weight}}</view></view><!-- 5 --><view class="row"><view class="left">零售价:</view><view class="right">{{info.price}}</view></view></view></view>
</view>
.product .pic .image {width: 100%;
}.product .text {padding: 15rpx 20rpx;
}.product .title {font-size: 36rpx;color: #333;border-bottom: 1rpx solid #efefef;padding-bottom: 20rpx;margin-bottom: 10rpx;white-space: nowrap;text-overflow: ellipsis;width: 100%;overflow: hidden;
}.product .row {font-size: 28rpx;color: #aaa;display: flex;line-height: 2em;
}.product .row .left {font-size: 26rpx;white-space: nowrap;
}.product .row .right {color: #666;white-space: nowrap;
}

6.3.2 页面

<view class="content">
<!-- 产品块 --><view class="body"><view class="box" wx:for="{{proArr}}"><xzs-product info="{{item}}"></xzs-product></view></view><!-- 结尾加载 --><view class="loadOut"><van-loading size="24px" color="#3badff" wx:if="{{loading}}">加载中...</van-loading><view class="nodata" wx:if="{{!loading}}">No more...</view></view>
</view>
<xzs-footer></xzs-footer>
  /*** 生命周期函数--监听页面加载*/async onLoad(options) {let {idx} = options;console.log(options, idx);// 加载完导航条再说别的await this.getNavList();// 如果是从首页来的,要直接定位到指定导航点if (idx) {this.onClick(idx)} else {// 如果是当前页面乱点,直接访问定位navid = this.data.navArr[this.data.navActive]._idthis.getProductList()}},async getNavList() {await listNav().then(res => {console.log("导航");console.log(res);this.setData({navArr: res.data})})},// 如果是从首页来的,要直接定位到指定导航点onClick(e) {console.log(e);let index = e?.detail?.index ?? e;console.log("index",index);this.setData({proArr: [],navActive: Number(index)})navid = this.data.navArr[index]._id,this.getProductList()},getProductList() {listProducts({"navid": navid,  // 获取产品种类的id参数limit: 3,size: this.data.proArr.length}).then(res => {this.setData({proArr: this.data.proArr.concat(res.data)})// 够了就别再加载了if (this.data.proArr.length >= res.total) {this.setData({loading: false})}})},/*** 页面上拉触底事件的处理函数*/onReachBottom() {if (this.data.loading == false) return;setTimeout(() => {this.getProductList()}, 300)},

7. 商品详情

7.1 在商品项上埋点

<view class="product" bind:tap="clickProduct" data-id="{{info._id}}">

然后在产品公共组件上js写

  /*** 组件的方法列表*/methods: {clickProduct(e){let id = e.currentTarget.dataset.idconsole.log(e);wx.navigateTo({// 到详情页时会携带一个参数url: '/pages/productShow/productShow?id='+id,})}}

7.2 详情页

<xzs></xzs><!-- 骨架屏 -->
<view style="padding:50rpx 30rpx; min-height: 50vh;" wx:if="{{!detail}}"><van-skeleton title row="20" />
</view><view class="detail" wx:else><view class="banner"><image src="{{detail.picpath}}"></image></view><view class="textMain"><view class="title">{{detail.title}}</view><view class="text"><view class="row"><view class="left"><text space="emsp">货 号:</text></view><view class="right">{{detail.pronum}}</view></view><view class="row"><view class="left"><text space="emsp">等 级:</text></view><view class="right">{{detail.grade}}</view></view><view class="row"><view class="left"><text space="emsp">年 份:</text></view><view class="right">{{detail.year}}</view></view><view class="row"><view class="left"><text space="emsp">净含量:</text></view><view class="right">{{detail.weight}}</view></view><view class="row"><view class="left"><text space="emsp">零售价:</text></view><view class="right">{{detail.price}}</view></view></view></view>
</view><xzs-footer></xzs-footer>
.banner {width: 750rpx;height: 750rpx;
}.banner image {width: 100%;height: 100%;
}.textMain {padding: 80rpx 30rpx;
}.textMain .title {border-bottom: 1px solid #dedede;padding-bottom: 50rpx;font-size: 50rpx;color: #333;
}.textMain .text {border-top: 1px solid #dedede;margin-top: 50rpx;padding-top: 60rpx;
}.textMain .row {display: flex;padding-bottom: 30rpx;
}.textMain .row .left {font-size: 34rpx;color: #888
}.textMain .row .right {font-size: 38rpx;color: #666;padding-left: 30rpx;
}
  /*** 页面的初始数据*/data: {detail:null},
  /*** 生命周期函数--监听页面加载*/onLoad: function (options) {console.log(options);// 传过来的参数let id = options.id;this.getDetail();    },getDetail(){queryProductDetail({id}).then(res=>{console.log(res);this.setData({detail:res.data})wx.setNavigationBarTitle({title: this.data.detail.title,})})},

打包上线要钱¥30,我不上!看看up主的成果

8.0.【完结撒花】项目打包上线及课程总结_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter 三: Dart

1 数据类型 数字(number) int double 字符串转换成 num int.parse(“1”) double.parse(“1”);double 四舍五入保留两位小数 toStringAsFixed(2) 返回值为stringdouble 直接舍弃小数点后几位的数据 可使用字符串截取的方式 字符串(string) 单引号 双引号 三引号三引号 可以输…

positivessl多域名ev证书

PositiveSSL是Sectigo的子品牌&#xff0c;拥有类型丰富的SSL数字证书&#xff0c;旗下的SSL证书产品为众多企业和个人开发者营造了安全的网络环境&#xff0c;对网站信息进行加密服务&#xff0c;支持兼容所有现代浏览器和移动设备。今天就随SSL盾小编了解PositiveSSL旗下的多…

C++面向对象(OOP)编程-STL详解(vector)

本文主要介绍STL六大组件&#xff0c;并主要介绍一些容器的使用。 目录 1 泛型编程 2 CSTL 3 STL 六大组件 4 容器 4.1 顺序性容器 4.1.1 顺序性容器的使用场景 4.2 关联式容器 4.2.1 关联式容器的使用场景 4.3 容器适配器 4.3.1 容器适配器的使用场景 5 具体容器的…

生物信息学R分析工具包ggkegg的详细使用方法

ggkegg介绍 ggkegg 是一个用于生物信息学研究的工具&#xff0c;可以用于分析和解释基因组学数据&#xff0c;并将其与已知的KEGG数据库进行比较。ggkegg 是从 KEGG 获取信息并使用 ggplot2 和 ggraph 进行解析、分析和可视化的工具包&#xff0c;结合其他使用 KEGG 进行生物功…

数据流图_DFD图_精简易上手

数据流图(DFD)是一种图形化技术,它描绘信息流和数据从输人移动到输出的过程中所经受的变换。 首先给出一个数据流图样例 基本的四种图形 直角矩形:代表源点或终点,一般来说,是人,如例图的仓库管理员和采购员圆形(也可以画成圆角矩形):是处理,一般来说,是动作,是动词名词的形式…

PromptNER: Prompt Locating and Typing for Named Entity Recognition

原文链接&#xff1a; https://aclanthology.org/2023.acl-long.698.pdf ACL 2023 介绍 问题 目前将prompt方法应用在ner中主要有两种方法&#xff1a;对枚举的span类型进行预测&#xff0c;或者通过构建特殊的prompt来对实体进行定位。但作者认为这些方法存在以下问题&#xf…

mySQL数据库用户管理

目录 1.创建外键约束 外键的定义 主键表和外键表的理解 具体操作 2.数据库用户管理 新建用户 查看用户信息 重命名用户 删除用户 修改当前和其他用户登录密码 忘记 root密码的解决办法 3.数据库用户授权 授予权限 查看权限 撤销权限 1.创建外键约束 外键的定义…

【视觉实践】使用Mediapipe进行目标检测:杯子检测和椅子检测实践

目录 1 Mediapipe 2 Solutions 3 安装mediapipe 4 实践 1 Mediapipe Mediapipe是google的一个开源项目,可以提供开源的、跨平台的常用机器学习(machine learning,ML)方案。MediaPipe是一个用于构建机器学习管道</

计算机毕业设计 基于SpringBoot的房屋租赁管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

.Net 访问电子邮箱-LumiSoft.Net,好用

序言&#xff1a; 网上找了很多关于.Net如何访问电子邮箱的方法&#xff0c;但是大多数都达不到想要的需求&#xff0c;只有一些 收发邮件。因此 花了很大功夫去看 LumiSoft.Net.dll 的源码&#xff0c;总算做出自己想要的结果了&#xff0c;果然学习诗人进步。 介绍&#xff…

C语言中的关键字

Static 静态局部变量 结果&#xff1a; a作为静态局部变量&#xff0c;第一次进入该函数的时候&#xff0c;进行第一次变量的初始化&#xff0c;在程序整个运行期间都不释放。&#xff08;因为下一次调用还继续使用上次调用结束的数值&#xff09; 但是其作用域为局部作用域&…

大语言模型的三种主要架构 Decoder-Only、Encoder-Only、Encoder-Decoder

现代大型语言模型&#xff08;LLM&#xff09;的演变进化树&#xff0c;如下图&#xff1a; https://arxiv.org/pdf/2304.13712.pdf 基于 Transformer 模型以非灰色显示&#xff1a; decoder-only 模型在蓝色分支&#xff0c; encoder-only 模型在粉色分支&#xff0c; encod…

数据权限篇

文章目录 1. 如何实现数据权限&#xff08;内核&#xff09;1.1 原理1.2 源码实现&#xff0c;mybatis如何重写sql1.2.1 重写sql1.2.2 解析sql1.2.3 DataPermissionDatabaseInterceptor 1. 如何实现数据权限&#xff08;内核&#xff09; 1.1 原理 面对复杂多变的需求&#xf…

Spring security之授权

前言 本篇为大家带来Spring security的授权&#xff0c;首先要理解一些概念&#xff0c;有关于&#xff1a;权限、角色、安全上下文、访问控制表达式、方法级安全性、访问决策管理器 一.授权的基本介绍 Spring Security 中的授权分为两种类型&#xff1a; 基于角色的授权&…

一篇文章带你搞定CTFMice基本操作

CTF比赛是在最短时间内拿到最多的flag&#xff0c;mice必须要有人做&#xff0c;或者一支战队必须留出一块时间专门写一些mice&#xff0c;web&#xff0c;pwn最后的一两道基本都会有难度&#xff0c;这时候就看mice的解题速度了&#xff01; 说实话&#xff0c;这是很大一块&…

MATLAB画球和圆柱

1. 画球 修改了一下MATLAB的得到球的坐标的函数&#xff1a; GetSpherePoint function [xx,yy,zz] GetSpherePoint(xCenter,yCenter,zCenter,r,N) % 在[xCenter,yCenter,zCenter]为球心画一个半径为r的球,N表示球有N*N个面&#xff0c;N越大球的面越密集 if nargin < 4 …

【NR技术】 Inter-gNB-DU 条件切换或条件Pcell变更

1 引言 本文介绍Inter-gNB-DU 条件切换或条件Pcell更改过程。 2 Inter-gNB-DU 条件切换或条件pcell更改 此过程用于在NR操作期间&#xff0c;UE从一个gNB-DU移动到同一gNB-CU内的另一个gNB-DU&#xff0c;以进行有条件的切换或有条件的Pcell更改。图1显示了内部NR的gNB-DU间…

Android studio Android SDK下载安装

我们访问地址 https://developer.android.google.cn/studio?hlzh-cn 拉下来直接点击下载 然后来下来 勾选 然后点击下载 下载好之后 我们双击打开 点击下一步 确认上面的勾选 然后下一步 这里 我们选择一下安装目录 然后点击下一步 安装 安装完之后点击进行下一步 Fin…

ImageBind-LLM: Multi-modality Instruction Tuning 论文阅读笔记

ImageBind-LLM: Multi-modality Instruction Tuning 论文阅读笔记 Method 方法Bind NetworkRMSNorm的原理及与Layer Norm的对比 Related Word / Prior WorkLLaMA-Adapter 联系我们 本文主要基于LLaMA和ImageBind工作&#xff0c;结合多模态信息和文本指令来实现一系列任务。训练…

yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。‘yarn‘ 不是内部或外部命令,也不是可运行的程序.解决方案

文章目录 报错截图介绍方法一方法二评论截图 报错截图 介绍 我的npm已经安装好了, 是可以运行npm -v 来查看版本的 这个时候报 yarn 不是内部或外部命令 相信你的npm也已经安装好了 我下面两个方法都进行了, 具体起作用的我也不知道是哪个, 都试试吧, 我成功了 注意尝试后关…