当前位置:   article > 正文

微信小程序 之 原生开发_微信小程序原生开发

微信小程序原生开发

一、前期预备

1. 预备知识

小程序的核心技术主要是三个:

  • 页面布局:WXML,类似HTML
  • 页面样式:WXSS,几乎就是CSS(某些不支持,某些进行了增强,但是基本是一致的)
  • 页面脚本:JavaScript+WXS(WeixinScript)

2. 注册账号 - 申请AppID

网址 : 微信小程序

3. 下载小程序开发工具

网址 : 微信开发者工具下载地址与更新日志 | 微信开放文档

4. 小程序项目结构

5. 小程序的MVVM架构

Vue的MVVM和小程序MVVM对比

MVVM :  

  • DOM Listeners: ViewModel层可以将DOM的监听绑定到Model层
  • Data Bindings: ViewModel层可以将数据的变量, 响应式的反应到View层
  • MVVM架构将 命令式编程 转移到 声明式编程

二、创建小程序项目

1. 查看注册的appId

网址 : 小程序

2. 创建项目

3. 新建页面

01 - 创建text页面文件夹

02 - 新建text的page

03 - 在app.json中配置

可能会自动注册完成

ps : 也可以反向注册,在这里直接配置,文件夹会自动生成

4. 开发初体验

01 - text.wxml

  1. <!--pages/text/text.wxml-->
  2. <!-- 1. 普通文本 -->
  3. <view>text页面</view>
  4. <!-- 2. 数据绑定,使用 {{}} 这个语法 -->
  5. <view>{{message}}</view>
  6. <!-- 3. 列表渲染 -->
  7. <block wx:for="{{movies}}" wx:key="item">
  8. <view>item : {{item}} => index: {{index}}</view>
  9. </block>
  10. <!-- 4. 事件监听 -->
  11. <view style="text-align: center">当前计数 : {{counter}}</view>
  12. <button bindtap="increment">+1</button>
  13. <button bindtap="decrement">-1</button>

02 - text.js

直接修改data中的数据,不会引起页面的刷新

小程序和react中都不会,只有vue劫持了属性才能直接操作

 

ps : 修改data并且希望页面重新渲染,必须使用 this.setData()

  1. // pages/text/text.js
  2. Page({
  3. /**
  4. * 页面的初始数据
  5. */
  6. data: {
  7. // 1. 数据绑定,{{}} 语法
  8. message: 'star',
  9. // 2. 列表渲染数据
  10. movies: ['迪迦大战肯德基', '图图和小新抢东西吃'],
  11. // 3. 计数器参数
  12. counter: 0
  13. },
  14. // 监听计数器增加按钮触发
  15. increment() {
  16. // 此方法修改后的数据不会在页面上响应
  17. // this.data.counter += 1
  18. this.setData({
  19. counter: this.data.counter + 1
  20. })
  21. },
  22. // 监听计数器减少按钮触发
  23. decrement() {
  24. this.setData({
  25. counter: this.data.counter - 1
  26. })
  27. },
  28. })

03 - 效果

三、小程序的架构和配置

1. 小程序的架构模型

01 - 宿主环境

小程序的宿主环境   =>   微信客户端

 

ps :  宿主环境为了执行小程序的各种文件:wxml文件、wxss文件、js文件

02 - 双线程模型

  • 当小程序基于 WebView 环境下时,WebView 的 JS 逻辑、DOM 树创建、CSS 解析、样式计算、Layout、Paint (Composite) 都发生在同一线程,在 WebView 上执行过多的 JS 逻辑可能阻塞渲染,导致界面卡顿
  • 以此为前提,小程序同时考虑了性能与安全,采用了目前称为「双线程模型」的架构

双线程模型 : 

  • WXML模块和WXSS样式运行于 渲染层,渲染层使用WebView线程渲染(一个程序有多个页面,会使用多个WebView的线程)
  • JS脚本(app.js/home.js等)运行于 逻辑层,逻辑层使用JsCore运行JS脚本
  • 这两个线程都会经由微信客户端(Native)进行中转交互
  • 注 : wxs是和渲染层呆在一起的

2. 小程序的配置文件

01 - project.config.json

项目配置文件   =>   比如项目名称、appid等

 

网址 : 项目配置文件 | 微信开放文档

02 - sitemap.json

小程序搜索相关的

 

网址 : sitemap 配置 | 微信开放文档

03 - app.json

全局配置

 

网址 : 全局配置 | 微信开放文档

        代码

  1. {
  2. "pages": [
  3. // 默认显示的页面
  4. "pages/text/text",
  5. "pages/index/index",
  6. "pages/logs/logs"
  7. ],
  8. "window": {
  9. // 下拉 loading 的样式,仅支持 dark 黑色 / light 白色
  10. // 需要到页面的.json中加入 "enablePullDownRefresh": true , 开启即可
  11. // 最好别在全局开启下拉刷新
  12. "backgroundTextStyle": "dark",
  13. // 导航栏背景颜色
  14. "navigationBarBackgroundColor": "#f00",
  15. // 导航栏标题文字内容
  16. "navigationBarTitleText": "Weixin",
  17. // 导航栏标题颜色,仅支持 black / white
  18. "navigationBarTextStyle": "black"
  19. },
  20. // 底部导航按钮
  21. "tabBar": {
  22. // 文字默认的颜色
  23. "color":"#fff",
  24. // 选中时文字的颜色
  25. "selectedColor":"#ff8189",
  26. // 导航是一个数组
  27. "list": [
  28. {
  29. // 页面路径
  30. "pagePath": "pages/index/index",
  31. // 文本
  32. "text": "首页",
  33. // 默认显示的图标
  34. "iconPath": "assets/images/tabbar/home.png",
  35. // 选中时显示的图标
  36. "selectedIconPath": "assets/images/tabbar/home_active.png"
  37. },
  38. {
  39. "pagePath": "pages/text/text",
  40. "text": "记录",
  41. "iconPath": "assets/images/tabbar/category.png",
  42. "selectedIconPath": "assets/images/tabbar/category_active.png"
  43. }
  44. ]
  45. },
  46. // 表明启用新版的组件样式
  47. "style": "v2",
  48. // 配置搜索相关文件,基本不需更改
  49. "sitemapLocation": "sitemap.json"
  50. }

        效果

04 - (page).json

页面配置

每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置

页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项

网址 : 页面配置 | 微信开放文档

        代码

  1. {
  2. // 是否使用组件
  3. "usingComponents": {
  4. // 需要在这里配置
  5. },
  6. // 页面顶部标题文字
  7. "navigationBarTitleText": "冲啊",
  8. // 页面顶部标题颜色
  9. "navigationBarTextStyle": "white",
  10. // 页面顶部背景颜色
  11. "navigationBarBackgroundColor": "#0f0",
  12. // 是否开启下拉刷新
  13. // Page.js 中,onPullDownRefresh 开启这个,可以监听到是否下拉刷新了
  14. "enablePullDownRefresh": true,
  15. }

        效果

四、注册小程序 – App函数 - app.js

每个小程序都需要在 app.js 中调用 App 函数 注册小程序示例

 

网址 : App(Object object) | 微信开放文档

  • 在注册时, 可以绑定对应的生命周期函数
  • 在生命周期函数中, 执行对应的代码

注册App时,一般做如下事情 : 

  • 监听生命周期函数,在生命周期中执行对应的业务逻辑,比如在某个生命周期函数中进行登录操作或者请求网络数据
  • 判断小程序的进入场景
  • 因为App()实例只有一个,并且是全局共享的(单例对象),所以我们可以将一些共享数据放在这里

作用一 : 判断打开场景

01 - 常见场景

小程序的打开场景较多 : 

02 - 确定场景

在 onLaunch 和 onShow 生命周期回调函数中,会有options参数,其中有scene值

        代码

  1. // app.js
  2. App({
  3. /**
  4. * 生命周期回调——监听小程序初始化。
  5. * 小程序初始化时触发,只有执行一次
  6. */
  7. onLaunch(options) {
  8. console.log('onLaunch =>', 'scene :', options.scene);
  9. // 登录
  10. wx.login({
  11. success: res => {
  12. // 发送 res.code 到后台换取 openId, sessionKey, unionId
  13. }
  14. })
  15. },
  16. /**
  17. * 生命周期回调——监听小程序启动或切前台
  18. * 每次打开小程序都会执行
  19. */
  20. onShow(options) {
  21. console.log('onShow =>', 'scene :', options.scene);
  22. // 可根据场景值,跳转到对应的页面
  23. wx.navigateTo({
  24. // url: 'url',
  25. })
  26. },
  27. onHide() {
  28. console.log('onHide => 隐藏~');
  29. }
  30. })

        效果

作用二 : 定义全局App的数据

注意 : 定义在全局的数据不会响应式

 

共享的数据通常是一些固定的数据

app.js

  1. // app.js
  2. App({
  3. // 定义的全局变量
  4. globalData: {
  5. token: '',
  6. userInfo: {
  7. name: 'coder',
  8. age: 18
  9. }
  10. },
  11. // 页面初始化调用的回调函数
  12. onLaunch(options) {
  13. // 登录
  14. wx.login({
  15. success: res => {
  16. console.log('code =>', res.code);
  17. // 发送 res.code 到后台换取 openId, sessionKey, unionId
  18. this.globalData.token = res.token || 'abcdefghijklmnopqrstuvwxyz'
  19. }
  20. })
  21. }
  22. })

page.js

  1. // pages/text/text.js
  2. Page({
  3. // 页面加载的时候触发
  4. /**
  5. * 获取页面所需数据
  6. */
  7. onLoad() {
  8. // 获取共享的数据
  9. // 1. 获取app实例对象
  10. const app = getApp()
  11. // 2. 从app实例对象中获取数据
  12. const token = app.globalData.token
  13. const userInfo = app.globalData.userInfo
  14. console.log('userInfo :', userInfo);
  15. console.log('token :', token);
  16. // 3. 拿到token后发送网络请求
  17. // wx.request({
  18. // url: 'url',
  19. // token
  20. // })
  21. // 4. 展示数据到页面
  22. this.setData({
  23. userInfo
  24. })
  25. },
  26. /**
  27. * 页面的初始数据
  28. */
  29. data: {
  30. userInfo: {}
  31. },
  32. })

效果

作用三 : 生命周期函数 

在生命周期函数中,完成应用程序启动后的初始化操作

  • 比如登录操作
  • 比如读取本地数据(类似于token,然后保存在全局方便使用)
  • 比如请求整个应用程序需要的数据 

这里简单写写,详细的登录操作在下方

  1. // app.js
  2. App({
  3. // globalData
  4. globalData: {
  5. userState: {
  6. openId: '',
  7. sessionKey: '',
  8. unionId: ''
  9. },
  10. userInfo: {}
  11. },
  12. // 页面初始化调用的回调函数
  13. onLaunch(options) {
  14. // 从本地获取用户状态信息,判断是否需要登录
  15. const userState = wx.getStorageSync('userState')
  16. // 如果不存在,则进行登录
  17. if (!userState || !userState.openId) {
  18. wx.login({
  19. success: res => {
  20. console.log('code =>', res.code);
  21. // 发送 res.code 到后台换取 openId, sessionKey, unionId
  22. this.getUserState(res.code)
  23. }
  24. })
  25. }
  26. },
  27. // 获取用户信息
  28. getUserState(code) {
  29. wx.request({
  30. // 填入请求地址
  31. url: 'url',
  32. code,
  33. success: (res) => {
  34. const { openId, unionId, sessionKey, userInfo } = res
  35. // 将登录成功的数据,保存在storage中
  36. wx.setStorageSync('userState', {
  37. openId,
  38. unionId,
  39. sessionKey,
  40. })
  41. wx.setStorageSync('userInfo', userInfo)
  42. // 将登录成功的数据,保存在globalData中
  43. this.globalData.userState = {
  44. openId,
  45. unionId,
  46. sessionKey,
  47. }
  48. this.globalData.userInfo = userInfo
  49. }
  50. })
  51. //
  52. }
  53. })

五、注册页面 – Page函数 - (page).js

小程序中的每个页面, 都有一个对应的js文件, 其中调用 Page函数 注册页面示例

 

网址 : Page(Object object) | 微信开放文档

  • 在注册时, 可以绑定初始化数据、生命周期回调、事件处理函数等

注册Page页面时,一般做如下事情 : 

  • 在生命周期函数中发送网络请求,从服务器获取数据
  • 初始化一些数据,以方便被wxml引用展示
  • 监听wxml中的事件,绑定对应的事件函数
  • 其他一些监听(比如页面滚动、上拉刷新、下拉加载更多等)

0. 生命周期

网址 : 生命周期 | 微信开放文档

1. 发送网络请求

  1. // logs.js
  2. Page({
  3. data: {
  4. pagaData: {}
  5. },
  6. // 页面加载时促发
  7. onLoad() {
  8. const _this = this
  9. // 发送网络请求
  10. wx.request({
  11. url: 'www.baidu.com',
  12. success: (res) => {
  13. console.log(this, res);
  14. this.setData({
  15. pagaData: res.pagaData || {}
  16. })
  17. },
  18. error(err) {
  19. console.log(_this, err);
  20. }
  21. })
  22. }
  23. })

2. 初始数据

  1. // logs.js
  2. Page({
  3. data: {
  4. // 定义初始化数据
  5. movies: ['葫芦娃大战喜羊羊', '蜡笔小新殴打图图'],
  6. },
  7. // 页面加载时促发
  8. onLoad() { }
  9. })

3. 绑定事件函数

wxml

  1. <!--logs.wxml-->
  2. <view>
  3. <button bindtap="handClick">事件触发</button>
  4. <button>------</button>
  5. <button bindtap="clickQuery"
  6. data-query="abc">触发并传递参数</button>
  7. <button>------</button>
  8. <button wx:for="{{btns}}"
  9. wx:key="*this"
  10. bindtap="btnsClick"
  11. data-index="{{index}}"
  12. data-item="{{item}}"
  13. style="background-color: {{item}};">
  14. {{item}} - {{index}}
  15. </button>
  16. </view>

js

  1. // logs.js
  2. Page({
  3. data: {
  4. // 定义初始化数据
  5. btns: ['red', 'blue', 'green', 'pink', 'yellow'],
  6. },
  7. // 页面加载时促发
  8. onLoad() { },
  9. // 绑定事件
  10. handClick() {
  11. console.log('我被点击了');
  12. },
  13. // 传递参数
  14. clickQuery(e) {
  15. console.log('我被点击了,参数是 : ', e.target.dataset);
  16. },
  17. btnsClick(e) {
  18. console.log('循环出的按钮', e.target.dataset);
  19. }
  20. })

4. 其他的监听

01 - 下拉刷新

        logs.json

  1. {
  2. "usingComponents": {},
  3. // 开启下拉刷新
  4. "enablePullDownRefresh": true
  5. }

        logs.js

  1. // logs.js
  2. Page({
  3. data: {
  4. },
  5. // 监听用户下拉刷新
  6. onPullDownRefresh() {
  7. console.log('用户下拉刷新');
  8. // 模拟网络请求
  9. setTimeout(() => {
  10. // api: 停止下拉刷新
  11. wx.stopPullDownRefresh({
  12. success: (res) => {
  13. console.log('成功关闭下拉刷新', res);
  14. },
  15. fail: (err) => {
  16. console.log('关闭失败', err);
  17. }
  18. })
  19. }, 1000);
  20. }
  21. })

        效果

02 - 上拉加载更多

        logs.json

  1. {
  2. "usingComponents": {},
  3. // 页面上拉触底事件触发时距页面底部距离,单位为px
  4. // 距离底部多少距离,触发
  5. "onReachBottomDistance": 100
  6. }

        logs.js

  1. // logs.js
  2. Page({
  3. data: {
  4. // 默认展示50条数据
  5. countsNum: 50,
  6. // 到达底部后,需要增加的数量
  7. countsSize: 40
  8. },
  9. // 监听页面是否滚动到达底部
  10. onReachBottom() {
  11. this.setData({
  12. // 到达底部后,增加
  13. countsNum: this.data.countsNum + this.data.countsSize
  14. })
  15. console.log('滚动到底部');
  16. }
  17. })

        logs.wxml

  1. <!--logs.wxml-->
  2. <view wx:for="{{countsNum}}" wx:key="*this">
  3. 页面数据 : {{item}}
  4. </view>

        效果

03 - 页面滚动

  1. // logs.js
  2. Page({
  3. data: {
  4. // 定义初始化数据
  5. btns: ['red', 'blue', 'green', 'pink', 'yellow'],
  6. },
  7. // 页面加载时促发
  8. onLoad() { },
  9. // 页面滚动
  10. onPageScroll(e) {
  11. console.log(e); // 距离顶部的距离
  12. },
  13. })

六、常见的内置组件

Text : 文本组件

Text组件 : 用于显示文本, 类似于span标签, 是行内元

text | 微信开放文档

  1. <!-- 基本用法 -->
  2. <text>Hello world</text>
  3. <!-- 使用js中定义的数据 -->
  4. <text>{{message}}</text>
  5. <!-- 长按可选择,可用来复制 -->
  6. <text user-select>{{message}}</text>
  7. <!-- 解码 -->
  8. <text decode>&gt;</text>

Button : 按钮组件

Button组件用于创建按钮,默认块级元素

button | 微信开放文档

基本用法

  1. <!-- 默认 => 独占一行 -->
  2. <button>按钮</button>
  3. <!-- size属性 => 变成了inline-block -->
  4. <button size="mini">size属性</button>
  5. <!-- type属性 => 可更改背景、颜色 -->
  6. <button size="mini"
  7. type="default">文字颜色变绿</button>
  8. <button size="mini"
  9. type="primary">背景颜色变绿</button>
  10. <button size="mini"
  11. type="warn">文字颜色变红</button>
  12. <!-- plain => 镂空效果 -->
  13. <button size="mini"
  14. plain> 镂空效果,有边框 </button>
  15. <!-- 禁用 -->
  16. <button size="mini"
  17. disabled> 禁止交互 </button>
  18. <!-- 加载效果 => 前方有个小圆圈在转,可动态绑定 -->
  19. <button size="mini"
  20. loading='{{true}}'> 等待加载 </button>

open-type属性

open-type用户获取一些特殊性的权限,可以绑定一些特殊的事件

        获取用户信息

                wxml

  1. <!-- 获取用户信息 -->
  2. <button bindtap="getUserProfile">获取用户信息</button>

                js

  1. Page({
  2. getUserProfile(e) {
  3. // 推荐使用 wx.getUserProfile 获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
  4. // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
  5. wx.getUserProfile({
  6. desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
  7. // 点击允许
  8. success: (res) => {
  9. console.log('success', res);
  10. },
  11. // 点击拒绝
  12. fail: (err) => {
  13. console.log('fail', err);
  14. }
  15. })
  16. }
  17. })

        获取用户手机

                wxml

  1. <!-- 获取用户手机号 -->
  2. <button open-type="getPhoneNumber"
  3. bindgetphonenumber="getPhoneNumber">获取用户手机号</button>

                js

  1. Page({
  2. getPhoneNumber(e) {
  3. // 如果点击了拒绝
  4. if (e.target.errMsg !== 'getPhoneNumber:ok') {
  5. return wx.showToast({
  6. title: '用户未同意授权手机号',
  7. icon: 'none'
  8. })
  9. }
  10. // 如果点击确认
  11. cosnt { code, encryptedData, iv } = e.target
  12. // 把数据传给后端,后端会去解密拿到手机号的
  13. wx.request({
  14. url: 'https://example.com/onLogin',
  15. data: {
  16. appId: '',
  17. openId: '',
  18. code,
  19. encryptedData,
  20. iv
  21. },
  22. method: "post",
  23. success: function (res) {
  24. console.log(res);
  25. }
  26. })
  27. }
  28. })

View : 视图组件

View视图组件 : 块级元素,独占一行,通常用作容器组件,和div差不多

view | 微信开放文档

ScrollView滚动组件

scroll-view : 可以实现局部滚动

scroll-view | 微信开放文档

上下滚动

        wxml

  1. <!-- 固定高度,上下滚动,( y轴 : scroll-y ) -->
  2. <scroll-view class="contain scroll-y"
  3. scroll-y
  4. bindscrolltoupper="scrollTop"
  5. bindscrolltolower="scrollBottom"
  6. bindscroll='scrollIng'>
  7. <block wx:for="{{viewColors}}"
  8. wx:key="*this">
  9. <view class="box"
  10. style="background-color: {{item}}">
  11. {{item}}
  12. </view>
  13. </block>
  14. </scroll-view>

        css

  1. .contain {
  2. height: 300px;
  3. }
  4. .box {
  5. height: 100px;
  6. color: white;
  7. font-weight: bold;
  8. }

        js

  1. Page({
  2. data: {
  3. viewColors: ['red', 'pink', 'green', 'blue']
  4. },
  5. scrollTop() {
  6. console.log('到达顶部');
  7. },
  8. scrollBottom() {
  9. console.log('到达底部');
  10. },
  11. // 滚动中触发
  12. scrollIng({ detail }) {
  13. console.log(detail);
  14. }
  15. })

左右滚动

注 : 若要开启flex布局,须加上enable-flex这个属性

        wxml

  1. <!-- 固定宽度,左右滚动,( x轴 : scroll-x ) -->
  2. <scroll-view class="contain scroll-x"
  3. scroll-x
  4. enable-flex
  5. bindscrolltoupper="scrollLeft"
  6. bindscrolltolower="scrollRight"
  7. bindscroll='scrollIng'>
  8. <block wx:for="{{viewColors}}"
  9. wx:key="*this">
  10. <view class="box"
  11. style="background-color: {{item}}">
  12. {{item}}
  13. </view>
  14. </block>
  15. </scroll-view>

        css

  1. .contain {
  2. display: flex;
  3. }
  4. .box {
  5. /* 不压缩 */
  6. flex-shrink: 0;
  7. width: 150px;
  8. height: 150px;
  9. color: white;
  10. font-weight: bold;
  11. }

        js 

  1. Page({
  2. data: {
  3. viewColors: ['red', 'pink', 'green', 'blue']
  4. },
  5. scrollLeft() {
  6. console.log('到达左侧');
  7. },
  8. scrollRight() {
  9. console.log('到达右侧');
  10. },
  11. // 滚动中触发
  12. scrollIng({ detail }) {
  13. console.log(detail);
  14. // detail.deltaX > 0,往左滚动
  15. // detail.deltaX < 0,往右滚动
  16. }
  17. })

Image : 图片组件

Image组件 : 用于显示图片

image | 微信开放文档

基本使用 

  1. <!-- image : 默认自带宽度和高度 => 320 * 240 -->
  2. <!-- 根目录 : / 表示根目录,有些地方能用,有些不行 -->
  3. <!-- <image src="/assets/images/zznh.png" /> -->
  4. <!-- 加载本地图片 -->
  5. <image src="../../assets/images/zznh.png" />
  6. <!-- 加载网络图片 -->
  7. <image src="https://uploadfile.bizhizu.cn/up/9d/8d/1e/9d8d1e3fba7895d13a639f464ef147b1.jpg.source.jpg" />
  8. <!-- 使用mode属性 -->
  9. <image src="../../assets/images/zznh.png" mode="widthFix" />

使用手机本地图片 wx.chooseMedia

        wxml

  1. <!-- 选择手机本地图片,将本地图片展示出来 -->
  2. <button bindtap="choseImage"
  3. type="primary">进入相册选择图片</button>
  4. <image wx:if="{{imgUrl}}"
  5. src="{{imgUrl}}"
  6. style="width: 100%;"
  7. mode="widthFix" />

        js 

  1. Page({
  2. data: {
  3. imgUrl: ''
  4. },
  5. choseImage() {
  6. // 选择本地图片
  7. wx.chooseMedia({
  8. // 最多可以选择的文件个数
  9. count: 1,
  10. // 只能拍摄图片或从相册选择图片
  11. mediaType: 'image',
  12. }).then(res => {
  13. if (res.errMsg !== 'chooseMedia:ok') return
  14. console.log(res);
  15. const imageList = res.tempFiles || []
  16. const imgUrl = imageList[0].tempFilePath || ''
  17. this.setData({
  18. imgUrl
  19. })
  20. })
  21. }
  22. })

Swiper : 组件

Swiper组件 => 用来做轮播图效果

swiper | 微信开放文档

        简单轮播

                效果

                 wxml

  1. <view>
  2. <!--
  3. circular : 是否开启衔接滑动
  4. autoplay : 自动轮播
  5. interval : 多少秒轮播一次
  6. duration : 显示多长时间
  7. -->
  8. <swiper class="s-swiper"
  9. autoplay
  10. circular
  11. interval="1000"
  12. duration="500">
  13. <block wx:for="{{swiperData}}"
  14. wx:key="index">
  15. <swiper-item class="s-item"
  16. style="background-color: {{item.color}};">
  17. {{item.text}}
  18. </swiper-item>
  19. </block>
  20. </swiper>
  21. </view>

                wxss 

  1. .s-swiper {
  2. /* 注意 : swiper默认有个150px的高度 */
  3. height: 300rpx;
  4. }
  5. .s-item {
  6. color: #fff;
  7. font-weight: 800;
  8. text-align: center;
  9. line-height: 300rpx;
  10. }

                js 

  1. Page({
  2. data: {
  3. // 轮播数据
  4. swiperData: [{
  5. text: 'A',
  6. color: 'green'
  7. },
  8. {
  9. text: 'B',
  10. color: 'black'
  11. },
  12. {
  13. text: 'C',
  14. color: 'skyblue'
  15. },
  16. {
  17. text: 'D',
  18. color: 'pink'
  19. },
  20. {
  21. text: 'E',
  22. color: 'blue'
  23. }],
  24. }
  25. })

        前露后露轮播

                 效果 

                wxml

  1. <view>
  2. <!--
  3. circular : 是否开启衔接滑动
  4. autoplay : 自动轮播
  5. previous-margin : 露出多少前部分
  6. next-margin : 露出多少后部分
  7. interval : 多少秒轮播一次
  8. duration : 显示多长时间
  9. -->
  10. <swiper class="s-swiper"
  11. autoplay
  12. circular
  13. previous-margin="50rpx"
  14. next-margin="50rpx"
  15. interval="1000"
  16. duration="500"
  17. bindchange="handleChange">
  18. <block wx:for="{{swiperData}}"
  19. wx:key="index">
  20. <swiper-item class="s-item">
  21. <view class="content {{currentIndex === index ? 'active' : ''}}"
  22. style="background-color: {{item.color}};">
  23. {{item.text}}
  24. </view>
  25. </swiper-item>
  26. </block>
  27. </swiper>
  28. </view>

                wxss 

  1. .s-swiper {
  2. /* 注意 : swiper默认有个150px的高度 */
  3. height: 300rpx;
  4. margin-top: 20rpx;
  5. }
  6. .s-item {
  7. /* 用来做间距的颜色 */
  8. background-color: #fff;
  9. display: flex;
  10. /* 使其居中 */
  11. justify-content: center;
  12. }
  13. .content {
  14. /* 重要 */
  15. width: 100%;
  16. color: #fff;
  17. font-weight: 800;
  18. text-align: center;
  19. line-height: 300rpx;
  20. /* 加入动画 */
  21. transform: scale(.9);
  22. transition: transform .6s ease-in-out 0s;
  23. }
  24. .active {
  25. transform: scale(1);
  26. }

                js 

  1. Page({
  2. data: {
  3. // 轮播数据
  4. swiperData: [{
  5. text: 'A',
  6. color: 'green'
  7. },
  8. {
  9. text: 'B',
  10. color: 'black'
  11. },
  12. {
  13. text: 'C',
  14. color: 'skyblue'
  15. },
  16. {
  17. text: 'D',
  18. color: 'pink'
  19. },
  20. {
  21. text: 'E',
  22. color: 'blue'
  23. }],
  24. // 当前轮播模块索引
  25. currentIndex: 0
  26. },
  27. /**
  28. * 监听方法
  29. */
  30. // 轮播图滚动
  31. handleChange(e) {
  32. this.setData({
  33. currentIndex: e.detail.current
  34. })
  35. }
  36. })

Input : 组件

model:value => 双向绑定功能

wxml

<input type="text" model:value='{{message}}' />

js

  1. Page({
  2. data: {
  3. message: 'abc'
  4. },
  5. })

组件的共同属性

七、小程序基础语法

1. Wxss

01 - 样式写法

页面样式的三种写法:行内样式、页面样式、全局样式

优先级依次是:行内样式 > 页面样式 > 全局样式

02 - 选择器

权重

03 - 尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应,规定屏幕宽为750rpx

在iphone6上,屏幕宽度为375px,共有750个物理像素,1px === 2rpx

iphone6为标准,设计稿是375,1px === 2rpx  => 设计稿16px,我们写32rpx

iphone6为标准,设计稿是750,1px === 1rpx  => 设计稿20px,我们写20rpx

  1. .view {
  2. /* 在375的设计稿中,200rpx === 100px */
  3. width: 200rpx;
  4. height: 200rpx;
  5. background-color: blue;
  6. line-height: 200rpx;
  7. text-align: center;
  8. color: #fff;
  9. }

2. Wxml

01 - 逻辑判断

wx:if --- wx:elif --- wx:else

  1. <view>
  2. <text wx:if="{{counter >= 90}}">优秀</text>
  3. <text wx:elif='{{counter >= 60}}'>及格</text>
  4. <text wx:else>不及格</text>
  5. </view>

02 - hidden

hidden属性:

  • hidden是所有的组件都默认拥有的属性
  • 当hidden属性为true时, 组件会被隐藏
  • 当hidden属性为false时, 组件会显示出来

hidden和wx:if的区别

hidden => 控制隐藏和显示是控制是否添加hidden属性,相当于display:none

wx:if => 是控制组件是否渲染的

03 - block

block : 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

  • 将需要进行遍历或者判断的内容进行包裹
  • 将遍历和判断的属性放在block便签中,不影响普通属性的阅读,提高代码的可读性 

04 - 列表渲染

        wx:for

index : 遍历后在wxml中可以使用一个变量index,保存的是当前遍历数据的下标值

item : 数组中对应某项的数据

  1. <!-- 遍历一个数组 => a,b,c -->
  2. <view wx:for="{{['a','b','c']}}"
  3. wx:key="*this">{{item}} --- {{index}}</view>
  4. <!-- 遍历一个字符串 => p,o,i,p,o,i -->
  5. <view wx:for="{{'poipoi'}}"
  6. wx:key="item">{{item}} --- {{index}}</view>
  7. <!-- 遍历数字 => 0 - 9 -->
  8. <view wx:for="{{10}}"
  9. wx:key="*this">{{item}} --- {{index}}</view>

        item - index

wx:for-item = ' '    =>   item 重命名

wx:for-index = ' '  =>   index 重命名

  1. <view wx:for="{{['a','b','c']}}"
  2. wx:for-item='str'
  3. wx:for-index='key'
  4. wx:key="*this">{{str}} --- {{key}}</view>

        key

使用wx:for时,可以添加一个key来提供性能

wx:key 的值以两种形式提供 :

  • 字符串  =>  代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能 动态改变
  • 保留关键字 *this  =>  代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字 

3. Wxs

01 - 概念

WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构

为什么要设计WXS语言

  • 在WXML中是不能直接调用Page/Component中定义的函数的 (  底层没有进行封装 )
  • 但是某些情况, 我们可以希望使用函数来处理WXML中的数据(类似于Vue中的过滤器),这个时候就使用WXS了

WXS使用的限制和特点 : 

  • WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行
  • WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序 提供的API
  • 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备 上二者运行效率 无差异
  • 最好使用ES6之前的语法,否则可能会有问题

02 - 写法

WXS有两种写法  :写在标签中 || 写在以.wxs结尾的文件中

WXS标签的属性 : 

wxs : 

  • 每一个 .wxs 文件和 标签都是一个单独的模块
  • 每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见
  • 一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现 

        写法一 : 直接写在标签内

  1. <!-- 1. 定义wxs标签,设定模块名 -->
  2. <wxs module="format">
  3. // 2. 定义函数
  4. function priceFormat(price) {
  5. return price + '元'
  6. }
  7. // 3. 导出 : 必须导出后,才能被使用,且必须被CommonJs导出
  8. module.exports = {
  9. priceFormat: priceFormat
  10. }
  11. </wxs>
  12. <!-- 4. 使用 : 使用模块名.函数 => 进行使用 -->
  13. <view wx:for="{{['111','222','333']}}"
  14. wx:for-item='money'
  15. wx:for-index='key'
  16. wx:key="*this">{{format.priceFormat(money)}}</view>
  17. <!-- 5. 输出 : 111元、222元、333元 -->

        写法二 : 独立的文件,通过src引入

                定义format.wxs

  1. // 1. 定义函数
  2. function priceFormat(price) {
  3. return price + '元'
  4. }
  5. // 2. 导出 : 必须导出后,才能被使用,且必须被CommonJs导出
  6. module.exports = {
  7. priceFormat: priceFormat
  8. }

                wxml

  1. <!-- 3. 定义wxs标签,设定模块名,引入wxs文件 -->
  2. <wxs module="format" src='./format.wxs' />
  3. <!-- 4. 使用 : 使用模块名.函数 => 进行使用 -->
  4. <view wx:for="{{['111','222','333']}}"
  5. wx:for-item='money'
  6. wx:for-index='key'
  7. wx:key="*this">{{format.priceFormat(money)}}</view>
  8. <!-- 5. 输出 : 111元、222元、333元 -->

4. setData

['对象.属性']: 修改的值

01 - 对象

  1. data: {
  2. dataObj: {
  3. name: 'aaa',
  4. age:15
  5. }
  6. }
  7. // 修改对象的属性
  8. this.setData({
  9. ['dataObj.age']: 77
  10. })
  11. // 删除对象的属性
  12. delete this.data.dataObj.age
  13. this.setData({
  14. dataObj: this.data.dataObj
  15. })

02 - 数组

  1. data: {
  2. arr: [{
  3. name: '123'
  4. }, {
  5. name: 'abc'
  6. }]
  7. }
  8. // 修改第二个元素的属性
  9. const index = 2
  10. this.setData({
  11. [`arr[${index}].name`]: '555'
  12. })
  13. // 删除某个数组元素
  14. this.data.dataList.splice(index, 1)
  15. this.setData({
  16. dataList: this.data.dataList
  17. })

八、小程序的事件处理

1. 组件事件类型

某些组件会有自己特性的事件类型

input : bindinput  ||  bindblur  ||  bindfocus

scroll-view : bindscrolltowpper  ||  bindscrolltolower

2. 事件对象event

当某个事件触发时, 会产生一个事件对象, 并且这个对象被传入到回调函数中

01 - currentTarget && target

target : 触发事件的元素

currentTarget : 处理事件的元素(大部分情况使用target)

        wxml

  1. <view id="outer" class="outer" bindtap="outerClick">
  2. <view id="inner" class="inner">
  3. </view>
  4. </view>

        wxss

  1. .outer {
  2. width: 400rpx;
  3. height: 400rpx;
  4. background-color: #0f0;
  5. display: flex;
  6. justify-content: center;
  7. align-items: center;
  8. margin: 100rpx auto;
  9. }
  10. .inner {
  11. width: 150rpx;
  12. height: 150rpx;
  13. background-color: #00f;
  14. }

        js

  1. Page({
  2. outerClick(e) {
  3. console.log(e);
  4. // target : 触发事件的元素 => 点击的是蓝色,所以 target === inner
  5. console.log('target:', e.target);
  6. // currentTarget : 处理事件的元素 => 冒泡到外层了,所以 currentTarget === outer
  7. console.log('currentTarget:', e.currentTarget);
  8. }
  9. })

02 - touches && changedTouches

touches : 当前屏幕上有多少个手指

changedTouches : 较上一个状态,改变了多少个手指

        区别一 : touchend中不同

        区别二 : 多手指触摸时不同

03 - 事件参数的传递

方式一  :  使用data-*

方式二  :  使用mark ( 2.7.1版本以上 )  =>    事件 | 微信开放文档

data- : 需要区分currnetTarget 和 target,一般使用currnetTarget即可

mark : 会自动合并所有的mark数据,不受影响

        wxml

  1. <view id="outer"
  2. class="outer"
  3. bindtap="outerClick"
  4. data-name='coder'
  5. data-age='18'
  6. mark:address='地球
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/423012
    推荐阅读
    相关标签