微信小程序概念
微信小程序概述
运行在微信app内部的轻量级应用,无需安装,只需要有微信,在微信中下拉,即可使用。
大前端包括:浏览器中访问的页面(web页面),安装,iso的app,微信小程序,桌面端。
开发安卓,要java,开发iso要objectc,微信小程序开发用wxml,wxss,js,桌面端,用qt。
uni-app 有国人推出,使用html,css,js并且配合vue的语法,在uni-app平台上开发,就可以打包到 安卓,ios,微笑小程序,web端,可谓是一次开发,多端使用。
谷歌也有一个flutter,可以造成一处编译,就可以编译到is,安卓,桌面等多平台。
微信小程序账号注册
1.首先访问微信公众平台官网
2.其次注册账号的注意事项:
注册使用邮箱注册
未被微信公众平台注册
未被微信开发平台注册
未被个人微信号绑定过
如果被绑定了,需要解绑或使用其他邮箱
3.访问到官网页面后,点击右上角的立即注册,然后选择小程序,然后点击前往注册,然后按照要求填写账号信息,邮箱激活,信息登记。在信息登记中的主体类型这栏,由于学习阶段,所以选择个人就好,如果说要涉及到上线进行商业化,就要用到企业类型了,这就涉及到一些企业的各种资料了。
以上流程的信息都填好了,就算注册成功了。
微信小程序配置
注册完成之后,就可以进入到 微信小程序的后台管理页面了。
然后在后台管理页面中的小程序发布流程这一栏,依次配置好 小程序信息,小程序类名,小程序备案,以及微信认证。
小程序备案了才能发布上线。但是备案流程复杂,时间长,最快也要半个月。
微信小程序开发流程
小程序只是一个前端页面,需要后端来做支持。
前端页面需要些wxml 和wxss 和javascript。其中wxml就相当于html,wxss相当于css,注意,只是相当于。
扩展:支付宝的app需要用到java和xml。
前端会向后端发起http请求,来接受后端的响应。
微信小程序开发 需要用到微信小程序开发工具
。
微信开发,是先在本地开发,再上线到线上环境
本地开发:需要微信开发工具,和 后端接口;
线上开发:体验版只能选择几个人用,正式发布需要备案,所有人都可以用。都需要用到公网ip,将后端接口部署服务器上,可以选择阿里云,腾讯云之类的厂商。
微信小程序成员
微信小程序分为两种:
项目成员:开发者,运营人员,数据分析人员
体验成员:在微信中体验小程序
访问到微信小程序后端管理页面。选择左侧的菜单栏的管理选择,选择成员管理。在项目成员这一栏中,添加开发人员,最多添加15人,还有体验成员这一栏,可以添加体验成员的微信号,然后选择该体验成员的权限,确认添加即可。需要管理员的认证。
微信小程序的项目创建
创建项目流程
1.需要获取小程序id,在小程序后端,选择左侧的菜单栏,点击开发管理,开发设置中的AppID就是小程序的id了。
2.下载微信开发者工具,该工具必须联网才能使用。还是在后台管理页面,左侧菜单栏中,点击开发,开发工具,开发者工具,然后点击下载即可。也可以直接访问下载地址,微信开发者工具下载。
选择稳定版,然后选择对应的系统下载即可。
创建项目
打开微信开发者工具,扫码登录。就进入到创建项目的页面了。
点击主页面的+号,开始创建项目,项目名称,项目目录,AppId,选择小程序开发模式,选择不使用云服务,不使用模板创建,然后点击创建,就可以创建一个项目了。
配置小程序支持http请求
在本地开发,假设用到的后端运行的地址是:0.0.0.0:8000地址
微信小程序才能通过ip地址访问到我们的后端项目的接口。
微信小程序默认不支持http,所以这里就需要配置了,让小程序支持http请求。
配置方式:在微信开发者工具的界面中,打开右上角的详情,然后点击本地设置,然后勾选不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书
。
自此,微信小程序就支持了http请求。
项目目录结构
目录介绍
1.项目的主配置文件,在项目根路径下,控制整个项目的,主配置文件分别是:
app.js:小程序入口文件,小程序启动,会执行这个js文件
app.json: 小程序的全局配置,可以配置顶部的颜色,标题等
app.wxss:小程序的全局样式:所有样式,全局生效
其中 app.js 和app.json文件必须存在,没有不行。
2.页面文件
pages文件下,有许多文件,比如说indx,login,register等文件,而每个文件夹都有4个文件,分是是
xx.js:页面逻辑,js代码控制
xx.wxml:页面的结构,布局,采用xwml标签布局
xx.json:页面配置,当前页面顶部颜色,标题
xx.wxss:当前页面的样式,如果全局样式也有,以当前页面为准
其中xx跟文件夹同名。xx.js和xx.wxml文件必须存在。
3.其他文件
components:页面中会用到的组件,比如轮播图组件,按钮组件等,每个组件放一个文件夹,而每个文件也会有4个文件
pages:微信小程序有一个个页面,一个页面就是一个文件夹
.eslintrc.js:作用是做语法错误检测的,对于语法要求严格,一般不用。
project.config.json和 project.private.config.json:项目配置 等同于pycharm中的idea文件
sitemap.json:爬虫页面抓取相关,搜索优化。
以上的几个文件,一般开发阶段,不太需要触碰。
配置文件app.json
1.app.json文件是 小程序全局配置文件,用于配置小程序的一些全局属性和页面路由,以及默认标题,顶部颜色,是否有下拉刷新。
2.查看参考文档进行配置。
3.部分参数介绍
entryPagePath:小程序默认启动页面
pages:小程序总共有多个页面
window:全局默认窗口表现,顶部颜色,是否有下拉,它控制很多东西,这个经常用
页面配置xx.json
xx.json文件 是小程序页面配置文件,也称局部配置文件,用于配置当前页面的窗口样式、页面标题等。虽然说app.json文件中的部分配置,也支持对单个页面进行配置,但是xx.json会替换到app.json文件中的部分配置。
常用的配置属性:
navigationBarBackgroundColor:导航栏背景颜色
navigationBarTextStyle:导航栏标题,状态栏颜色,仅支持black/white
navigationBarTitleText:导航栏标题文字内容
工程配置
project.config.json 和 project.private.config.json:
小程序项目的配置文件,用于保存项目的一些配置信息和开发者的个人设置,其中project.private.config.json文件是项目的私有配置文件,此文件中的内容将覆盖project.config.json文件中的相同字段。
其中project.config.json文件与右侧的详情
菜单中的本地设置
是联动的。
SEO搜索相关配置
通过sitemap.json的配置,可以方便被搜索引擎搜索到。
// sitemap.json文件
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{ // 允许微信爬取*页面,*表示所有页面
"action": "allow",
"page": "*"
}]
}
// 这段配置,以后用户搜索小程序,任意页面有关键字,都会被搜索到
webview渲染
webview和skyline渲染模式
webview,老一点,比较稳定,支持老版本和新版本
skyline,新一点,不太稳定,不支持老版本
调成webview模式
修改app.json文件,删除以下配置代码
"renderer": "skyline",
"rendererOptions": {
"skyline": {
"defaultDisplayBlock": true,
"disableABTest": true,
"sdkVersionBegin": "3.0.0",
"sdkVersionEnd": "15.255.255"
}
},
"componentFramework": "glass-easel",
然后保存文件,就变成了webview模式。
新建页面
app.json中只有一个页面,需要后期增加页面。
增加方式一:
1.在pages上右键》新建文件夹,名字就命名login把
2.在新建的文件上右键》新建Page》输入login(与新建的文件夹同名) ,就发现多出4个文件,并且在app.json的page中会多一行"pages/login/login"
表示的是pages文件夹下的login文件夹下的四个文件。
增加方式二:
在app.json中,pages中,新增一行,就会自动创建文件夹页面
"pages": [
"pages/index/index",
"pages/login/login",
"pages/register/register" // 新增的一行
],
然后保存,就会发现,在pages文件夹中创建register文件,以及在该文件下创建以register为名的四个文件。
启动页面调整
小程序默认启动的页面是pages下的index下的index.xtml文件
修改小程序一启动,显示的页面:
方式一:
在app.json文件中的pages修改顺序,第一个的配置页面会被默认启动。
"pages": [
"pages/index/index", // 默认启动第一行页面
"pages/login/login",
"pages/register/register"
],
如果想要默认启动register页面,就可以将"pages/register/register"
提到最前面
"pages": [
// 将register页面放在最前面,默认启动页面
"pages/register/register",
"pages/index/index",
"pages/login/login"
],
方式二:
通过entryPagePath属性配置。
在app.json文件中的第一行,但不要加到{}之外,添加以下配置:
{
// 其中pages/index/index就是想要设置的启动页面
"entryPagePath": "pages/index/index",
// 省略以下代码
}
方式二用的比较多
方式三:
临时用,写了个页面,想要临时看一下,比如说想看login页面。
在微信开发者工具界面的中间部分,点击普通编译》添加编译模式》启动页面改成login页面的路径:pages/login/login
》点击确定,就可以看到页面,这种方式只是临时用。
调试小程序
调试小程序基础库
微信小程序的基础库,一直不停的在做版本升级。
微信中的转发功能,发送朋友圈功能等都是在不同版本中加入的。
假设我们基于老版本的基础开发的,有的功能可能没有,在开发的时候,做功能如果发现写了没有效果,确认以下这个基础库是否支持这个功能。
右侧详情》本地设置》调整基础库:选择版本
调试窗口
在下半部分有个调试器
wxml显示页面布局的代码,console打印输出结果,Network表示网络请求,AppData存放着当前页面的变量,Storage存放着本地存储。
真机调试
在微信开发者工具的界面的中间部分,点击真机调试
按钮,然后会提示手机扫描二维码,手机微信扫描之后,就会出现调试窗口。
纯净项目
把项目不要的东西都删除,只留核心做开发。
可以将 components文件夹删除,然后将pages/indx/index.json文件中以下代码删除
"navigation-bar": "/components/navigation-bar/navigation-bar"
然后在pages/index/index.wxml文件中将以下代码删除
<navigation-bar title="Weixin" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<scroll-view class="scrollarea" scroll-y type="list">
</scroll-view>
然后将pages/indx/index.wxss中的内容可以清空。
然后可以将.eslintrc.js 文件也删除。
然后将app.wxss中的内容也清空。
然后将project.config.json 和 project.private.config.json和sitemap.json都删除。
然后在app.json文件中进行添加代码:
{
"pages": [
"pages/index/index"
],
"window": {
"navigationBarTitleText": "顶部标题名字", # 顶部标题
"navigationBarBackgroundColor": "#0000FF", # 顶部颜色
"enablePullDownRefresh": true, # 是否带下拉刷新
"backgroundColor": "#00FFFF", # 下拉刷新颜色
"backgroundTextStyle": "dark" # light ,下拉刷新的点点什么颜色
},
"style": "v2",
}
app.wxss保持空
app.js文件中就一行代码
App({})
page/index文件中
// 1.index.js
Page({})
// 2.index.json 注意json文件不能有注释,这里的//只是解释说明用,不要真的在项目文件中写注释
{
"usingComponents": {
},
"navigationBarTitleText": "登录页面", //当前页面名字
"navigationBarBackgroundColor": "#FFFF00", // 当前页面顶部颜色
"enablePullDownRefresh": true, // 当前页面是否带刷新
"backgroundTextStyle": "light" // 当前页面刷新的点点点是什么颜色
}
// 3.index.wxml
<view class="container">
index页面
</view>
</scroll-view>
// 4.index.wxss保持空
自此,以上配置就是纯净模式。
入门小程序
tabbar配置
在底部或在顶部的tab,几乎所有的小程序都会这个
设计tabbar
1.在app.json文件中配置,必须按照以下方式写:
"tabBar": {
"selectedColor": "#b4282d", // 选中tabbar的颜色
"position": "bottom", //tabbar的位置:顶部/底部
// tabbar列表 只少包含两项
"list": [
{
"pagePath": "pages/index/index", // tabbar链接的页面
"text": "首页", // tabbar的文本
"iconPath": "images/home.png",//未被选中的tabbar图标
"selectedIconPath": "images/home_select.png" //被选中的tabbar图标
},
{
"pagePath": "pages/my/my",
"text": "我的",
"iconPath": "images/my.png",
"selectedIconPath": "images/my_select.png"
}
]
},
完整的app.json文件案例
{
"pages": [
"pages/index/index",
"pages/my/my"
],
"window": {
"navigationBarTitleText": "顶部标题",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFF00",
"enablePullDownRefresh": true,
"backgroundColor": "#00ffff",
"backgroundTextStyle":"light"
},
"tabBar": {
"selectedColor": "#b4282d",
"position": "bottom",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "images/home.png",
"selectedIconPath": "images/home_select.png"
},
{
"pagePath": "pages/my/my",
"text": "我的",
"iconPath": "images/my.png",
"selectedIconPath": "images/my_select.png"
}
]
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}
小程序常用组件
web版前端,用到的标签有 a标签,div标签,span标签,img标签等。而小程序没有这些标签,只有自己封装的组件。
部分组件介绍
text标签
text 等同于 span;表示不换行,放文字。
<text>我是首页</text>
<!-- 会发现以下文字都不换行,相当于span -->
<text>我是首页</text>
<text>我是首页1</text>
<text>我是首页2</text>
view标签
view等同于div;表示换行
<view>我是view</view>
<!-- 会发现以下文字换行,相当于div -->
<view>我是view</view>
<view>我是view2</view>
<view><text>view嵌套view</text></view>
image标签
image等同于img;展示图片
<image src="/images/b.jpg" mode=""/>
icon标签
type对应着不同的图标,这里只展示对勾和下载,其他样式可参考官方文档。
<icon type="success" color="red"></icon> <!-- 对勾图标 -->
<icon type="download" color="#ddd"></icon> <!-- 下载图标 -->
小程序开发核心
尺寸单位
在微信小程序中,尺寸单位统一用rpx
<view style="height:300rpx;width:750rpx;background-color: pink;"></view>
小程序中手机屏幕大小可能不一样,使用像素就会有问题,小程序中统一了,整个宽度就是750rpx,这样无论在什么手机上都能等比例缩放。
样式
全局样式
app.wxss 文件中写的是css样式。这里写的样式在整个小程序都生效。
案例
index.wxml
<view class="myview">我是个view</view>
app.wxss
/**app.wxss**/
.myview{
height: 500rpx;
width: 300rpx;
background-color: aquamarine;
font-size: 16rpx;
}
这样,局部页面就使用了全局样式,也就是其他页面也可以引入myview的class样式,能达到与index页面相同的效果。
局部样式
pages文件夹中的 xxx.wxss文件中写的也是css样式,这里的写样式只作用于当前页面。
案例
my.wxml
<!--pages/my/my.wxml-->
<text>个人中心</text>
<view class="myview"></view>
my.wxss
/* pages/my/my.wxss */
.myview{
background-color: purple;
}
以上代码,my是局部组件,它使用全局样式(app.wxsss),并且在全局样式的基础上,重写或者说覆盖了background-color的样式。这样一来,my组件和index组件,除了背景色不一样,其他样式都一致。
按钮组件
按钮组件,button
<button>按钮</button>
button中的属性介绍
size:“”,表示尺寸样式
type: “” ,表示按钮的样式,比如default,warn,primary
plain ,表示镂空按钮(布尔类型)
如果一个属性是布尔类型,就不需要 属性='布尔值'
,直接写上就是默认true,不写就默认false。
<button size:"mini" type="default" plain>按钮</button>
也可以给button设置一些盒子样式,例如:
/* 标签选择器 */
button{
/* 距离顶部300rpx */
margin-top:300rpx;
/* 距离底部30rpx */
margin-botton:30rpx;
/* 按钮本身就是有样式,如果想修改,记得添加!important */
background-color:red !important;
}
轮播图组件
轮播图组件有 swiper 和 swiper-item 这两个组件来实现轮播图
案例
<!-- autoplay表示自动轮播 indicator-dots表示显示指示点 indicator-color表示指示点的颜色 interval="毫秒"表示自动轮播的间隔时间 circular表示衔接轮播-->
<!-- mode表示图片的裁剪属性,例如:mode="widthFix"表示图片自适应宽度 -->
<!-- 轮播图效果 -->
<swiper autoplay indicator-dots indicator-color="#00F00"
interval="3000" circular>
<swiper-item>
<image src="/images/banner1.jpg" mode="widthFix"/>
</swiper-item>
<swiper-item>
<image src="/images/banner2.png" mode="widthFix"/>
</swiper-item>
<swiper-item>
<image src="/images/banner3.jpg" mode="widthFix"/>
</swiper-item>
</swiper>
引入矢量图标库
这里介绍 使用阿里的矢量图标
1.登录成功后,搜索自己想要的图标,
2.然后点击图标上的购物车图标,然后点击右上角的购物车图标,然后添加至项目(没有项目就点击加入新项目),项目名称自定义,然后点击确定。然后会自动跳转到我的项目
页面
3.然后选择Font class,然后点击项目设置
选项,在弹出窗口中项目设置里勾选base64,点击保存。点击暂无代码,点此生成
,会看到一段地址,访问该链接,会访问到代码,将代码复制下来
4.然后再项目里新建一个static文件夹,再在该目录下新建css文件夹,在/static/css/下新建一个文件font.wxss,将刚刚的代码粘贴进去,然后再app.wxss
文件中写入:
@import "/static/css/font.wxss";
5.在我的项目
页面中,复制图标下的图标名称,比如icon-anquan
6.在页面中引入阿里矢量图
<!-- icon-anquan是图标的名称 -->
<text class="iconfont icon-anquan"></text>
tips效果
<view class="tips">
<!-- -->
<!-- icon-anquan是图标的名称 -->
<text class="iconfont icon-anquan"></text>
<text>欢迎使用我们的系统,谢谢</text>
</view>
.tips{
/* 背景色 */
background-color:#f5eedf;
/* 字大小 */
font-size:40rpx;
/* 字颜色 */
color:#e9ab4a;
/* 圆角效果 */
border-radius:50rpx;
/* 上右下左的距离 */
margin:30rpx 10rpx 30rpx 10rpx;
/* */
padding-left:20rpx;
}
flex布局
index.wxml
<view class="menu">
<view class="item">
<image src="/images/menu/ht.png" class="img" />
<text class="title">物业合同</text>
</view>
<view class="item">
<image src="/images/menu/wyf.png" class="img" />
<text class="title">物业费</text>
</view>
<view class="item">
<image src="/images/menu/wygl.png" class="img" />
<text class="title">物业管理</text>
</view>
<view class="item">
<image src="/images/menu/wylx.png" class="img" />
<text class="title">物业维修</text>
</view>
<view class="item">
<image src="/images/menu/ht.png" class="img" />
<text class="title">物业合同</text>
</view>
<view class="item">
<image src="/images/menu/wyf.png" class="img" />
<text class="title">物业费</text>
</view>
<view class="item">
<image src="/images/menu/wygl.png" class="img" />
<text class="title">物业管理</text>
</view>
<view class="item">
<image src="/images/menu/wylx.png" class="img" />
<text class="title">物业维修</text>
</view>
</view>
inedx.wxss
/* flex布局 */
.menu{
display:flex;
justify-content:space-between;
padding:16rpx;
border-radius:10rpx;
/* 元素自动换行 */
flex-wrap:wrap;
background-color:powderblue;
}
.item{
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
width:150rpx;
height:200rpx;
border:rgb(192,251,255) solid 1rpx;
margin:1rpx;
background-color:powderblue;
}
.img{
width:88rpx;
height:88rpx;
border-radius:10rpx;
}
.title{
margin-top:12rpx;
font-size:24rpx;
}
通知布局
index.wxml
<view class="notice">
<image src="/images/home/board.png" mode="aspectFit" style="width:200rpx;height:100rpx">
<text>通知公告</text>
</view>
index.wxss
.notice{
display:flex;
justify-content:flex-start;
margin-top:20rpx;
margin-bottom:20rpx;
}
.notice > text{
flex-grow:1;
font-size:40rpx
}
底部布局
index.wxml
<view class="bottom">
<view>
<image src="/images/home/cute_1.jpg" mode="scaleToFill" />
</view>
<view>
<image src="/images/home/cute_2.jpg" mode="scaleToFill" />
</view>
<view>
<image src="/images/home/cute_3.jpg" mode="scaleToFill" />
</view>
<view>
<image src="/images/home/cute_4.jpg" mode="scaleToFill" />
</view>
</view>
index.wxss
.bottom{
display:flex;
justify-content:space-between;
flex-wrap:wrap;
}
.bootm>view>image{
width:345rpx;
padding:10rpx;
height:200rpx;
}
事件
事件绑定
按钮或者某些组件,点击会触发事件执行,比如打印数据,向后端发起请求。
bind:tap=“函数方法” :给组件添加点击事件
也可以bindtap=“” 这种写法
最简单的事件绑定案例
my.wxml
<view>====事件绑定====</view>
<button type="warn" plain size="mini" bind:tap="handleConsole">点击控制台打印</button>
my.js
// 所有代码,都要放在Page对象中
Page({
handleConsole(){
console.log('我被点了');
},
})
当打开my的页面,点击按钮,调试器中的Console就会打印:我被点了。
阻止事件冒泡
父组件套了子组件,子组件上有事件,父组件上也有事件,点击子组件,子组件的事件会触发,父组件的事件也会触发。为了防止这种现象发生,就要阻止事件冒泡。
使用
catch:tap="方法名"
绑定点击事件 就可以阻止事件冒泡
my.wxml
<view style="height:400rpx;width:750rpx;background-color:pink; display:flex;justify-content:center;align-items:center;" bind:tap="handleParent">
<!-- 阻止事件冒泡:catch:tap="函数方法名" -->
<button type="primary" plain catch:tap="handleChildren">按钮</button>
</view>
my.wxss
Page({
handleParent(){
console.log("父亲被点了");
},
handleChildren(){
console.log("孩纸被点了");
},
})
事件对象的传参
当绑定了事件后,函数都可以接受一个参数,事件对象(evnet)
在标签中添加属性:data-xxx=“数据”;
例如:
my.wxml
<!-- 传参方式一 -->
<view bind:tap="handleClick" data-id="1001" data-name="justin">点我</view>
<!-- 将data-xxx="" 传递给js中的event -->
<!-- 传参方式二 -->
<view bind:tap="handleClick" mark:name="justin1">点我</view>
my.js
event.currentTarget : 事件绑定者
event.target:事件触发者
一般情况下,上面这两个值是一样的,如果有事件冒泡,这两个值就不一样了
event.target.dataset: 获取标签传来的对象 data,里面有data-xxx的值 {id:1001,name:justin}
<!-- 获取参数方式一 -->
Page({
handleClick(event){
// event.currentTarget:事件绑定者
// event.target:事件触发者
// event.target.dataset 获取标签传来的对象 data,里面有data-xxx的值
console.log(event.target.dataset.name);//获取data-name的值
}
})
<!-- 获取参数方式二 -->
Page({
handleClick(event){
// event.mark.xxx 获取标签中mark:xxx传来的值
console.log('event.mark.name');
}
})
页面跳转
组件跳转
组件跳转又称为声明式导航
需要使用navigator组件,加属性来实现跳转
<navigator url="/pages/login/login">
<view> type="primary" plain>跳转登录页面</view>
</navigator>
这样,当点击按钮,就会调转到login页面。
更多跳转方式
navigator标签中的open-type属性
navigate(默认):保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面
redirect: 关闭当前页面,跳转到应用内的某个页面。但不能跳转到 tabbar 页面
switchTab:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
reLaunch:关闭所有页面,打开到应用内的某个页面
navigateBack:关闭当前页面,返回上一页面或多级页面
<!-- open-type="navigate"案例 -->
<navigator url="/pages/login/login" open-type="navigate">
<button type="primary" plain="true">跳转到登录页面</button>
</navigator>
<!-- open-type="navigateBack":表示回退上一页 -->
<!-- delta="数字" 表示回退到前面第几个页面 -->
<navigator open-type="navigateBack">
<button>回退</button>
</navigator>
跳转携带参数
url=“/pages/login/login?name=justin&age=19”
<navigator url="/pages/login/login?name=justin&age=19">
<button type="primary" plain>携带参数的跳转</button>
</navigator>
跳转到的另一个页面获取 跳转来的数据,要在另一个页面的js文件中的onLoad(options){console.log("options")}
获取
js跳转
js跳转又称为编程式导航
有5个方法进行跳转
wx.navigateTo({
url:‘url’;
})
wx.redirectTo({
url:‘url’;
})
wx.switchTab({
url:‘url’;
})
wx.reLaunch({
url:‘url’;
})
wx.navigateBack({
url:‘url’;
})
js跳转案例
my.wxml
<button type="default" bind:tap="handlenavigateTo">navigateTo</button>
<button type="warn" bind:tap="handleredirectTo">redirectTo</button>
<button type="primary" bind:tap="handleswitchTab">switchTab</button>
<button type="default" bind:tap="handlereLaunch">reLaunch</button>
<button type="warn" bind:tap="handlenavigateBack">navigateBack</button>
my.js
// 跳转的时候也可以携带参数
handlenavigateTo(){
wx.navigateTo({
url: '/pages/login/login?name=xxx&hobby=fly',
})
},
handleredirectTo(){
wx.redirectTo({
url: '/pages/login/login',
})
},
handleswitchTab(){
wx.switchTab({
url: '/pages/index/index',
})
},
handlereLaunch(){
wx.reLaunch({
url: '/pages/login/login',
})
},
handlenavigateBack(){
// 关闭当前页面,返回上一页或上某一页,传入数字
wx.navigateBack()
wx.navigateBack({
delta:2
})
},
wxml语法
模板语法
页面的js中定义一些变量,在wxml使用 {{js中的data中的变量}}。
注意:{{}} 中不能写js语句和js方法。
login.wxml
<view>
<view>名字是:{{name}}</view>
<view>年龄是:{{age}}</view>
<view>爱好是:{{hobby}}</view>
</view>
<view>
<view>对象数据类型显示</view>
<view>名字是:{{userinfo.name}}</view>
<view>年龄是:{{userinfo.gender}}</view>
<view>爱好是:{{userinfo.age}}</view>
</view>
<view>
<view>列表数据类型显示</view>
<view>animals[0]</view>
<view>animals[1]</view>
<view>animals[2]</view>
</view>
<view>算术运算:{{99+1}}</view>
<view>三目运算符:{{num>999?"真":"假"}}</view>
<view>逻辑运算:{{num>999}}</view>
<!-- {{}} 中不能写js语句和js方法 -->
login.js
Page({
// wxml中使用的变量,必须放在data中
data:{
name:'justin',
age:99,
hobby:'喝酒',
userinfo:{
name:'lyf',
gender:'女',
age:38
},
animals:['狗','猫','大象'],
num:99
}
})
数据更新
修改变量值
如果在js中,改了变量的值,想让页面也发生变化,需要使用
this.setData({key: 变化后的值}
)
index.wxml
<view>姓名是:{{name}}</view>
<view>年龄是:{{age}}</view>
<button bind:tap="handleAddAge">点我年龄+1</button>
index.js
Page({
data:{
name:'justin',
age:19
},
handleAddAge(){
//1.取到data中的age
console.log(this.data.age);//19
this.data.age+=1;
console.log(this.data.age);//20
// 默认数据,不是响应式,js变化,页面不变
// 2.想要页面也变化,借助微信提供的setData方法,也就是直接给数据赋值
this.setData({
age:this.data.age + 1;
})
}
})
修改对象
使用 this.setData({‘对象.属性’=属性值}) 修改data中对象的属性值
另一种方式:this.data.对象.属性 = 属性值
this.setData({
‘对象.属性’ :this.data.对象.属性 = 属性值
})
index.js
Page({
data:{
name:'justin',
age:19,
userinfo:{name:'lqz',hobby:'烫头'}
},
handleChangeHobby(){
// 修改对象中值
this.setData({
// 修改userinfo对象中的hobby属性
'userinfo.hobby':'篮球'
})
}
})
index.wxml
<!-- 显示对象 -->
<view>{{userinfo.name}}</view>
<view>{{userinfo.hobby}}</view>
<button type="primary" bindtap="handleChangeHobby">变换爱好</button>
修改多个对象
思路:直接定义一个新的对象,将data中原有的对象,直接整个替换掉。
<!-- 显示对象 -->
<view>{{userinfo.name}}</view>
<view>{{userinfo.hobby}}</view>
<view>{{userinfo.age}}</view>
<button type="primary" bindtap="handleChangeHobby">变换爱好和增加年龄</button>
Page({
data:{
userinfo:{name:'lqz',hobby:'烫头'}
},
handleChangeHobby(){
// 解压赋值
const user = {...this.data.userinfo,age:19};
// ..this.data.userinfo是解压赋值,后面的全都是替换对象原有的值
// 简写:const userinfo = {...this.data.userinfo,age:19,hobby:'乒乓球'};
this.setData({
// 简写直接用:
// userinfo
userinfo:user
})
}
})
修改数组
思路:先把数组修改完,再用setData赋值
index.wxml
<!-- 循环数组打印名字 -->
<view wx:for="{{names}}" wx:key="{{index}}">{{item}}</view>
<button type="primary" bindtap="handleAddName">增加人名</button>
index.js
Page({
data:{
names:['lyf','dlrb','glnz','mezh']
},
handleAddName(){
// 1.先追加,再setData
// 增加亚瑟王
this.data.names.push('亚瑟王');
// 让页面数据变化
this.setData({
names:this.data.names
})
// 2.通过数组的拼接
// concat不会在原数据上增加
const newName = this.data.names.concat('甄姬');
this.setData({
names:newName
})
// 3.通过解构赋值
const newName = [...this.data.names,'李白'];
this.setData({
names:newName
})
// 4.修改数组中的值
// 修改方式:'数组[索引]' = '新值'
this.setData({
'names[0]': 'alyf'
})
// 5.删除数据中的值
this.setData({
// 删除数组中的第一个元素
names:this.data.names.slice(1)
})
}
})
列表渲染
for循环
<view wx:for={{}} wx:key="index"> </view>
item只要循环数据,在循环里面,就会有两个值,一个是index,索引值,另一个是item,数组循环的值。
修改item: wx:for-item =‘info’
修改index: wx:for-index=‘i’
index.wxml
<!-- 列表渲染 -->
<view>循环显示商品信息</view>
<view wx:for="{{goodsList}}" wx:key="index">
<text>商品id:{{item.id}}--商品名字:{{item.name}}--商品价格:{{item.price}}</text>
</view>
index.js
Page({
data:{
goodsList:[{id:1001,name:'钢笔',price:9},{id:1002,name:'铅笔',price:6},{id:1003,name:'脸盆',price:99}]
}
})
条件渲染
if语句
wx:if wx:elif wx:else
<!-- if语句格式 -->
<view wx:if="{{}}"></view>
<view wx:elif="{{}}"></view>
<view wx:else></view>
index.wxml
<!-- 条件渲染 -->
<!-- model:变量名 表示双向数据绑定 -->
<input type="text" model:value="{{score}}" style="border:1rpx solid red;">
<view wx:elif="{{score>=90&&score<=100}}">优秀</view>
<view wx:elif="{{score>=80&&score<=90}}">良好</view>
<view wx:elif="{{score>=60&&score<=80}}">及格</view>
<view wx:else>不及格</view>
index.js
Page({
data:{
score:70
}
})
扩展
<!-- wx:if 和 hidden 的区别 -->
wx:if 为false的时候,元素隐藏,但元素不占据位置
hiden 为false的时候,,元素隐藏,但元素会占据位置
<!-- 部分代码案例 -->
<view wx:if="{{false}}">元素</view>
<view hidden="{{false}}">元素</view>
网络请求
需要在微信小程序端,发送网络请求,获取数据,显示在小程序上。
注意:发送网络请求的域名,必须在微信公众平台配置。
微信访问后端地址,必须有域名,https的,需要在服务器域名
中配置才能访问
配置方式
1.登录到微信小程序后端管理,
2.点击左侧菜单栏中的
开发
3.然后在右侧的
开发设置
中,鼠标向下滑动,找到服务器域名
4.点击
开始配置
,然后扫描验证身份,在request合法域名
对应的输入框中输入https://www/xxx/com
(自己备案的域名),然后点击保存并提
按钮。
当然了,以上方式是项目上线阶段。如果只是测试,只需要在微信开发者工具中的 详情》本地配置》勾选不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书
即可。就可以本地接受和发送网络请求了。
具体案例
django后端部分代码
子应用的views.py
from django.http import JsonResponse
def index(request):
return JsonResponse({"name":"pyy","hobby":"抽烟","age":38})
根目录下 urls.py
from 子应用.view import index
urlpatterns = [
path('index/'index)
]
然后启动django程序。
微信小程序部分代码
index.wxml
<!-- 发送网络请求 -->
<view>用户名:{{user.name}}</view>
<view>爱好:{{user.hobby}}</view>
<view>年龄:{{user.age}}</view>
<button type="primary" bindtap="handleLoadUser">加载用户信息</button>
index.js
Page({
data:{
user:{}
},
handleLoadUser(){
// 发送请求之前,展示loading效果
wx.showLoading({
title:'加载中~',
mark:true,//显示透明蒙层,设置后,框后的按钮都不能点击了。
})
// 发起网路请求
wx.request({
url:'http://127.0.0.1:8000/index/',
method:'GET',
data:{},//如果是POST请求,这里就写请求参数,GET请求为空就好
header:{},
success:(res)=>{
// 如果请求成功
// 获取后端返回的数据 res.data
console.log(res.data);
// 渲染数据到页面
this.setData({
user:res.data
})
},
fail:(error)=>{
// 如果请求失败
console.log(error)
},
complete:(res)=>{
// 请求无论是成功 还是失败都会走到这里
// 关闭加载loading 必须手动关闭
wx.hideLoading();
}
})
}
})
显示电影案例
小程序端样式
my.wxml
<view class="item" wx:for="{{film_list}}" wx:key="*this">
<image src="{{item.poster}}" mode="aspectFit" class="photo" />
<view>
<view class="name">{{item.name}}</view>
<text>
<text class="grade">观众评分 </text>
<text class="grade2">{{item.grade}} </text>
<text class="label">
{{item.nation}} | {{item.runtime}} 分钟
</text>
</text>
</view>
</view>
my.js
Page({
data:{
film_list:[]
},
/**
* 生命周期函数--监听页面加载
*/
// 当页面一进来,页面加载成功,就发送请求获取数据
onLoad: function (options) {
// 发送网络请求,加载数据
wx.request({
url:'http://127.0.0.1:8000/app01/films/',
method:'GET',
success:(res)=>{
console.log(res.data);
if(res.data.code==100){
// 后端返回的,赋值给film_list
this.setData({
film_list:res.data.results
})
}
}
})
}
})
my.wxss
page{
background-color:pink;
}
.item{
display:flex;
flex-direction:row;
justify-content:flex-start;
margin:10rpx;
background-color:#FFFFFF;
border-radius:20rpx;
}
.photo{
height:250rpx;
width:200rpx;
padding:5rpx;
}
.name{
color:#191a1b;
font-size:40rpx;
height:22px;
line-height:22px;
margin-right:5px
}
.grade{
font-size:30rpx;
margin-top:4px;
color:#797d82;
}
.grade2{
color:#ffb232;
font-size:30rpx;
}
.label{
font-size:30rpx;
margin-top:4px;
color:#797d82;
}
django后端接口
film.json文件中的数据
{
"code": 100,
"msg": "ok",
"results": [
{
"filmId": 6821,
"name": "你想活出怎样的人生",
"poster": "https://pic.maizuo.com/usr/movie/57116f984c95f7e0abe768550bd78ef9.jpg",
"actors": [
{
"name": "宫崎骏",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/589bd0777f174e554b866cbc61145422.jpg"
},
{
"name": "山时聪真",
"role": "真人",
"avatarAddress": "https://pic.maizuo.com/usr/movie/ed862a087874582813cf62ff331be69d.jpg"
},
{
"name": "刘昊然",
"role": "真人(中文配音)",
"avatarAddress": "https://pic.maizuo.com/usr/movie/a7b242f9b8167e42c460d3b96d28a721.jpg"
},
{
"name": "菅田将晖",
"role": "苍鹭",
"avatarAddress": "https://pic.maizuo.com/usr/movie/06eae5dd0a6a705ae6eb1f2c625fc1e0.jpg"
},
{
"name": "大鹏",
"role": "苍鹭\u0026苍鹭男(中文配音)",
"avatarAddress": "https://pic.maizuo.com/usr/movie/3125ea2b699584e68cb3c3b9ae586217.png"
}
],
"director": "宫崎骏",
"category": "动画|奇幻|冒险",
"synopsis": "电影讲述了少年牧真人的母亲葬身火海后,他随父亲与继母组成新家庭。深陷悲伤的真人阴郁孤僻,难以融入新环境。一次意外,他跟随一只会说话的苍鹭闯入废弃的神秘塔楼,却不料进入了奇幻的“亡灵世界”,开始了一场不可思议的冒险……",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "日本",
"language": "",
"videoId": "",
"premiereAt": 1712102400,
"timeType": 3,
"runtime": 124,
"grade": "7.4",
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6753,
"name": "哥斯拉大战金刚2:帝国崛起",
"poster": "https://pic.maizuo.com/usr/movie/be17f0784f8a83fbe6be79df1ce1914b.jpg",
"actors": [
{
"name": "亚当·温加德",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/de782ff4f69db74eb031ff33a035f8c8.jpg"
},
{
"name": "金刚",
"role": "演员",
"avatarAddress": "https://pic.maizuo.com/usr/movie/cab8709e5703861909485b45abae59c0.jpg"
},
{
"name": "哥斯拉",
"role": "演员",
"avatarAddress": "https://pic.maizuo.com/usr/movie/f7b2715cecfc4365ff749a5a9e6b025c.jpg"
},
{
"name": "丽贝卡·豪尔",
"role": " 艾琳 Ilene Andrews",
"avatarAddress": "https://pic.maizuo.com/usr/movie/467d85cafb939c0285ab69ae887fce84.jpg"
},
{
"name": "布莱恩·泰里·亨利",
"role": " 伯尼 Bernie Hayes",
"avatarAddress": "https://pic.maizuo.com/usr/movie/c10d99a613d070ce83c60e25d169cb64.jpg"
}
],
"director": "亚当·温加德",
"category": "动作|冒险|科幻",
"synopsis": "继上一次的怪兽高燃对战之后,金刚和哥斯拉将再度联手对抗一个潜伏在世界中的巨大威胁,并逐步探索这些巨兽们的起源以及骷髅岛等地的奥秘。同时,上古之战的面纱也将会被揭晓,而正是那场战斗创造出了这些超凡的生物,并深刻影响了人类世界的命运。",
"filmType": {
"name": "3D",
"value": 2
},
"nation": "美国",
"language": "",
"videoId": "",
"premiereAt": 1711670400,
"timeType": 3,
"runtime": 115,
"grade": "7.2",
"item": {
"name": "3D",
"type": 2
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6812,
"name": "草木人间",
"poster": "https://pic.maizuo.com/usr/movie/7a4e3daddbe3a35aa4247cb4ae6273cd.jpg",
"actors": [
{
"name": "陈建斌",
"role": "老钱",
"avatarAddress": "https://pic.maizuo.com/usr/movie/7fc8f50b79675adaeb37a83833696652.jpg"
},
{
"name": "王佳佳",
"role": "万晴",
"avatarAddress": "https://pic.maizuo.com/usr/movie/655d3d188544bec01ebab82c5adaee3e.jpg"
},
{
"name": "顾晓刚",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/83acc483e3d165bf99083da374aaec20.jpg"
},
{
"name": "吴磊",
"role": "何目莲",
"avatarAddress": "https://pic.maizuo.com/usr/movie/42ab0462b8b3bc7c2203713320ab9c8e.jpg"
},
{
"name": "蒋勤勤",
"role": "吴苔花",
"avatarAddress": "https://pic.maizuo.com/usr/movie/529786e75f23f5d5b45ddf3f2d32c652.jpg"
}
],
"director": "顾晓刚",
"category": "剧情|犯罪",
"synopsis": "丈夫何山凭空消失了十年后,苔花(蒋勤勤饰)正要迈进新生,但命运却把她推向了另一重绝境——她前脚被情人(陈建斌饰)母亲从采茶园赶走,后脚就被最亲近的好姐妹金兰骗进了传销组织“蝴蝶国际”。母亲沉迷其中,让一边寻父一边救母的儿子目莲(吴磊饰)身心疲惫,而蝴蝶国际却如藤蔓疯长一般,将恶魔的种子根植在无数百姓心中。苔花也摇身一变,从衣着打扮到言行举止都宛如“新生”,疯癫的举动让目莲感到诧异。母亲如蝴蝶一般翩翩于梦中之际,儿子想尽一切办法奋力解救……这座人间炼狱究竟该怎样逃脱?现代版“目连救母”能否成功?",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "中国大陆",
"language": "",
"videoId": "",
"premiereAt": 1712102400,
"timeType": 3,
"runtime": 118,
"grade": "7.7",
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6801,
"name": "白日之下",
"poster": "https://pic.maizuo.com/usr/movie/11bf63b107d048357e8ca630fc39ae35.jpg",
"actors": [
{
"name": "姜大卫",
"role": " 周健通(通伯)",
"avatarAddress": "https://pic.maizuo.com/usr/movie/542a5a0e25aed5c3bae6ea68f1d63600.jpg"
},
{
"name": "余香凝",
"role": " 凌晓琪",
"avatarAddress": "https://pic.maizuo.com/usr/movie/496d1fed33ad248efb3ceea0b408d0cf.jpeg"
},
{
"name": "林保怡",
"role": " 章剑华",
"avatarAddress": "https://pic.maizuo.com/usr/movie/4b1c4459cc5b00ec4588482ce997f3db.jpg"
},
{
"name": "梁仲恒",
"role": " 阿亮",
"avatarAddress": "https://pic.maizuo.com/usr/movie/8d0e65025c7e9a51caf5eeeb4d92b344.jpg"
},
{
"name": "简君晋",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/f6705ea1b27e72a8c93a06d7b2649153.jpg"
}
],
"director": "简君晋",
"category": "剧情|犯罪",
"synopsis": "故事改编自真实事件,揭露隐藏在新闻背后、鲜为人知的残疾院舍真相。新闻社接获一宗有关残疾院舍“彩桥之家”虐待院友的线报,侦查小组为揭露残疾院舍监管问题,记者晓琪(余香凝 饰)潜入院舍,揭发内里的非人道生活,寻找日光之下的残酷真相。",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "中国香港",
"language": "",
"videoId": "",
"premiereAt": 1712880000,
"timeType": 3,
"runtime": 106,
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6816,
"name": "黄雀在后!",
"poster": "https://pic.maizuo.com/usr/movie/adc91ba9d7505d7352260f9d4a6fcff2.jpg",
"actors": [
{
"name": "徐伟",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/b8566f83d0af556ec66e67fde7e91f89.jpg"
},
{
"name": "何文超",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/cafb44fa22a10eb809ace85b89291d3b.jpg"
},
{
"name": "冯绍峰",
"role": "演员",
"avatarAddress": "https://pic.maizuo.com/usr/movie/63cd6726f250c6788cc8d8f4caab1509.jpg"
},
{
"name": "陶虹",
"role": "演员",
"avatarAddress": "https://pic.maizuo.com/usr/movie/87e31cded6c44462755aa44eed9b0be2.jpg"
},
{
"name": "黄觉",
"role": "演员",
"avatarAddress": "https://pic.maizuo.com/usr/movie/793afc2b277346f51375d06f84d732ff.jpg"
}
],
"director": "徐伟|何文超",
"category": "犯罪|悬疑|剧情",
"synopsis": "10年前的一个夏夜,警官袁文山(冯绍峰 饰)接到一起抢劫杀人案,在逐渐深入的调查过程中,当晚在场的嫌疑人们逐一浮出水面,然而案情的真相远非表面那般简单,三案并行,一场利益和正义的较量愈演愈烈,卷入其中的人们都是所图为何?究竟是情法之争,还是欲望驱使?在案件稍有眉目之时,袁文山却发现了一个被自己忽略的重要线索... ...",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "中国大陆",
"language": "",
"videoId": "",
"premiereAt": 1712102400,
"timeType": 3,
"runtime": 99,
"grade": "7.6",
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6795,
"name": "功夫熊猫4",
"poster": "https://pic.maizuo.com/usr/movie/89d7a3bbd98d0ffab74da50cd03641e2.jpg",
"actors": [
{
"name": "迈克·米歇尔",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/9f40bb3aaf9ef967b67b4bc3123a03e8.jpg"
},
{
"name": "杰克·布莱克",
"role": "阿宝 Po",
"avatarAddress": "https://pic.maizuo.com/usr/movie/0e4b06db0fb7f08fd309cf872b994cce.jpg"
},
{
"name": "黄渤",
"role": "阿宝 Po(中文配音)",
"avatarAddress": "https://pic.maizuo.com/usr/movie/f2a4a18bf8cf420b09c0a19d20a4a0fc.jpg"
},
{
"name": "奥卡菲娜",
"role": "小真 Zhen",
"avatarAddress": "https://pic.maizuo.com/usr/movie/1b7f719c81114df25dc2688ea39f6e18.jpeg"
},
{
"name": "关继威",
"role": "Han",
"avatarAddress": "https://pic.maizuo.com/usr/movie/b008f921bda277caae91823cffb4a4e6.jpg"
}
],
"director": "迈克·米歇尔",
"category": "动画|动作|冒险",
"synopsis": "爷青回!《功夫熊猫》新作来袭!阿宝“升职”同时,新仇旧敌集结现身,大龙竟起死回生?狐狸小真身份神秘,到底有何心机?阿宝被师傅要求选出下一任神龙大侠,正苦恼如何应对时,阿宝昔日的手下败将们却纷纷重出江湖!身世神秘的狐狸小真告诉阿宝,这一切的幕后黑手正是邪恶女巫魅影妖后!阿宝能否打败魅影妖后,昔日敌人又为何再次现身?这次又会发生怎样的搞笑趣事?赶快带上亲朋好友,一起到影院寻找真相吧~",
"filmType": {
"name": "3D",
"value": 2
},
"nation": "美国",
"language": "",
"videoId": "",
"premiereAt": 1711065600,
"timeType": 3,
"runtime": 94,
"grade": "7.3",
"item": {
"name": "3D",
"type": 2
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6834,
"name": "来自汪星的你",
"poster": "https://pic.maizuo.com/usr/movie/4de0b4ddb98abe9fa45d6b31da07cb53.jpg",
"actors": [
{
"name": "陆可",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/edf5c22c4394c5b2844d241ddb95378d.jpg"
},
{
"name": "郭富城",
"role": "江斯旺",
"avatarAddress": "https://pic.maizuo.com/usr/movie/bcb5b34461bff36771f7f7201090f057.jpg"
},
{
"name": "蓝盈莹",
"role": "江露",
"avatarAddress": "https://pic.maizuo.com/usr/movie/8fbfa4d3e0b988f796220f545dd0c683.jpg"
},
{
"name": "黄龄",
"role": "C姐",
"avatarAddress": "https://pic.maizuo.com/usr/movie/cab1fa62536f8bb52e38904f40a3bd74.jpg"
},
{
"name": "王大陆",
"role": "秦天",
"avatarAddress": "https://pic.maizuo.com/usr/movie/1d416e6ceb5529dc890c91236231e227.jpg"
}
],
"director": "陆可",
"category": "奇幻|喜剧|家庭",
"synopsis": "糖厂工人江斯旺(郭富城 饰)独自抚养女儿江露(蓝盈莹 饰)成长,不料在阴差阳错中变成一条小狗。狗爸阿旺费尽力气找到女儿,发现此时江露已长大成人,并成为了一位创作歌手,但看似光鲜亮丽的背后却另有隐情。老爸决定以小狗阿旺的身份开启一段“守护之旅”……",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "中国大陆",
"language": "",
"videoId": "",
"premiereAt": 1712880000,
"timeType": 3,
"runtime": 105,
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6767,
"name": "我们一起摇太阳",
"poster": "https://pic.maizuo.com/usr/movie/a8ecf5fcbeeddb7488876f042bf7baa4.jpg",
"actors": [
{
"name": "彭昱畅",
"role": "吕途",
"avatarAddress": "https://pic.maizuo.com/usr/movie/91590c0fb4e9e895503796203ed14489.jpg"
},
{
"name": "李庚希",
"role": "凌敏",
"avatarAddress": "https://pic.maizuo.com/usr/movie/e0d8d70d6a267dc4563806bc4b522b7b.jpg"
},
{
"name": "韩延",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/cfa40371868495071b1c97b72c55ab8f.jpg"
},
{
"name": "徐帆",
"role": "陶怡",
"avatarAddress": "https://pic.maizuo.com/usr/movie/4bc8d78d21b4e6c6eeeeedc143ca5b83.jpg"
},
{
"name": "高亚麟",
"role": "凌父",
"avatarAddress": "https://pic.maizuo.com/usr/movie/28c233165445e3079756d3c52f8cbb83.jpg"
}
],
"director": "韩延",
"category": "爱情|剧情|家庭",
"synopsis": "春节档温暖现实主义题材电影,挥别旧年的阴霾,迎接新年的爱与阳光!韩延导演“生命三部曲”终章,当“没头脑”吕途遇上“不高兴”凌敏,两个身患重症却性格迥异的年轻人,因为“生命接力”的约定,阴差阳错地踏上了一段充满爱与力量的治愈之旅。",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "中国大陆",
"language": "",
"videoId": "",
"premiereAt": 1707523200,
"timeType": 3,
"runtime": 129,
"grade": "7.9",
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6786,
"name": "坠落的审判",
"poster": "https://pic.maizuo.com/usr/movie/a1cfca3e8ac6d12ac07cdbd9fc7a0697.jpg",
"actors": [
{
"name": "茹斯汀·特里耶",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/69178dbbc98aee3ab2fa12a4f21952c1.jpg"
},
{
"name": "桑德拉·惠勒",
"role": " Sandra Voyter",
"avatarAddress": "https://pic.maizuo.com/usr/movie/38c134c4bdac10d2d8dcf10c059cfd1f.jpg"
},
{
"name": "斯万·阿劳德",
"role": " Maître Vincent Renzi",
"avatarAddress": "https://pic.maizuo.com/usr/movie/dbfdb35a687980af2e6591931e363f16.jpg"
},
{
"name": "安托万·赖纳茨",
"role": " L'avocat général",
"avatarAddress": "https://pic.maizuo.com/usr/movie/08405bf7416d13af4aeea42e01b94e4b.jpg"
},
{
"name": "萨穆埃尔·泰斯",
"role": " Samuel Maleski",
"avatarAddress": "https://pic.maizuo.com/usr/movie/644bd98b7a230279f393f2e3a8ed09cf.jpg"
}
],
"director": "茹斯汀·特里耶",
"category": "剧情|家庭",
"synopsis": "2023戛纳金棕榈最佳影片!2024奥斯卡最佳原创剧本大奖!狂揽全球280+项大奖及提名!继是枝裕和的《小偷家族》后,时隔六年,再度登陆内地大银幕的金棕榈最佳影片!国内外各大平台口碑爆棚,影片以女性视角细腻地呈现了夫妻关系中的隐痛,丈夫的死亡真相唤起观众对亲密关系的深入思考和共鸣,没有谁的生活经得起这样的审判!但人性中不肯投降的、微弱的美好和希望,最终将指引着每个人继续前行!3月29日,大银幕探寻家庭与婚姻的真相!",
"filmType": {
"name": "2D",
"value": 1
},
"nation": "法国",
"language": "",
"videoId": "",
"premiereAt": 1711670400,
"timeType": 3,
"runtime": 152,
"grade": "7.5",
"item": {
"name": "2D",
"type": 1
},
"isPresale": true,
"isSale": false
},
{
"filmId": 6756,
"name": "沙丘2",
"poster": "https://pic.maizuo.com/usr/movie/ed94ed416641c374e55e16162692019c.jpg",
"actors": [
{
"name": "丹尼斯·维伦纽瓦",
"role": "导演",
"avatarAddress": "https://pic.maizuo.com/usr/movie/967cff2206d0325dfaa865fb613224a5.jpg"
},
{
"name": "提莫西·查拉梅",
"role": "保罗",
"avatarAddress": "https://pic.maizuo.com/usr/movie/5697b464e40ed22bec1a9e1952d3adb9.jpg"
},
{
"name": "赞达亚·科尔曼",
"role": "契妮",
"avatarAddress": "https://pic.maizuo.com/usr/movie/0599bb29ab6f328cce7a0ff7d6cb4f1b.jpg"
},
{
"name": "丽贝卡·弗格森",
"role": "杰西卡夫人",
"avatarAddress": "https://pic.maizuo.com/usr/movie/d5fa927d7101db694815d4b60fad0926.jpg"
},
{
"name": "乔什·布洛林",
"role": "哥尼",
"avatarAddress": "https://pic.maizuo.com/usr/movie/1d90154f6fb5ad98a6c5497184e50526.jpg"
}
],
"director": "丹尼斯·维伦纽瓦",
"category": "科幻|动作|冒险|剧情",
"synopsis": "《沙丘2》将会探索保罗·厄崔迪的传奇之旅,他与契妮和弗雷曼人联手,踏上对致其家毁人亡的阴谋者的复仇之路。当面对一生挚爱和已知宇宙命运之间的抉择时,他必须努力阻止只有他能预见的可怕的未来。",
"filmType": {
"name": "4D",
"value": 13
},
"nation": "美国,加拿大",
"language": "",
"videoId": "",
"premiereAt": 1709856000,
"timeType": 3,
"runtime": 166,
"grade": "7.2",
"item": {
"name": "4D",
"type": 13
},
"isPresale": true,
"isSale": false
}
]
}
1.创建django项目 wx_backend
2.创建app文件夹,在该文件夹下创建子应用app01
3.路由分发,app01下的urls.py
4.总路由分发
urlpatterns = [
# ...省略以上代码
path('app01/',include('app01.urls')),
]
5.app01包下的urls.py
from django.urls import path,include
form .views import films
urlpatterns = [
path('films/',films),
]
6.视图函数
import json
from django.http import JsonResponse
def films(request):
with open('./film.json','r',encoding="utf-8") as f:
res_dic = json.load(f)
return JsonResponse(res_dic,safe=False)
7.前端访问:http://127.0.0.1:8000/app01/films/ 就可以看到json数据。
对话框
模态框
index.wxml
<button type="primary" plain bind:tap="handleShowModel">点我弹出模态框</button>
index.js
Page({
data:{
},
handleShowModel(){
wx.showModal({
title:'您确定要xx吗',
content:'这里是内容部分',
complete:(res)=>{
if(res.cancel){
// 用户取消操作
console.log('用户取消了');
}
if(res.confirm){
// 用户确认操作
console.log('用户确认了');
}
}
})
}
})
消息对话框
index.wxml
<button type="primary" plain bind:tap="handleShowTost">点我弹出消息对话框</button>
index.js
Page({
handleShowTost(){
wx.showToast({
title:'恭喜你,秒杀成功',
icon:'success', // 也可以eroor
duration:2000,// 2000毫秒之后消失
})
}
})
本地存储
比如说登录成功,后端返回token串[用户登录信息],把token存到小程序端,后续发送请求,要携带token,后端才能校验通过。
小程序端本地如何存储数据
index.wxml
<button type="default" plain bind:tap="handleSave">存储数据</button>
<button type="primary" plain bind:tap="handleGet">获取数据</button>
<button type="default" plain bind:tap="handleDelete">删除数据</button>
<button type="primary" plain bind:tap="handleClear">清空数据</button>
index.js
Page({
// 后期可以使用同步或异步,但是感官上差不多,但是写法不一样
// 同步保存
handleSave(){
wx.setStorageSync('name','justin')
wx.setStorageSync('age',19)
// 微信小程序,直接存对象即可,最终它被转成json格式字符串存到 本地存储中
wx.setStorageSync('wife',{name:'lyf',age:'37',hobby:'高尔夫'})
},
handleGet(){
// 获取本地存储
const name = wx.getStorageSync("name")
const age = wx.getStorageSync("age")
const wife = wx.getStorageSync("wife")
console.log(name)
console.log(age)
console.log(wife)
},
handleDelete(){
// 清除微信缓存或者删除小程序或者用代码删除
wx.removeStorageSync('wife')
},
handleClear(){
// 清空本地存储
wx.clearStorageSync()
}
})
Page({
// 异步保存
handleSave(){
wx.setStorage({
// 必须是key和data
key:'name',
data:'lqz'
})
wx.setStorage({
key:'boyfirend',
data:{name:'pyy',age:67}
})
},
// 异步获取,函数定义成async 内部获取的时候,前面写await
async handleGet(){
// 获取
const boyfriend = await wx.getStorage({key:'boyfirend'})
console.log(boyfriend.data)
},
handleDelete(){
// 删除
wx.removeStorage({
key:'name'
})
},
handleClear(){
// 清空
wx.clearStorage()
}
})
上拉下拉加载
上拉加载更多
goods.wxml
<view wx:for="{{good_list}}" wx:key:'*this'>{{item}}</view>
goods.js
onReachBottom(){} 是固定内置函数,必须这么写
Page({
data:{
good_list:[1,2,3]
},
// (配合goods.json中的配置)当滑动到底部还有50rpx时,就会触发整个函数执行
// 可以发送请求获取数据
onReachBottom(){
// console.log('上拉了')
wx.request({
url:"http://127.0.0.1:8000/app01/random/",
method:"GET",
success:(res)=>{
this.setData({
good_list:this.data.good_list.concat(res.data)
})
}
})
}
})
goods.wxss
view{
height:400rpx;
dispaly:flex;
justify-content:center;
align-items:center;
}
// 奇数背景色是粉色
view:nth-child(odd){
background-color:pink;
}
// 偶数背景色绿色
view:nth-child(even){
background-color:rgb(17,133,88);
}
goods.json
“onReachBottomDistance”:50 表示当页面距离底部50rpx的时候,触发js文件中的onReachBottom函数
{
"usingComponents":{},
"onReachBottomDistance":50,
}
后端接口
子应用的urls.py
from django.urls import path
from .views import random_view
urlpatterns =[
path('random/',random_view)
]
子应用的views.py
import json
from django.http import JsonResponse
def random_view(request):
l = []
for i in range(3):
l.append(random.randint(0.99999))
return JsonResponse(l,safe=False) #返回json格式,如果里面有列表,必须加safe=False
下拉刷新
goods.json
“enablePullDownRefresh”:true 表示开启下拉刷新
“backgroundColor”:“#efefef” 表示下拉刷新的背景颜色
“backgroundTextStyle”:“dark” 表示下拉刷新的小白点
{
"usingComponents":{},
"enablePullDownRefresh":true,
"backgroundColor":"#efefef",
"backgroundTextStyle":"dark"
}
goods.wxml
<view wx:for="{{good_list}}" wx:key:'*this'>{{item}}</view>
goods.js
onPullDownRefresh(){} 表示下拉刷新,是内置函数,必须这样写
Page({
data:{
good_list:[1,2,3]
}
// 下拉刷新
onPullDownRefresh(){
// ......下拉刷新之后要做的事情.......
console.log('下拉了,刷新')
// 只要下拉,把数据恢复
this.setData({
good_list:[1,2,3]
})
// 下拉刷新后.loading效果回弹
if(this.data.good_list.length==3){
wx.stopPullDownRefresh();
}
}
})
scroll-view实现上拉下拉
<scroll-view></scroll-view>
标签,使用该标签,必须要给该标签设置css样式:height:100vh;
该标签内的属性介绍:
scroll-y: 允许上下滑动
lower-threshold=“50” :距离底部50rpx的时候,触发滑动
bindscrolltolower=“handleGetData” :给滑动绑定事件处理函数
refresher-enabled=“true” 表示开启上拉
refresher-default-style=“black” 表示上拉刷新的颜色
refresher-background=“#f0f0f0” 表示上拉刷新的背景颜色
bindrefresherrefresh = “handleReloadData” 表示给上拉操作绑定事件处理函数
refresher-triggered=“{{isRefresh}}” 配合在js中的data定义isRefresh:false 以及在 下拉操作的方法最后设置this.setData({isRefresh:false}) 来实现下拉回弹
enable-back-to-top=“true” 表示: 在真机上,快速双击顶部标题,立即回到最顶上
goods2.wxml
<scroll-view class="scroll" scroll-y lower-threshold="50" bindscrolltolower="handleGetData" refresher-enabled="true" refresher-default-style="black" refresher-background="#f0f0f0" bindrefresherrefresh = "handleReloadData">
<view wx:for="{{good_list}}" wx:key:'*this'>{{item}}</view>
</scroll-view>
goods2.js
Page({
data:{
good_list:[1,2,3],
isRefresh:false
},
//
handleGetData(){
// 上拉 的事件处理逻辑
console.log('上拉了');
wx.request({
url:"http://127.0.0.1:8000/app01/random/",
method:"GET",
success:(res)=>{
this.setData({
good_list:this.data.good_list.concat(res.data)
})
}
})
},
// 下拉的操作
handleReloadData(){
Wx.showToast({
title:'下拉刷新了'
})
this.setData({
good_list:[1,2,3]
})
//隐藏掉下拉刷新
this.setData({
isRefresh:false
})
}
})
goods2.wxss
.scroll{
/* 100vh就是指元素的高度等于当前浏览器的视窗高度,即浏览器内部的可视区域的高度大小 */
height:100vh;
background-color:gray;
}
view{
height:400rpx;
dispaly:flex;
justify-content:center;
align-items:center;
}
// 奇数背景色是粉色
view:nth-child(odd){
background-color:pink;
}
// 偶数背景色绿色
view:nth-child(even){
background-color:rgb(17,133,88);
}
小程序强制更新
后续我们代码更新了,如果我们在微信端使用过小程序,微信会把小程序代码拉到微信本地,下次打开,会优先使用本地的代码,咱们代码更新了,需要强制更新到我们最新的代码
在app.js 加入如下代码,即可实现强制更新
App({
// 生命周期函数,启动小程序就会执行
onLaunch(){
const update=wx.getUpdateManager()
update.onUpdateReady(function(){
wx.showModal({
title: '发现新版本',
content: '重启应用,更新版本新版本?',
success:(res)=>{
if(res.confirm){
update.applyUpdate()
}
}
})
})
}
})
小程序的生命周期
整个应用的生命周期
app.js
// app.js
App({
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
console.log('小程序启动了')
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
console.log('后台切前台了')
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
console.log('进后台了')
},
})
某个页面的生命周期
index.js
Page({
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('1 页面加载了')
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
console.log('3 初次渲染完成')
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
console.log('2 页面显示')
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
console.log('4 页面隐藏')
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
console.log('5 页面卸载')
},
})
分享到朋友圈
假设想要将my页面分享到朋友圈
my.js
Page({
// 允许分享到朋友圈 onShareTimeline(){}固定内置函数
onShareTimeline(){
return {
title:'这是一个神奇的页面',
query:'name=justin&age=19',//带参数访问过来
inageUrl="/images/b.jpg"
}
}
})
Page({
// 允许分享到朋友 onShareAppMessage(){}固定内置函数
onShareAppMessage(){
return {
title:'是朋友就帮我点一下',
path:'/pages/my/my.json',//带参数访问过来
imageUrl:'/images/b.jpg'
}
}
})
另外一种转发方式
<button open-type="share">转发</button>
获取头像
index.wxml
open-type="chooseAvatar 固定属性写法
bindchooseavatar=“choosePhoto” :绑定获取头像事件
<!-- 获取用户头像 -->
<button class="btn" open-type="chooseAvatar" bindchooseavatar="choosePhoto">
<image src="{{photo}}" class="photo" />
</button>
index.js
Page({
data:{
photo:'/images/b.jpg'
},
// 获取头像
choosePhoto(event){
console.log(event);
this.setData({
photo:event.detail.avatarUrl
})
// 同时要把图片传到后端保存
}
})
index.wxss
.btn{
background-color:transparent;
}
.btn:after{
border:none;
}
.photo{
height:250rpx;
width:250rpx;
border-radius:50%
}
获取昵称
index.wxml
<!-- 获取昵称 -->
<!-- type必须是nickname -->
<input type="nickname" placeholder="输入或获取昵称" model:value="{{username}}" />
<button type="primary" plain bind:tap="showName">提交</button>
index.js
Page({
data:{
username:""
},
// 获取用户名
showName(){
// 获取输入框中的值
console.log(this.data.username)
}
})
index.wxss
input{
border:1rpx solid pink;
border-radius:10rpx;
padding:10rpx;
margin:10rpx;
}
获取手机号
快速登录,需要前后端配合,前端配合获取手机号带着code到后端,后端实现注册+登录接口,后端通过code去微信开发平台换取真正的手机号。后端检测用户表,这个用户有没有注册过,如果注册过,直接签发token登录成功,如果没有注册过,先注册,再签发token登录成功。
获取手机号,有两种方式。
手机号快速验证
就是小程序登录界面 有手机号快速登录的按钮
手机号实时验证
给用户手机发送验证码,输入验证码后,才能获取到手机号码
# 前提
# 1 手机号接口,必须是非个人开发者,并且完成了认证的小程序
# 2 两种验证方式需要付费使用,每个小程序账号有1000次体验额度
# 3 小程序端
# https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
代码案例
快速获取手机号,必须添加这两个属性:open-type="getPhoneNumber"
和 bindgetphonenumber="getPhoneNumber"
实时获取手机号,必须添加这两个属性:open-type="getRealtimePhoneNumber"
和 bindgetrealtimephonenumber="getRealPhoneNumber"
index.wxml
<button type="warn" open-type="getPhoneNumber"
bindgetphonenumber="getPhoneNumber">快速手机号</button>
<button type="default" plain open-type="getRealtimePhoneNumber"
bindgetrealtimephonenumber="getRealPhoneNumber"
>实时手机号</button>
index.js
Page({
getPhoneNumber(event){
console.log(event.detail.code);
wx.request({
url:'后端地址',
method:'POST',
data:{
code:event.detail.code
}
})
},
getRealPhoneNumber(event){
console.log(event);
}
})
客服功能
微信为小程序提供客服消息能力,以便小程序用户可以方便快捷地与小程序服务提供方进行沟通
https://developers.weixin.qq.com/miniprogram/introduction/custom.html
先在微信小程序的后台,添加客服人员
index.wxml
<!-- 客服 -->
<button type="default" plain open-type="contact">联系客服</button>
当用户点击该按钮,并且发送信息,微信小程序的后台的客服
管理界面就会收到用户的信息,并且可以回复。