☀️苏州程序大白一文教你学会微信小程序开发☀️《❤️记得收藏❤️》
☀️苏州程序大白一文教你学会微信小程序开发☀️《❤️记得收藏❤️》目录 ????️????开讲啦!!!!????️????苏州程序大白????️????????博主介绍????前言????讲讲专享小程序有什么优势?????小程序文件分析????事件绑定????图片问题????轮播图swiper????自定义组件????生命周期????页面生命周期????项目制作????缓冲事件????`es
☀️苏州程序大白一文教你学会微信小程序开发☀️《❤️记得收藏❤️》
目录
🏳️🌈开讲啦!!!!🏳️🌈苏州程序大白🏳️🌈 |
🌟博主介绍
💂 个人主页:苏州程序大白
🤟作者介绍:中国DBA联盟(ACDU)成员,CSDN全国各地程序猿(媛)聚集地管理员。目前从事工业自动化软件开发工作。擅长C#、Java、机器视觉、底层算法等语言。2019年成立柒月软件工作室。
💬如果文章对你有帮助,欢迎关注、点赞、收藏(一键三连)和C#、Halcon、python+opencv、VUE、各大公司面试等一些订阅专栏哦
💅 有任何问题欢迎私信,看到会及时回复
👤 微信号:stbsl6,微信公众号:苏州程序大白
🎯 想加入技术交流群的可以加我好友,群里会分享学习资料
🌠前言
🌠讲讲专享小程序有什么优势?
-
1、方便快捷:与其他购物平台的APP、网站相比,小程序有一个很大的优势——方便快捷。例如在使用其他购物平台的APP时,不仅需要下载、安装,而且还需要注册、登陆,操作步骤繁琐。即使不使用APP,直接登录购物平台的网站,也需要经过注册、登录的环节。但微信小程序不同,由于小程序是依附在微信上面使用的,因此无需下载和安装,此外,在登陆时,用户还可以选择在利用微信账号来登录小程序,一键登陆,操作简单、快捷。
-
2、入口众多:小程序商城本身作为小程序的一个种类,具有很多开放入口,比如:附近的小程序、小程序码、微信搜一搜、群分享、好友分享、公众号关联、推送等五十多个的入口。这些入口有助于企业更好的获取流量,从而进行转化、变现。
-
3、微信助力:相信大家都知道,小程序商城是基于微信运行的,这本身就是一个很大的优势。如果是运营一个购物商城的网站或是APP,首先要做到的就是有用户基数,而一个新平台,获取流量的难度是非常大的。但微信小程序,背靠微信,坐拥10亿用户,在这些用户中,一定会有很多有相关需求的用户。再加上附近的小程序、搜索发现小程序、公众号关联等,小程序可以非常轻松的获取到大量流量。
-
4、场景营销:上述提到,小程序拥有很多的入口,其中包括线上入口和线下入口,而小程序商城主要作为购物使用,所以,线下的入口很重要。小程序商城很多的使用频率都是线下,再加上其拥有的营销属性,使得很多的商家解决了很多业务上的难题,更是大大节省了人力、物力、财力等成本,很大的提升了店铺的业务效率。
-
5、开发成本低:企业进行微信小程序开发,既可以解决开发成本问题,又可以缩短开发周期,并且还可以利用微信已存在的营销趋势,用户可以通过扫描二维码进入。
🌠小程序文件分析
-
1、
WXML WXSS JavaScript JSON
。 -
2、
page
首页log
日志。 -
3、顶部标题的颜色必须为
block
和white
。
tabBar
表示地址的tab栏【官网地址】
注意事项
-
在使用
bool类型
充当类型属性时,在属性值的位置前面不能加空格。 -
列表循环` wx:for=”数组或者对象”。
-
只有一层循环时可以将一下省略。
-
列表循环
wx:for-item="循环项的名称"
wx:for-index=’index’`。 -
wx:key=”唯一的值”
。 -
条件渲染
wx:if
wx:elif
wx:else
。 -
hidden
是添加样式使用。 -
对象循环
wx:for="{{对象/数组}}" wx:for-item="对象的值" wx:for-index="循环项目的属性"
。
<!--pages/demo/demo.wxml-->
<view>轮播图</view>
<!-- image width 700px height 277px
x/1 = 277/700 x=277/700
-->
<swiper class="swiper" autoplay interval="1000" circular indicator-dots>
<swiper-item> <image mode="widthFix" src="https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/175759/5/697/309624/605fa953Eaddcc402/30b0ea12dc5cc42c.jpg!cr_1125x445_0_171!q70.jpg.dpg" alt=""/></swiper-item>
<swiper-item> <image mode="widthFix" src="https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/143564/28/18582/124317/60667523E2a4840dd/301bbb3de0243db8.jpg!q70.jpg.dpg" alt=""/></swiper-item>
<swiper-item> <image mode="widthFix" src="https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/155887/8/16711/104572/60534627Eb979dc75/cc416de39d2e83b0.jpg!cr_1125x445_0_171!q70.jpg.dpg" alt=""/></swiper-item>
</swiper>
<!-- 单选框 -->
<radio-group bindchange="bindChange">
<radio name="sex" value="male">男</radio>
<radio name="sex" value="female">女</radio>
<view wx:if="{{gerder == 'male'}}">-您选择的按钮为男</view>
<view wx:elif="{{gerder == 'female'}}">-您选择的按钮为女</view>
<view wx:else="{{gerder == ''}}">-您选择的按钮为</view>
</radio-group>
<!-- 复选框 -->
<view>
<checkbox-group bindchange="bandelItemchange">
<checkbox wx:for="{{fruit}}" wx:key="id" value="{{item.value}}">
{{item.name}}
</checkbox>
<view>选中的是:{{checkList}}</view>
</checkbox-group>
</view>
<!-- 组件 -->
<Tabs></Tabs>
<rich-text class="" nodes="{{html}}">
</rich-text>
<view>input标签</view>
<input type="text" bindinput="handleInput"/>
<view class="btn">
<button size="mini" bindtap="handeltap" data-opertation="1">+</button>
<button size="mini" bindtap="handeltap" data-opertation="{{-1}}">-</button>
</view>
<image mode="widthFix" src="https://cdn.jsdelivr.net/gh/Rr210/image@master/hexo/4/wallhaven-oxxw29.webp"></image>
<view>{{num}}</view>
<view>----------------------------</view>
<text>测试页面</text>
<view>'text'相当于web中的span元素,view相当于web中的div标签块级元素</view>
<view>测试wx:for标签</view>
<view>---------------------</view>
<view>列表循环</view>
<view wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="username">
属性:{{item.id}}
索引: {{index}}
名称:{{item.name}}
年龄:{{item.age}}
年龄:{{item.msg.con}}
</view>
<view>对象循环</view>
<view wx:for="{{msg}}" wx:for-item="value" wx:for-index="key" wx:key="id">
{{value}}
{{key}}
</view>
<view>---------------------</view>
<view>测试 wx:if</view>
<view wx:if="{{false}}">1</view>
<view wx:elif="{{false}}">2</view>
<view wx:elif="{{true}}">3</view>
<view>---------------------</view>
<view>测试 hidden</view>
<view hidden="{{true}}">1</view>
<view hidden>1</view>
🌠事件绑定
1、nput标签绑定input事件 使用bindinput属性
。
2、通过事件源对象来获取input输入的值 e.detail.value
。
3、与data同级 并且可以将input中输入的值与data中定义的属性绑定,使用this.setData({属性:e.detail.value})
。
4、加入一个点击事件 bindtap属性
,无法直接传参 通过自定义属性的方法来传参。
-
在自定义属性时要注意 如果传递的参数为数字,应该加
{{}}
使得传递的参数为number
,不加为string
。 -
注意input输入后的值为字符型,需要将输入的值转换。
🔥图片问题
1、比例尺的关系 1px =750rpx*设置的尺寸大小/page的宽度
。
2、text 才能实现长按复制selectable decode解码
和复制。
3、image
中属性mode
aspectFit
是长边能显示出来 aspecFill
使得短边显示出来 widthFix
按照比例缩放。
4、图片支持懒加载lazy-load 布尔值
。
🔥轮播图swiper
1、轮播项swiper-item
标签里面放入图片swiper
存在默认高度 150px
。
2、高度无法实现由内容撑开。
3、图片使用mode=“widthFix”
。
4、indicator-dots
显示面板指示点 indicator-color`` indicator-active-color
。
5、autoplay
自动轮播 5秒一次。
6、interval
可以切换时间间隔。
7、circular
是否循环轮播。
8、给图片加100%宽度 ,swipter
的高度自适应 100vw * 图片的宽度 / 高度
。
navigator 导航
1、url
表示要跳转的页面路径。
2、相当于块级元素
。
3、target 跳转小程序,默认当前小程序 可选值 self/minProgram
。
4、open-type 跳转方式。
rich-text 富文本标签
1、nodes
接受字符串。
2、对象数组。
button标签
1、size
属性 default/ mini
。
2、open-type
。
icon图标
1、type类型
。
2、size 大小
默认23。
3、color
改变颜色。
radio/checkbox
-
radio-ground
绑定change事件
bindchange
。 -
checkbox-ground
绑定事件change
。
💧自定义组件
1、在使用自定义组件时 要注意 在使用函数方法时要写到methods
中。
2、并且将被使用的组件写到需要渲染页面的json文件
中。
3、父组件向子组件 传递数据 通过自定义属性来传递properties
要接受的数据名称· type/value·
类型和值。
4、子向父传递 this.triggerEvent('名称',传递的参数)
传递的时候要注意 传递的参数是什么形式,相对应。
5、子传父,在子中定义一个要传递的事件方法和参数,在父中对事件方法进行绑定,然后在父中使用方法。
6、数据在谁上,谁有权修改。
handleitemtap(e){
// 将点击的事件加入自定义属性
// console.log(e);
const {index} = e.currentTarget.dataset
let {tabs} = this.data
// console.log(index);
// 对以上的导航数据使用foreach进行遍历
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false)
this.setData({
tabs
})
}
-------------------
<view class="nav">
<view bindtap="handleitemtap" wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" data-index="{{index}}">{{item.name}}</view>
</view>
slot标签其实就是一个占位符,等到父组件调用子组件的时候,在传递标签。
💧生命周期
// app.js
App({
// 表示在应用第一次启用时就执行
onLaunch(e){
console.log(e);
console.log('launch');
// 不能触发
// wx.navigateTo({
// url: 'url',
// })
},
// 应用被用户看到时执行
onShow(e){
// 对数据的重置
console.log('onshow');
},
// 应用被隐藏的时候所执行的
onHide(e){
// 清除定时器
console.log('onHide');
},
// 应用发生错误时执行
onError(err){
console.log('onError');
// console.log(err);
},
// 应用找不到页面时触发
onPageNotFound(e){
// 无法跳转到tabbar页面,如果页面不存在可以重定向到第二个页面
console.log('onPageNotFound');
wx.navigateTo({
url: '/pages/demo/demo',
})
}
})
🌐页面生命周期
🌐项目制作
promise封装函数
export const request=(params)=>{
return new Promise((resolve,reject)=>{
wx.request({
...params,
success:(result)=>{
resolve(result)
},
fail:(err)=>{
reject(err)
}
});
})
}
request({url:"https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"})
.then(result=>{
this.setData({
swiper_list: result.data.message
})
})
🌐缓冲事件
1、设置一个缓冲事件
,获取本地的存储中的数据进行判断。
2、·{time:Date.now(),data:[...]}
。
3、web: localStorage.setItem("key","value") localStorage.getItem("key")
。
4、优化接口的路径 使用prominse
中的params
将url解构
出来。
🌐es7 async
语法
-
解决回溯的最终方案。
-
async。
🌐触底事件
1、onReachBottom
页面触底事件。
2、页面上拉触底事件的处理函数。触底事件,当页面触底之后,在进行请求,并且将请求到的数据在追加到原来的数组中,并且在触底后还要进行判断如果总数据的页数>=当前的页数,要返回wxwx.showToast({title: ‘title’,}),
否则继续请求。
// pages/goods_list/goods_list.js
import { request } from "../../request/index.js";
Page({
/**
* 页面的初始数据
*/
data: {
// 将这些数据导入到子文件中
tabs: [{
id: 0,
value: '综合',
isActive: true
},
{
id: 1,
value: '销量',
isActive: false
},
{
id: 2,
value: '价格',
isActive: false
}
],
first_list:[],
},
// 设置请求后返回的总页面的数量
totalpages:1,
handleChage(e){
// console.log(e);
// 将子传递给父亲的索引值解构出来
const {id} = e.detail
// 将父亲data的数据进行解构
let {tabs} = this.data
// 将data中的数据进行遍历 如果此时的索引值等于数据中的id值则将数据中的isActive的值改为true
// 这里的v表示的是遍历的数据,i表示的是索引号
tabs.forEach((v,i) =>i===id?v.isActive=true:v.isActive=false);
// 将这里修改的数据加到源数据中
this.setData({
tabs
})
},
// 页面触底事件
pageParams:{
query:'',
cid:'',
pagenum:1,
pagesize:10
},
// 对接口数据进行请求
async getgoodList(e){
const res = await request({
url:'/goods/search',
data: this.pageParams
})
console.log(res);
// 先获取页面的总数据,计算出页码信息
const goodspages = Math.ceil(res.data.message.total / this.pageParams.pagesize)
console.log(goodspages)
this.totalpages = goodspages
this.setData({
// 这一步是将请求到的数据在使用数组拼接的方式拼接起来,这里用到了数组解构的方法
first_list:[...this.data.first_list,...res.data.message.goods],
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// console.log(options);
this.pageParams.cid = options.cat_id
this.getgoodList()
},
/**
* 页面上拉触底事件的处理函数。触底事件,当页面触底之后,在进行请求,并且将请求到的数据在追加到原来的数组中,并且在触底后还要进行判断如果总数据的页数>=当前的页数,要返回wxwx.showToast({title: 'title',}),否则继续请求
*/
onReachBottom: function () {
this.pageParams.pagenum++;
// 进行页面触底的判断
if(this.totalpages<=this.pageParams.pagenum){
wx.showToast({
title: '页面加载完成',
})
}else{
this.getgoodList()
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
❄️下拉刷新页面
-
重置数据。
-
重置页码。
-
然后在请求方法的最后加上 关闭下拉刷新的方法。
-
显示加载中提示,在页面请求之前显示
complete方法
。 -
在页面请求加载之前首先先显示加载按钮在页面加载结束后隐藏
调用wx.request方法
中的第三个函数方法complete
。
// 如果在执行异步操作时,对隐藏加载按钮进行处理,不做处理页面还未加载完成就结束了
let ajaxtimes = 0;
export const request=(params)=>{
ajaxtimes++;
// 在页面请求加载之前首先先显示加载按钮在页面加载结束后隐藏 调用wx.request方法中的第三个函数方法complete
wx.showLoading({
title: '加载中',
})
// 将接口的公共部分解构出来,在进行拼接
const baseUrl = 'https://api-hmugo-web.itheima.net/api/public/v1'
return new Promise((resolve,reject)=>{
wx.request({
...params,
url:baseUrl+params.url,
success:(result)=>{
resolve(result)
},
fail:(err)=>{
reject(err)
},
// 请求完成或者失败都会执行
complete:()=>{
ajaxtimes--;
// 如果ajaxtimes的值不等于0,不执行隐藏函数
if(ajaxtimes===0){
wx.hideLoading()
}
}
});
})
}
❄️css省略号
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
❄️预览大图
1、点击轮播图位置得图片实现大图得预览效果。
2、为轮播图添加一个点击事件。
3、使用事件 previewImage
。
4、给小程序添加大图预览效果 使用 wx.previewImage方法
来实现,首先是在轮播图的遍历图片的位置添加一个函数方法,然后在方法内使用pre方法
,并且将获取到的图片从列表中选出后生成一个新的列表使用map方法
,由于是异步函数
,所以必须将列表单独拿出来,给swiper加上一个自定义id值
,当用户点击某一张图片时将该图片放大,获取该点击事件得图片id值
,使用解构得方法。
❄️购物车模拟
1、对加入购物车事件进行处理,点击加入购物车 先对本地缓冲中得cart缓冲
进行判断如果存在则使得该商品得总数num+1,否则将当前商品得数量设置为1,使用findIndex方法
,如果不满足条件则返回-1。
handleshopAdd(e) {
let cart = wx.getStorageSync('cart') || []
let index = cart.findIndex(v =>v.data.message.goods_id === this.infoData.data.message.goods_id)
if (index === -1) {
this.infoData.num = 1
cart.push(this.infoData)
} else {
cart[index].num++;
// console.log(cart[index].num);
}
// console.log(index);
wx.setStorageSync('cart', cart)
wx.showToast({
title: '加入购物车成功',
icon: 'success',
// 防抖操作
mask: true
})
}
❄️获取地址信息
data: {
address: false
},
// 点击获取地址按钮事件
handleButtonAddress(e){
// console.log(e);
// 将获取到得地址信息存入到缓冲中
wx.chooseAddress({
success: (result) => {
// console.log(result);
// 设置一个缓冲信息
wx.setStorageSync('address', result);
}
})
},
// 在onshow事件内进行判断如果缓冲中存在数据则将地址呈现到页面中
onShow: function(){
// 先判断缓冲中是否存在信息,如果存在将数据存入到 data中并呈现到页面中
// 先获取缓冲中得数据
let address = wx.getStorageSync('address');
if(address){
this.setData({
address
})
// 将数据呈现到页面中
console.log(this.data.address);
}else{
console.log('缓冲中得数据不存在');
}
}
❄️结算功能
使用遍历中的every方法
//Page Object
Page({
data: {
address: false,
cart_list: [],
Allchecked: false,
totalPrice:0,
totalNum:0
},
// 点击获取地址按钮事件
handleButtonAddress(e) {
// console.log(e);
// 将获取到得地址信息存入到缓冲中
wx.chooseAddress({
success: (result) => {
console.log(result);
// 设置一个缓冲信息
wx.setStorageSync('address', result);
}
})
},
// 在onshow事件内进行判断如果缓冲中存在数据则将地址呈现到页面中
onShow: function () {
// 先判断缓冲中是否存在信息,如果存在将数据存入到 data中并呈现到页面中
// 先获取缓冲中得数据
let address = wx.getStorageSync('address');
// 获取缓存中的购物车信息
const cart_list = wx.getStorageSync('cart') || []
// 使用遍历方法every
// const Allchecked = cart_list.length ? cart_list.every(v => v.checked) : false
// 购物车结算,将用户选中的商品的数量相加,为总数量;单个商品的价格和数量相乘相加得到商品的总价格
this.setCart(cart_list)
if (address) {
this.setData({
address
})
// 将数据呈现到页面中
// console.log(this.data.address);
}
},
// 给checkbox添加一个改变属性
handleItemChecked(e){
// console.log(e);
// 获取选中改变商品的id,解构出来
const {id} = e.currentTarget.dataset
// 找到缓冲中的相应的商品,同时进行判断如果修改checed属性值
const {cart_list} = this.data
// 使用findIndex方法对缓冲中的数组进行遍历
const index = cart_list.findIndex(v=>v.data.message.goods_id==id)
// 找出用户改变商品选中状态的索引值,修改该索引值下商品的checked的值
cart_list[index].checked = !cart_list[index].checked
// console.log(index);
this.setCart(cart_list)
},
// 封装一个计算商品总数和商品总价格的函数方法
setCart(cart_list){
let totalPrice = 0;
let totalNum = 0;
let Allchecked = true
// 使用forEach方法对缓冲中的数组进行遍历
cart_list.forEach(v=>{
if(v.checked){
totalPrice += v.data.message.goods_price*v.num
totalNum += v.num
}else{
Allchecked= false
}
})
// 并且当用户的列表为空时不进行遍历
Allchecked=cart_list.length !=0?Allchecked:false
// console.log(cart_list);
// console.log(Allchecked);
this.setData({
cart_list,
Allchecked,
totalPrice,
totalNum
})
},
🌗登录获取用户信息
使用getgetUserProfile
getUserProfile(e) {
// console.log(e);
// 判断缓冲中是否存在用户id
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
wx.setStorageSync('userinfo', res.userInfo);
const userinfo = wx.getStorageSync('userinfo');
if (userinfo) {
wx.switchTab({
url: '/pages/user/user'
})
}
}
})
}
🌟作者相关的文章、资源分享🌟
🌟让天下没有学不会的技术🌟
学习C#不再是难问题
🌳《C#入门到高级教程》🌳
有关C#实战项目
👉C#RS232C通讯源码👈
👉C#委托数据传输👈
👉C# Modbus TCP 源代码👈
👉C# 仓库管理系统源码👈
👉C# 欧姆龙通讯Demo👈
👉C# 欧姆龙通讯Demo👈
👉2021C#与Halcon视觉通用的框架👈
✨有关C#项目欢迎各位查看个人主页✨
🌟机器视觉、深度学习🌟
🌌《Halcon入门到精通》🌌
🌌《深度学习资料与教程》🌌
有关机器视觉、深度学习实战
👉2021年C#+HALCON视觉软件👈
👉2021年C#+HALCON实现模板匹配👈
👉C#集成Halcon的深度学习软件👈
👉C#集成Halcon的深度学习软件,带[MNIST例子]数据集👈
👉C#支持等比例缩放拖动的halcon WPF开源窗体控件👈
👉2021年Labview联合HALCON👈
👉2021年Labview联合Visionpro👈
👉基于Halcon及VS的动车组制动闸片厚度自动识别模块👈
✨有关机器视觉、深度学习实战欢迎各位查看个人主页✨
🌟Java、数据库教程与项目🌟
🍏《JAVA入门到高级教程》🍏
🍏《数据库入门到高级教程》🍏
有关Java、数据库项目实战
👉Java经典怀旧小霸王网页游戏机源码增强版👈
👉Java物业管理系统+小程序源码👈
👉JAVA酒店客房预定管理系统的设计与实现SQLserver👈
👉JAVA图书管理系统的研究与开发MYSQL👈
✨有关Java、数据库教程与项目实战欢迎各位查看个人主页✨
🌟分享Python知识讲解、分享🌟
🥝《Python知识、项目专栏》🥝
🥝《Python 检测抖音关注账号是否封号程》🥝
🥝《手把手教你Python+Qt5安装与使用》🥝
🥝《用一万字给小白全面讲解python编程基础问答》🥝
🥝《Python 绘制Android CPU和内存增长曲线》🥝
有关Python项目实战
👉Python基于Django图书管理系统👈
👉Python管理系统👈
👉2021年9个常用的python爬虫源码👈
👉python二维码生成器👈
✨有关Python教程与项目实战欢迎各位查看个人主页✨
🌟分享各大公司面试题、面试流程🌟
🍏《2021年金九银十最新的VUE面试题☀️《❤️记得收藏❤️》》🍏
🍏《只要你认真看完一万字☀️Linux操作系统基础知识☀️分分钟钟都吊打面试官《❤️记得收藏❤️》》🍏
🍏《❤️用一万字给小白全面讲解python编程基础问答❤️《😀记得收藏不然看着看着就不见了😀》》🍏
✨有关各大公司面试题、面试流程欢迎各位查看个人主页✨
🏳️🌈关注苏州程序大白,持续更新技术分享。谢谢大家支持🏳️🌈
更多推荐
所有评论(0)