新手入门:小程序架构快速上手

目录

新建项目和配置

项目基本结构

新建小程序页面

修改项目首页

全局配置

窗口

tabBar

页面配置

小程序基本语法

wxml

数据绑定

条件渲染

列表渲染

wxss

wxss 对比 css

rpx

@import

全局样式和局部样式

js

wxs

数据请求

get和post请求

小程序和跨域

小程序和Ajax

小程序API的 Promise 化

最后


前言

随着微信小程序的推出,小程序逐渐成为了一个热门话题。各大平台相继推出了自己的小程序框架,如支付宝小程序、百度智能小程序等。它们以其便捷的用户体验、无需下载安装即可使用的特性,受到了广大用户的喜爱。因此,学会如何开发一款小程序,不仅能够提升个人的技术能力,还能为未来的职业发展打开新的窗口。

新建项目和配置

项目基本结构

创建一个微信小程序项目,目录结构如下:

- pages: 存放所有小程序的页面
- utils:存放工具性质的模块
- app.js:小程序入口文件
- app.json:小程序全局配置文件。包含小程序所有页面路径、窗口外观、界面表现(所有页面的背景色、文字颜色、小程序组件所使用的样式版本)、底部tab
- project.config.json:项目配置文件。记录我们对小程序开发工具做的个性化配置,如项目名、小程序账号ID、编译相关配置(ES6转ES5、上传代码时自动压缩混淆、上传代码时样式自动补全)
- sitemap.json:配置小程序及其页面是否允许被微信索引。微信现已开放了小程序内搜索,类似网页的SEO。

小程序官方建议所有小程序页面都放在 pages 目录中,以单独文件夹存放:

- pages
  - index
    - index.js 页面脚本
    - index.wxml 页面结构
    - index.wxss 页面样式
    - index.json 当前页面的配置,如窗口的外观
  - pageb
    - pageb.js
    - pageb.wxml
    - pageb.wxss
    - pageb.json

Tip:小程序中有4种json配置文件(具体作用后面会介绍)

  • 项目根目录中的 app.json

  • 项目根目录中的 project.config.json

  • 项目根目录中的 sitemap.json

  • 每个页面文件夹中的 json

新建小程序页面

在 app.json->pages 中新增页面存放路径,ctrl+s保存,工具会自动创建对应页面文件。

{
  pages: [
    "pages/index/index",
    "pages/pageb/pageb",
  + "pages/pageb/pagec"
  ]
}
修改项目首页

只需调整 app.json->pages 数组中页面路径的顺序,小程序会把排在第一位的页面,当做项目首页渲染。

全局配置

小程序根目录下的 app.json 是小程序全局配置文件。

常用配置:

  • pages 记录当前小程序所有页面的存放路径

  • window 全局设置小程序窗口外观

  • tabBar 设置小程序底部的 tabBar 效果

  • style 是否启用新版的组件样式

示例:

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window": {
    "navigationBarTitleText": "小程序示例",
    "navigationBarBackgroundColor": "#ffffff",
    "navigationBarTextStyle": "black",
    "backgroundColor": "#eeeeee",
    "backgroundTextStyle": "light",
    "enablePullDownRefresh": true,
    "onReachBottomDistance": 50
  },
  "tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "images/icon_home.png",
        "selectedIconPath": "images/icon_home_active.png"
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日志",
        "iconPath": "images/icon_logs.png",
        "selectedIconPath": "images/icon_logs_active.png"
      }
    ]
  },
  "style": "v2"
}
窗口

小程序窗口组成部分(从上到下):

  • navigationBar 导航栏区域:包含时间、电量、微信标题

  • background 背景区域,默认不可见,下拉才显示

  • 页面主体区域,用了显示 wxml 中布局

windown节点常用配置项:

  • navigationBarTitleText 导航栏标题文字 字符串

  • navigationBarBackgroundColor 导航栏背景颜色 默认#000000,类型 HexColor

  • navigationBarTextStyle 导航栏颜色(标题、电池等颜色) 仅支持 black/white,默认 white

  • backgroundColor 窗口背景色 默认#ffffff,类型 H3xColor

  • backgroundTextStyle 下拉loading 的样式,仅支持 dark/light,默认 dark

  • enablePullDownRefresh 是否全局开启下拉刷新。默认 false。开启后会作用于小程序每个页面。

  • onReachBottomDistance 页面上拉触底时间触发时距离底部距离,单位 px,默认 50,若无特殊需求,不建议修改。

Tip下拉刷新,通常做法是在页面中单独开启,而非在这里全局开启。下拉刷新开启后,若要实现刷新,还得在 onPullDownRefresh 方法中处理下来刷新逻辑,这个方法会在用户触发下拉刷新操作时被调用。

:模拟器不能百分之百还原真机。例如下拉刷新,在模拟器中,下拉后,过了3秒,下拉自动合上;而在真机中,不会自动合上

tabBar

小程序中 tabBar 是导航组件。特性有:

  • 位置: 通常位于小程序界面的底部。

  • 图标和文字: 每个 tab 都可以包含图标和文字。

  • 选中状态: 可以配置选中和未选中状态下的图标和文字颜色。

  • 页面映射: 每个 tab 对应一个页面路径,点击 tab 会切换到相应的页面。

以下是一个典型的 app.json 中 tabBar 配置示例:

{
  "tabBar": {
    "color": "#999999",
    "selectedColor": "#1c1c1b",
    "backgroundColor": "#ffffff",
    "borderStyle": "black",
    "list": [
      {
        "pagePath": "pages/home/index",
        "text": "首页",
        "iconPath": "/images/icon_home.png",
        "selectedIconPath": "/images/icon_home_active.png"
      },
      {
        "pagePath": "pages/search/index",
        "text": "搜索",
        "iconPath": "/images/icon_search.png",
        "selectedIconPath": "/images/icon_search_active.png"
      },
      {
        "pagePath": "pages/profile/index",
        "text": "我的",
        "iconPath": "/images/icon_profile.png",
        "selectedIconPath": "/images/icon_profile_active.png"
      }
    ]
  }
}

:tabBar 只能配置最少2个,最多5个。当渲染顶部tabBar 时,不显示 icon,只显示文本。说tabBar 中的页面要放在 pages 前面,否则显示不出。

tabBar 有6个组成部分:

  • color,tab上文字的颜色

  • selectedColor,tab文字选中时的颜色

  • backgroundColor,tabBar 背景色

  • borderStyle,tabBar 边框颜色

  • iconPath,未选中时图片路径

  • selectedIconPath,选中时图片路径

tabBar 节点配置项:

  • position,默认 bottom,可配置 top

  • borderStyle,默认 black,仅支持 black/white

  • color,hexColor 类型

  • selectedColor,hexColor 类型

  • backgroundColor,hexColor 类型

  • list,Array,必填,最少2个,最多5个

每个 tab 项配置选项:

  • pagePath,必填,页面路径,页面必须在 pages 中预先定义

  • text,必填,tab上显示的文字

  • iconPath,未选中时图片路径;position 为top时不显示 icon

  • selectedIconPath,选中时图片路径;position 为top时不显示 icon

页面配置

在小程序中,全局配置和页面配置可以定义页面的外观和行为。当全局配置和页面配置冲突时,确实遵循就近原则,最终效果通常以页面配置为准。这意味着页面特定的配置会覆盖全局配置。这样可以确保页面的定制化效果。

页面配置中常用配置项:

  • navigationBarTitleText 导航栏标题

  • navigationBarBackgroundColor 导航栏背景颜色

  • navigationBarTextStyle 导航栏文字颜色

  • backgroundColor 页面背景颜色

  • backgroundTextStyle 下拉loading 的样式

  • enablePullDownRefresh 是否全局开启下拉刷新

  • onReachBottomDistance 页面上拉触底时间触发时距离底部距离

  • disableScroll 禁止页面滚动

  • usingComponents 页面使用的自定义组件列表

小程序基本语法

wxml

微信小程序的 wxml 类似网页中的 html。支付宝小程序中是 axml。

wxml 和 html 区别

  • 标签名称不同(比如用 view 代替 div):

    • HTML: div、span、img、a

    • wxml: view、text、image、navigator

  • 属性节点不同

<a href="http://www.baidu.com">百度</a>
<navigator url="http://www.baidu.com">百度</navigator>
  • 提供了类似 vue 的模板语法:数据绑定、列表渲染、条件渲染

数据绑定

在 data 中定义数据,在 wxml 中使用。例如:

Page({
  data: {
    name: '张三',
    age: 18,
    url: 'http://....png',
    randomNum: Math.random() * 10,
  }
})

用Mustache语法({{}})将变量包起来即可:

<view>{{ name }}</view>
<view>{{ randomNum > 5 ? '大于5': '小于或等于5' }}</view>

动态绑定属性不同于 vue 的 v-bind,小程序的动态绑定属性是直接在标签上写(写法不同而已,死记即可),例如:

<image src="{{ url }}"></image>

Tip: 数据在小程序开发工具控制台的 AppData tab中可以看到。

条件渲染

小程序和vue中条件渲染对比:

  • 语法差异:微信小程序使用 wx:if、hidden、block wx:if,vue中使用 v-if,v-show。

  • wx:if 和 v-if 类似,是真正的条件渲染

  • hidden 和 v-hsow 类似,都是通过 css 控制显隐,元素始终存在

  • block 类似 template,一次控制多个组件的展示与隐藏,且都不会渲染成实际的 dom 元素

用法:在 wxml 中使用 wx:if、wx:elif、wx:else 标签,在 data 中定义变量,在 wx:if 中使用变量。

<view>
  <view wx:if="{{ age > 18 }}">
    你成年了
  </view>
  <view wx:elif="{{ age < 18 }}">  你未成年
  </view>
  <view wx:else>
    你很少年
  </view>
</view>
列表渲染

小程序和vue中列表渲染对比:

  • 语法差异:微信小程序使用 wx:for、wx:key,vue中使用 v-for和:key

  • 都强调为列表渲染的每一项制定一个唯一的 key

  • vue 在列表渲染中提供了更丰富的功能

  • wx:for 和 v-for 类似,都是遍历数组,渲染成列表

用法:在 wxml 中使用 wx:for 标签,在 data 中定义数组,在 wx:for 中使用数组。

默认当前循环项索引是 index,当前循环项是 item:

<view class="container">
  <block wx:for="{{items}}" wx:key="index">
    <view>
      <text>{{index}}: {{item}}</text>
    </view>
  </block>
</view>
​
Page({
  data: {
    items: ['Item 1', 'Item 2', 'Item 3']
  }
});

wx:for-item 和 wx:for-index 用于自定义变量名,使得代码更加清晰和可读。

<view class="container">
  <block wx:for="{{items}}" wx:for-item="user" wx:for-index="idx" wx:key="id">
    <view>
      <text>Index: {{idx}}</text>
      <text>ID: {{user.id}}</text>
      <text>Name: {{user.name}}</text>
    </view>
  </block>
</view>
​
Page({
  data: {
    items: [
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
      { id: 3, name: 'Charlie' }
    ]
  }
});

: 小程序的 key,直接是循环项中的属性,且不需要 {{}}。如果是vue,得通过循环项找到

<template v-for="item in items" :key="item.id">
wxss

小程序的样式,类似网页的 css。

wxss 对比 css

wxss 具备 css 大部分特定,wxss 还对 css 进行了扩充和修改,以适应小程序的开发

wxss 和 css 区别:

  • 新增rpx(responsive pixel,响应式像素)尺寸单位

    • css中实现响应式布局,需要手动进行像素转换(常用 rem)。比如设计师提供的是 750 稿子,我们可能会将 1rem 等于75,设计稿的75就是1rem

    • wxss 在底层支持新的尺寸单位 rpx,在不同屏幕上会自动进行换算,同样是 750 的稿子,75个大小直接写成 75rpx 即可。

  • 提供全局样式和局部样式

    • 微信小程序:项目根目录中 app.wxss 会作用于素有小程序页面;局部页面的 .wxss 样式仅对当前页面生效

    • web 中CSS是全局作用,除非使用CSS模块化工具

  • 文件类型:微信小程序是 .wxss

  • 媒体查询:微信小程序不支持传统CSS媒体查询,如@media

  • css动画和过度:微信小程序支持部分 css 动画和过度,但有一些限制

  • wxss 仅支持部分常见的 css属性和选择器:.class和#id、element、并集选择器和后代选择器、::after和::before等伪类选择器

  • flex布局:微信小程序中的 flex 大部分与css一致,但具体表现有细微差异

  • 引入样式:微信小程序通过 @import 引入其他 .wxss,不支持 @import url() 形式引入外部 css

rpx

rpx 原理非常简单,把所有设备的屏幕从宽度上等分 750 份

  • 在375的设备,1rpx 等于 0.5px

  • 在1500的设备,1rpx 等于 2px

Tip:rem和 rpx 在实现响应式布局中,主要关注的是宽度的自适应。高度需要自行处理,比如等比扩展,或者限制最高高度。

iphone 屏幕宽度是 375px(逻辑像素),共有 750个像素点(物理像素),1个逻辑像素等于2个物理像素,等分750rpx。则:

  • 750rpx = 375px = 750 物理像素

  • 1rpx = 0.5px = 1 物理像素

开发举例:根据设计稿来,有的要求是1:1,有的是1:2,宽100px200px的盒子,转成rpx 就是 200rpx400rpx。

@import

@import 后根需要导入的外联样式的相对路径,用;表示结束。示例:

@import "demo.wxss";
.box{
​
}

使用时是 class 而非 className。

Tip:微信小程序支持使用 less,不过需要进行一些配置。

全局样式和局部样式

定义在 app.wxss 中的样式是全局样式,作用于每一个页面

定义在页面的 .wxss 中的样式是局部样式,只作用于当前页面。

:当局部样式和全局样式冲突,和 css 中一样:哪个权重高用哪个,如果权重相同,则使用就近原则(采取局部样式)

Tip:把鼠标放到小程序工具中选择器上,会有选中提示,例如:Selector Specificity:(0, 1, 0)

js

Tip:小程序中的 js 分3大类

  • app.js:小程序入口文件,通过调用 App() 函数启动整个小程序

  • 页面.js:页面的入口文件,通过调用 Page() 函数创建并运行页面

  • 普通.js:普通功能模块文件,用来封装公共的函数或属性,供页面使用

wxs

wxs在微信小程序中的作用类似 Vue.js中的过滤器(vue3 已废除过滤器)

小程序中的 wxs 和 javascript 是两种语言,区别有:

  • wxs 在视图层中运行,js运行在逻辑层

  • wxs 隔离性。不能调用 js 中定义的函数,不能调用小程序的API

  • wxs 设计初衷为了提高数据处理性能,特别是与界面渲染密切相关场景,减少和逻辑层的通信

Tip: 在 ios 中,小程序内的 wxs 比 js 块 2~20倍;在安卓上无差异。

wxs的语法基于JavaScript,这意味着如果你熟悉JavaScript,学习wxs会相对容易:

  • wxs 有自己的数据类型:number、string、boolean、array、object...

  • wxs 不支持类似es6+语法,不支持let、const、解构赋值、箭头函数;支持 var、function、es5语法

  • wxs 遵循 commonjs规范:module对象、require()函数、module.exports对象

  • wxs 可以编写在 <wxs>标签中,就像js写在 <script> 中,wxs 必须提供 module 属性,用来指定当前 wxs 模块名称

外联wxs用法(src必须是相对路径):

<!-- index.wxml -->
<wxs module="utils" src="../../utils/utils.wxs"/>
<view>
  <text>{{utils.formatDate(new Date())}}</text>
</view>
// utils.wxs
module.exports = {
  formatDate: function(date) {
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    return [year, month, day].map(this.formatNumber).join('-');
  },
​
  formatNumber: function(n) {
    n = n.toString();
    return n[1] ? n : '0' + n;
  }
};
数据请求

小程序中网络数据,处于安全考虑,小程序官方对数据接口做了如下限制:

  • 只能请求 https 类型接口

  • 必须将接口的域名添加到信任列表中

假如希望在自己的微信小程序中,希望请求https://www.xxx.com/域名下的接口。配置步骤:登录微信小程序后台->开发->开发设置->服务器域名->修改request合法域名。注意:

  • 域名只支持 https

  • 域名不能是 ip 地址或 localhost

  • 域名必须经过 ICP 备案

  • 服务器域名一个月内最多可申请5次修改

Tip: 如果后端仅提供http协议接口,为不耽误开发进度,可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS版本及HTTPS证书」,跳过 request 合法域名校验,仅限在开发和调试阶段使用。

get和post请求

在微信小程序中,您可以使用 wx.request 方法来发起 HTTP GET 和 POST 请求。这个方法提供了一种简单的方式来与服务器进行数据交互:

请看示例:

wx.request({
  url: 'https://api.example.com/data',
  method: 'GET', 
  data: {
    key1: 'value1',
    key2: 'value2'
  }, 
  header: {
    'content-type': 'application/json' 
  },
  success: function(res) {
  },
  fail: function(err) {
  }
});
wx.request({
  url: 'https://api.example.com/submit', 
  method: 'POST',
  data: {
    key1: 'value1',
    key2: 'value2'
  }, 
  header: {
    'content-type': 'application/json' 
  },
  success: function(res) {
  },
  fail: function(err) {
  }
});
小程序和跨域

小程序没有常规的跨域问题,但本质上还是涉及一些。但是对于前端开发,则无需处理跨域。

跨域(Cross-Origin Resource Sharing,简称 CORS)是指一个域名下的文档或脚本尝试请求另一个域名下的资源时,由于浏览器的同源策略(Same-origin policy)限制而导致的请求被阻拦的行为。这里的“同源”指的是协议、域名和端口号完全相同。同源策略是一种安全措施,旨在防止恶意网站通过脚本读取另一个网站的敏感数据。

跨域的本质是指浏览器出于安全考虑,实施的一种同源策略(Same-origin policy)

小程序的主体不是浏览器,而是小程序平台,所以没有常规的跨域问题。

因为小程序需要配置受信任域名,其实也在一定程度上有了安全保障,小程序的服务端也会涉及到CORS的配置

小程序和Ajax

Ajax核心依赖浏览器中的 XMLHttpRequest 对象,而小程序的宿主环境是微信客户端,所以小程序不叫”发起ajax请求“,而叫”发起网络请求“

微信小程序没有直接使用 ajax 这个术语,但提供了类似异步HTTP请求能力,主要通过 wx.request 接口来完成 Get 或 Post 请求,这一过程和Ajax非常类似,都是异步获取数据并更新界面而不阻塞页面。所以小程序中不说”ajax“,但实际上具备异步获取数据的能力

wx.request 和 ajax 功能相似,运营环境和实现机制不同。

请看示例:

wx.request({
  url: 'https://api.example.com/data', 
  method: 'GET', 
  data: {
    key1: 'value1',
    key2: 'value2'
  }, // 请求参数
  header: {
    'content-type': 'application/json' 
  },
  success: function(res) {
  },
  fail: function(err) {
  }
});

wx.request 可以与 async/await 和 Promise.all 配合使用:

  • 封装一个使用 wx.request 的 Promise 函数

const request = (options) => {
  return new Promise((resolve, reject) => {
    wx.request({
      ...options,
      success: res => resolve(res),
      fail: err => reject(err)
    });
  });
};
  • 然后在 async/await 中使用它:

Page({
  async onLoad() {
    try {
      const response = await request({
        url: 'https://example.com/api/data',
        method: 'GET'
      });
      console.log('Data:', response.data);
    } catch (err) {
      console.error('Error:', err);
    }
  }
});
小程序API的 Promise 化

在开发微信小程序时,许多原生 API 是基于回调函数的,这在现代 JavaScript 编程中可能不太方便。为了更好地处理异步操作,我们可以将这些回调函数形式的 API 转换为 Promise 形式

一种是手动封装

一种是用库(例如miniprogram-api-promise)。例如: 安装,构建后,在你的项目中配置并使用:

// app.js
import wxp from 'miniprogram-api-promise';
​
App({
  onLaunch() {
    // 把所有 wx 函数 promise 化
    wxp.init();
  }
});

在页面或组件中使用:

// pages/index/index.js
Page({
  data: {},
​
  async onLoad() {
    try {
      const response = await wx.p.request({
        url: 'https://api.example.com/data',
        method: 'GET',
      });
      console.log(response.data);
    } catch (error) {
      console.error(error);
    }
  }
});

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!优秀是一种习惯,欢迎大家留言学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值