小程序基础篇笔记-技术鸭论坛-前端交流-技术鸭(jishuya.cn)

小程序基础篇笔记

小程序入门篇

基础创建演示

第一步,新建一个小程序的项目目录。名字可以随便起,这里称为wechat-miniprogram-demo

第二步,在该目录里面,新建一个脚本文件app.js。这个脚本用于对整个小程序进行初始化。

第三步,新建一个配置文件app.json,记录项目的一些静态配置。 app.json 不能写注释

  • app.json文件的内容,至少必须有一个pages属性,指明小程序包含哪些页面

// pages属性是一个数组,数组的每一项就是一个页面。
 // 这个示例中,小程序只有一个页面,所以数组只有一项pages/home/home。
 {
   "pages": [  // pages
     "pages/home/home"
  ]
 }
 ​
 pages/home/home是一个三层的文件路径。
 ​
 所有页面都放在pages子目录里面。
 每个页面有一个自己的目录,这里是pages下面的home子目录,表示这个页面叫做home。页面的名字可以随便起,只要对应的目录确实存在即可。
 小程序会加载页面目录pages/home里面的home.js文件,.js后缀名可以省略,所以完整的加载路径为pages/home/home。home.js这个脚本的文件名也可以随便起,但是习惯上跟页面目录同名。

第四步,新建pages/home子目录。

然后,在这个目录里面新建一个脚本文件home.js。该文件的内容如下。

Page({});
 ​
 // `Page()`由小程序原生提供,它是一个函数,用于初始化一个页面实例。它的参数是一个配置对象,用于设置当前页面的行为属性。这里是一个空对象,表示不设置任何属性。

第五步,在pages/home目录新建一个home.wxml文件。WXML 是微信页面标签语言,类似于 HTML 语言,用于描述小程序的页面。

home.wxml的内容很简单,就写一行hello world

hello world
 

到这一步,可以在开发者工具里面,看到运行结果了。

WXML 标签语言

<view>
 <text> hello world </text>
 </view>
 ​
 // `<view>`标签表示一个区块,用于跟其他区块分隔,类似 HTML 语言的`<div>`标签。`<text>`表示一段行内文本,类似于 HTML 语言的`<span>`标签,多个`<text>`标签之间不会产生分行。

上面的代码用到了两个标签:<view><text>

 // 目前文件结构
 |- app.json
 |- app.js
 |- pages
    |- home
       |- home.wxml
       |- home.js

项目配置文件 app.json

window 用于设置小程序的状态栏、导航条、标题、窗口背景色 :

官网链接:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#window

最外层目录的app.json文件用于整个项目的配置,对于所有页面都有效。

除了pages属性,app.json文件还有一个window属性 (见上面官网链接),用来设置小程序的窗口。window属性的值是一个对象,其中有三个属性很常用。

navigationBarBackgroundColor://导航栏的颜色,默认为#000000(黑色)。
 navigationBarTextStyle://导航栏的文字颜色,只支持black(黑色)或white(白色),默认为white。
 navigationBarTitleText://导航栏的文字,默认为空。
 ​
 // 代码演示
 {
   "pages": [
     "pages/home/home"
  ],
   "window": {
     "navigationBarBackgroundColor": "#ff0000",
     "navigationBarTextStyle": "white",
     "navigationBarTitleText": "小程序 Demo"    
  }
 }

样式

  • 外层目录放置一个app.wxss文件,里面采用 CSS 语法设置页面样式。这个文件的设置,对所有页面都有效。

  • 在单个文件pages/home目录里面,新建一个home.wxss文件,只对 home 页面生效

使用 CSS 样式,但是样式文件的后缀名一律要写成.wxss

<view>
   <text class="title">hello world</text>
 </view>
 ​
 // app.wxss文件中
 .title {
   font-size: 24pt;
   color: blue;
 }

Flex 布局

page {
   height: 100%;
   width: 750rpx;
   display: flex;
   justify-content: center;
   align-items: center;
 }

这里单位是rpx,而不是pxrpx小程序为适

应不同宽度的手机屏幕,而发明的一种长度单位。

不管什么手机屏幕,宽度一律为750rpx。它的好处是换算简单,如果一个元素的宽度是页面的一半,只要写成width: 375rpx;即可。

样式导入

@import 可以导入外联样式表

@import  '路径';

图片轮播

小程序原生的“组件可以提供图片轮播效果。

<swiper>组件的indicator-dots属性设置是否显示轮播点,autoplay属性设置是否自动播放轮播。它们的属性值都是一个布尔值,这里要写成{{true}}。这种{{...}}的语法,表示里面放置的是 JavaScript 代码。

// 代码演示
 <view>
   <swiper  // <swiper>组件就是轮播组件
     indicator-dots="{{true}}"  //indicator-dots设置是否显示轮播点
     autoplay="{{true}}" // autoplay设置是否自动播放轮播
     style="width: 750rpx;">
     <swiper-item>  // 放置了三个<swiper-item>组件,表示有三个轮播项目,每个项目就是一个<image>组件。
       <image src="https://picsum.photos/200"></image>
     </swiper-item>
     <swiper-item>
       <image src="https://picsum.photos/250"></image>
     </swiper-item>
     <swiper-item>
       <image src="https://picsum.photos/300"></image>
     </swiper-item>
   </swiper>
 </view>

数据绑定

// 打开home.js文件
 Page({
   data: {
     name: '张三'
  }
 });
 ​
 //渲染到页面
 <view>
   <text class="title">hello {{name}}</text>
 </view>

data对象的所有属性,自动成为当前页面可以读取的全局变量。也就是说,home页面可以自动读取name变量。

全局数据

数据绑定只对当前页面有效,如果某些数据要在多个页面共享,就需要写到全局配置对象里面。

打开app.js,改写如下。

App({
   globalData: {  // 随便起个对象名名字,用于在多个页面之间分享的值
     now: (new Date()).toLocaleString()
  }
 });
// 其他页面使用共享的数据
 const app = getApp();
 ​
 Page({
   data: {
     now: app.globalData.now  // 页面直接使用插值表达式就可以使用了 {{now}}
  }
 });
  • getApp()函数是小程序原生提供的函数方法,从页面获取 App 实例对象。

  • 拿到实例对象以后,就能从它上面拿到全局配置对象的globalData属性,从而把app.globalData.now赋值给页面脚本的now属性,进而通过数据绑定机制,变成页面的全局变量now

事件

也会有事件捕获事件冒泡

tap://触摸后马上离开。
 longpress://触摸后,超过 350ms 再离开。如果指定了该事件的回调函数并触发了该事件,tap事件将不被触发。
 touchstart://触摸开始。
 touchmove://触摸后移动。
 touchcancel://触摸动作被打断,如来电提醒,弹窗等。
 touchend://触摸结束。

在传播上分成两个阶段:

  • 先是捕获阶段(由上层元素向下层元素传播),

  • 然后是冒泡阶段(由下层元素向上层元素传播)。所以,同一个事件在同一个元素上面其实会触发两次:捕获阶段一次,冒泡阶段一次

// 指定是哪个阶段触发回调函数
 capture-bind:捕获阶段触发。
 capture-catch:捕获阶段触发,并中断事件,不再向下传播,即中断捕获阶段,并取消随后的冒泡阶段。
 bind:冒泡阶段触发。
 catch:冒泡阶段触发,并取消事件进一步向上冒泡。

案例演示:

前缀里面的冒号可以省略,即写成bindtap也可以

<view>
   <text class="title">hello {{name}}</text>
   <button bind:tap="buttonHandler">点击</button> // bind:冒泡阶段触发。
 </view>
 ​
 ​
 // Page
 Page({
   data: {
     name: '张三'
  },
   buttonHandler(event) {
     this.setData({   // 事件回调函数内部的this,指向页面实例。
       name: '李四'  // 页面实例的 this.setData()方法,可以更改配置对象的data属性
    });
  }
 });

动态提示 Toast

用来增强互动效果 如: 每次操作后,都显示一个动态提示

打开home.js文件,为this.setData()加上第二个参数。

这个参数函数内部,调用了wx.showToast()方法,wx是小程序提供的原生对象,所有客户端 API 都定义在这个对象上面,wx.showToast()会展示微信内置的动态提示框,它的参数对象的title属性指定提示内容,duration属性指定提示框的展示时间,单位为毫秒。过了700毫秒,提示框就会自动消失。

//this.setData()方法第二个参数,这是一个函数,
 // 它会在页面变更完毕后(即this.setData()执行完)自动调用。
 ​
 Page({
   data: {
     name: '张三'
  },
   buttonHandler(event) {
     this.setData({
       name: '李四'
    }, function () {  // 第二个参数
 //它的参数对象的 title 属性指定提示内容, duration 属性指定提示框的展示时间,单位为毫秒。
       wx.showToast({  // // wx.showToast() 会展示微信内置的动态提示框,
         title: '操作完成',  // title指定提示内容
         duration: 700  // duration展示时间,单位为毫秒。 过了700毫秒,提示框就会自动消失。
      });
    }),
  }
 });

对话框 Modal

小程序提供的wx.showModal()方法,制作一个对话框,即用户可以选择”确定”或”取消”。

// 打开home.js文件
 Page({
   data: {
     name: '张三'
  },
   buttonHandler(event) {
     const that = this;  // 赋值 this
     wx.showModal({  // `wx.showModal()`方法的参数是一个配置对象
       title: '操作确认',  // `title`属性表示对话框的标题
       content: '你确认要修改吗?',  // `content`属性表示对话框的内容
       success (res) {      // `success`属性指定对话框成功显示后的回调函数
         if (res.confirm) { // `confirm`属性为`true`,点击的就是"确定"按钮
             
           that.setData({  //同上次动态提示案例代码 这里this不会指向页面实例,所以上面用变量接受以下this
             name: '李四'
          }, function () {
              wx.showToast({
                title: '操作完成',
                duration: 700
              });
          });
             
        } else if (res.cancel) {  // 失败的 // `cancel`属性为`true`,点击的就是"取消"按钮
           console.log('用户点击取消');
        }
      }
    });
  }
 });
  • 如果参数对象的confirm属性为true,点击的就是”确定”按钮,

  • cancel属性为true,点击的就是”取消”按钮。

注意,上面代码写的是that.setData(),而不是this.setData()。这是因为setData()方法定义在页面实例上面,但是由于success()回调函数不是直接定义在Page()的配置对象下面,this不会指向页面实例,导致this.setData()会报错。解决方法就是在buttonHandler()的开头,将this赋值给变量that,然后在success()回调函数里面使用that.setData()去调用。

WXML 渲染语法

WXML 的全称是微信页面标签语言(Weixin Markup Language),它不仅提供了许多功能标签,还有一套自己的语法,可以设置页面渲染的生效条件,以及进行循环处理。

// 数据
 Page({
   data: {
     items: ['事项 A', '事项 B', '事项 C']
  }
 });
 ​
 // 页面
 <view>
     // 数组有多少个成员,就会生成多少个<text>。渲染后的页面结构如下。
   <text class="title" wx:for="{{items}}">  // 循环 类似Vue  
    {{index}}、 {{item}}
    </text>
 </view>
 ​
 // 运行结果
 ​
 /*
 <view>
  <text>...</text>
  <text>...</text>
  <text>...</text>
 </view>
 */

客户端数据储存

// 一个输入框 一个按钮 实现点击按钮新增事项,渲染到页面
 ​
 // input事件的监听函数inputHandler(输入内容改变时触发),
 // 按钮有一个tap事件的监听函数buttonHandler(点击按钮时触发)。这两个监听函数负责处理用户的输入。
 <view>
   <text class="title" wx:for="{{items}}">
    {{index}}、 {{item}}
    </text>
    <input placeholder="输入新增事项" bind:input="inputHandler"/>  // 输入内容改变时触发
    <button bind:tap="buttonHandler">确定</button> // tap:// 点击按钮时触发
 </view>
 ​
 ​
 // -------------
 Page({
   data: {
     items: [],
     inputValue: ''
  },
   inputHandler(event) {
     this.setData({
       inputValue: event.detail.value || ''  // 有数据就给inputValue ,没有就给 ''
    });
  },
   buttonHandler(event) {
     const newItem = this.data.inputValue.trim(); // 去掉左右空格
     if (!newItem) return;  // 空的就return出去
     const itemArr = [...this.data.items, newItem];
     wx.setStorageSync('items', itemArr); // 本地缓存
     this.setData({ items: itemArr });  // 新增data里面items的数据
  },
     
 // onLoad()方法,该方法属于页面的生命周期方法,页面加载后会自动执行该方法。它只执行一次,用于页面初始化
   onLoad() {
     const itemArr = wx.getStorageSync('items') || [];  // 拿数据
     this.setData({ items: itemArr });  // 给data
  }
 });

wx.setStorageSync()方法用于将数据写入客户端储存。它接受两个参数,分别是键名和键值。与之配套的,

wx.getStorageSync()方法,用于读取客户端储存的数据。它只有一个参数,就是键名。这两个方法都是同步的,小程序也提供异步版本,请参考官方文档

远程数据请求

Page({
   data: { items: [] },
   onLoad() {
     const that = this;
 ​
     wx.request({
       url: 'http://localhost:3000/items',
       success(res) {
         that.setData({ items: res.data });
      }
    });
 ​
  }
 });

< open-data >组件

如果要在页面上展示当前用户的身份信息,可以使用小程序提供的<open-data>组件

  • <open-data>不需要用户授权,也不需要登录,所以用起来很方便。

  • 但也是因为这个原因,小程序不允许用户脚本读取<open-data>返回的信息。

// home 文件
 ​
 // <open-data>组件的type属性指定所要展示的信息类型,
 // userAvatarUrl表示展示用户头像,
 // userNickName表示用户昵称。
 ​
 <view>
   <open-data type="userAvatarUrl"></open-data>
   <open-data type="userNickName"></open-data>
 </view>
 userNickName:用户昵称
 userAvatarUrl:用户头像
 userGender:用户性别
 userCity:用户所在城市
 userProvince:用户所在省份
 userCountry:用户所在国家
 userLanguage:用户的语言

获取用户个人信息

如果想拿到用户的个人信息,必须得到授权。官方建议,通过按钮方式获取授权

<button>标签的open-type属性,指定按钮用于获取用户信息,bind:getuserinfo属性表示点击按钮会触发getuserinfo事件,即跳出对话框,询问用户是否同意授权。

<view>
   <text class="title">hello {{name}}</text>
   <button open-type="getUserInfo" bind:getuserinfo="buttonHandler">
     授权获取用户个人信息
   </button>
 </view>
 ​
 Page({
   data: { name: '' },
   buttonHandler(event) {  //不管用户点击"拒绝"或"允许",都会执行这个函数
 // 通过事件对象event有没有detail.userInfo属性,来判断用户点击了哪个按钮。如果能拿到event.detail.userInfo属性,就表示用户允许读取个人信息。这个属性是一个对象,里面就是各种用户信息,比如头像、昵称等等。
     if (!event.detail.userInfo) return;
     this.setData({
       name: event.detail.userInfo.nickName
    });
  }
 });
 ​
 //实际开发中,可以先用wx.getSetting()方法判断一下,用户是否已经授权过。如果已经授权过,就不用再次请求授权,而是直接用wx.getUserInfo()方法获取用户信息。

页面跳转

方式一:

<navigator>就是链接标签,相当于网页标签<a>,只要用户点击就可以跳转到url属性指定的页面(这里是第一页的位置)。

<view>
   <text class="title">这是首页</text>
   <navigator url="../second/second">前往第二页</navigator>
 </view>

方式一:

wx.navigateTo() 页面跳转

<view>
   <text class="title">这是首页</text>
   <button bind:tap="buttonHandler">前往第二页</button>
 </view>
 // --------
 Page({
 //只要用户点击按钮,就会调用wx.navigateTo()方法。该方法的参数是一个配置对象,该对象的url属性指定了跳转目标的位置,自动跳转到那个页面。
   buttonHandler(event) {
     wx.navigateTo({
       url: '../second/second'
    });
  }
 });
请登录后发表评论

    请登录后查看回复内容