【微信小程序】微信小程序开发学习记录

环境准备

注册账号

访问注册页面注册⻚⾯,完成注册(建议使用新邮箱)。

获取APPID

登录微信小程序,找到开发开发设置获取APPID。

开发工具

下载地址

第一个微信小程序

打开开发者工具

登录需要扫码登录

新建项目

填写项目信息,复制获取的AppID,后端服务暂时选择不使用云服务。

开发工具

开发工具介绍

结构目录

⼩程序框架的⽬标是通过尽可能简单、⾼效的⽅式让开发者可以在微信中开发具有原⽣APP体验的服务。

文件结构与传统web对比

  • 传统web:
    • 结构 HTML
    • 样式 CSS
    • 逻辑 Javascript
    • 配置 ⽆
  • 微信⼩程序
    • 结构 HTML
    • 样式 WXSS
    • 逻辑 Javascript
    • 配置 JSON

基本目录结构

  • pages :页面文件夹
    • index :首页文件夹
      • index.js :逻辑文件
      • index.json :配置文件
      • index.wxml :配置文件
      • index.wxss :样式文件
  • logs :日志页面
    • logs.js
    • logs.json
    • logs.wxml
    • logs.wxss
  • utils :第三方工具js文件夹
    • util.js
  • app.js :项目的全局入口文件
  • app.json :全局配置文件
  • app.wxss :全局样式文件
  • project.config.json :项目配置文件 AppID
  • sitemap.json :微信索引配置文件

配置文件

配置文件不能出现注释

全局配置文件 app.json

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。
完整配置项说明请参考小程序全局配置
以下是一个包含了部分常用配置选项的 app.json :

{
  "pages": [
    "pages/index/index",
    "pages/logs/index"
  ],
  "window": {
    "navigationBarTitleText": "Demo",
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  },
  "tabBar": {
    "list": [{
      "pagePath": "pages/index/index",
      "text": "首页"
    }, {
      "pagePath": "pages/logs/index",
      "text": "日志"
    }]
  },
  "networkTimeout": {
    "request": 10000,
    "downloadFile": 10000
  },
  "debug": true,
  "navigateToMiniProgramAppIdList": [
    "wxe5f52902cf4de896"
  ]
}

页面配置 page.json

这⾥的page.json其实⽤来表⽰⻚⾯⽬录下的page.json这类和⼩程序⻚⾯相关的配置。开发者可以独⽴定义每个⻚⾯的⼀些属性,如顶部颜⾊、是否允许下拉刷新等等。每一个小程序页面也可以使用同名 .json 文件来对本页面的窗口表现进行配置,页面中配置项会覆盖app.jsonwindow 中相同的配置项。
完整配置项说明请参考小程序页面配置

sitemap 配置

通过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler 及场景值:1129。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。sitemap

模板语法

WXML(WeiXin Markup Language)是框架设计的⼀套标签语⾔,结合基础组件、事件系统,可以构建出⻚⾯的结构。

数据绑定

普通写法

<view>{{name}}</view>
Page({
    data:{
        name:'丽丝'
    }
})

组件属性

<view id="item-{{id}}"></view>
Page({
    data:{
        id:0
    }
})

bool类型

不要直接写checked="false",其计算结果是⼀个字符串

<checkbox checked="{{false}}"></checkbox>

运算

三元运算

<view hidden="{{ flag ? true : false }}"></view>
<view>
	{{10%2===0 ? '偶数' : '奇数'}}
</view>

算术运算

<view>
	{{a+b}}+{{c}}+d
</view>
Page({
    data:{
        a:1,
        b:3,
        c:5
    }
})

逻辑判断

<view wx:if="{{length > 5}}"></view>

字符串运算

<view>{{"hello" + name}}</view>

列表渲染(遍历)

wx:for

项的变量名默认为 item wx:for-item 可以指定数组当前元素的变量名
下标变量名默认为 index wx:for-index 可以指定数组当前下标的变量名
wx:key ⽤来提⾼数组渲染的性能
wx:key绑定的值有如下选择:

  • string 类型,表⽰循环项中的唯⼀属性
  • 保留字*this,它的意思是item本⾝,*this代表的必须是唯⼀的字符串和数组。
<view>
	<view wx:for="{{ list }}" wx:for-item="item" wx:for-index="index" wx:key="id">
			索引:{{ index }}
			--
			值:{{ item.name }}
	</view>
</view>
<view>
	<view>对象循环</view>
	<view wx:for="{{person}}" wx:for-item="value" wx:for-index="key" wx:key="age">
		属性:{{key}}
		--
		值:{{value}}
	</view>
</view>

block

渲染⼀个包含多节点的结构块?block最终不会变成真正的dom元素

<view>
	<view>对象循环</view>
	<block wx:for="{{person}}" wx:for-item="value" wx:for-index="key" wx:key="age" class="my_list">
		属性:{{key}}
		--
		值:{{value}}
	</block>
</view>

条件渲染

wx:if

使用wx:if="{{condtion}}"判断是否需要渲染代码块。

    <view>条件渲染</view>
	<view wx:if="{{true}}">显示</view>
	<view wx:if="{{false}}">隐藏</view>

	<view wx:if="{{true}}">1</view>
	<view wx:elif="{{false}}">2</view>
	<view wx:else>3</view>

hidden

<view hidden="{{condition}}"> True </view>

频繁切换使用 hidden,不频繁则 wx:if

事件的绑定

  • wxml页面
<view>输入:
<input type="text" bindinput="handleInput"/>
</view>
<view>
 {{num}}
</view> 
  • js page
Page({
 /**
  * 页面的初始数据
  */
 data: {
     num:0
 },
 // 输入框测试
 handleInput(e){
   this.setData({
     num:e.detail.value
   });
   console.log(e.detail.value);
 },
})

事件传值通过标签⾃定义属性的⽅式和 value

<button bindtap="handletap" data-operation="{{1}}">+</button>
<button bindtap="handletap" data-operation="{{-1}}">-</button>
<view>
 {{num}}
</view>
// 加减
 handletap(e){
   const nums = e.currentTarget.dataset.operation;
   this.setData({
     num:this.data.num += nums
   })
 },

样式 WXSS

WXSS(WeiXin Style Sheets)是⼀套样式语⾔,⽤于描述 WXML的组件样式。
与CSS相⽐,WXSS扩展的特性有:

  • 响应式⻓度单位 rpx
  • 样式导⼊

尺寸单位

尺寸单位

  • rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
iPhone51rpx = 0.42px1px = 2.34rpx
iPhone61rpx = 0.5px1px = 2rpx
iPhone6 Plus1rpx = 0.552px1px = 1.81rpx

建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。

注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

样式导⼊

wxss中直接就⽀持,样式导⼊功能。也可以和less中的导⼊混⽤。使⽤ @import 语句可以导⼊外联样式表,只⽀持相对路径。

/** common.wxss **/
view{
  background-color: rgb(235, 235, 235);
}
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.userinfo-avatar {
  width: 128rpx;
  height: 128rpx;
  margin: 20rpx;
  border-radius: 50%;
}
/**index.wxss**/
@import "../../styles/common.wxss";

选择器

目前支持的选择器有:

选择器样例样例描述
.class.intro选择所有拥有 class=“intro” 的组件
#id#firstname选择拥有 id=“firstname” 的组件
elementview选择所有 view 组件
element, elementview, checkbox选择所有文档的 view 组件和所有的 checkbox 组件
::afterview::after在 view 组件后边插入内容
::beforeview::before在 view 组件前边插入内容

常见组件

微信开发文档


<!-- text -->
<text user-select decode>text &nbsp; 123</text>
<!-- images -->
<view class="img">
  <image mode="widthFix" lazy-load src="https://konachan.net/sample/417260b75396b82c6206e044a50e4cc9/Konachan.com%20-%20318761%20sample.jpg"></image>
</view>
<!-- swiper 轮播图 -->
<swiper autoplay="true" interval="1500" circular="true" indicator-dots="true" indicator-color="#0094ff" indicator-active-color="#ff0094">
  <swiper-item>
    <image mode="widthFix" lazy-load src="https://konachan.net/sample/417260b75396b82c6206e044a50e4cc9/Konachan.com%20-%20318761%20sample.jpg"></image>
  </swiper-item>
  <swiper-item>
    <image mode="widthFix" lazy-load src="https://konachan.net/sample/417260b75396b82c6206e044a50e4cc9/Konachan.com%20-%20318761%20sample.jpg"></image>
  </swiper-item>
  <swiper-item>
    <image mode="widthFix" lazy-load src="https://konachan.net/sample/417260b75396b82c6206e044a50e4cc9/Konachan.com%20-%20318761%20sample.jpg"></image>
  </swiper-item>
</swiper>
<!-- navigator -->
<navigator hover-class="navigator-hover" url="/pages/logs/logs">log</navigator>
<!-- rich-text 标签字符串 -->
<rich-text nodes="{{html}}"></rich-text>
<!-- button -->
<button>默认按钮</button>
<button size="mini">迷你按钮</button>
<button type="primary">primary 按钮</button>
<button type="warn">warn按钮</button>
<button type="warn" plain>plain按钮</button>
<button open-type="contact">contact</button>
<button open-type="share">share</button>
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
<button open-type="launchApp">launchApp</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
<!-- 字体图标 -->
<view class="" hover-class="none" hover-stop-propagation="false">
  <icon type="success" size="23" color="red"></icon>
</view>
<!-- radio 单选框 -->
<radio-group bindchange="handleChange">
  <radio class="" color="red" value="male"></radio>
  <radio class="" color="red" value="female"></radio>
</radio-group>
<view class="" hover-class="none" hover-stop-propagation="false">您选中的是:{{gender}}</view>
<!-- checkbox 多选框 -->
<checkbox-group bindchange="handleItemChange">
  <checkbox class="" value="{{item.value}}" wx:for="{{list}}" wx:key="id">{{item.name}}</checkbox>
</checkbox-group>
<view>选中的水果:{{checkdeList}}</view>

// pages/search/search.js
Page({

    /**
     * 页面的初始数据
     */
    data: {
        html: '<div><p>demo</p></div>',
        gender: '',
        list: [{
            id: 0,
            name: '🍎',
            value: 'apple'
        }, {
            id: 1,
            name: '🍌',
            value: 'banana'
        }, {
            id: 2,
            name: '🍊',
            value: 'orange'
        }],
        checkdeList: []
    },
    // 单选框事件
    handleChange(e) {
        let gender = e.detail.value;
        this.setData({
            gender: gender == "male" ? "男" : "女"
        });
    },
    // 多选框事件
    handleItemChange(e) {
        const checkdeList = e.detail.value;
        this.setData({
            checkdeList
        })
    },
    getPhoneNumber(e) {
        console.log(e);
    },
    getUserInfo(e) {
        console.log(e);
    },
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function(options) {

    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: function() {

    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function() {

    },

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide: function() {

    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function() {

    },

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function() {

    },

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: function() {

    },

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage: function() {

    }
})

自定义组件

创建自定义组件

⼩程序允许我们使⽤⾃定义组件的⽅式来构建⻚⾯。在微信开发者⼯具中快速创建组件的⽂件结构,项目根目录下新建components/Tabs文件夹,然后右键Tabs文件夹,新建Component,生成 json wxml wxss js 4个文件。

声明组件

需要在组件的json⽂件中进⾏⾃定义组件声明

{
  "component": true,
  "usingComponents": {}
}

编辑组件

在组件的wxml⽂件中编写组件模板,在wxss⽂件中加⼊组件样式slot 表⽰插槽,类似vue中的slot,注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

<view class="tabs">
    <view class="tabs_title">
        <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="hanldeItemTap" data-index="{{index}}">
            {{item.name}}
        </view>
    </view>
    <view class="tabs_content">
        <slot></slot>
    </view>
</view>

注册组件

在组件的 js ⽂件中,需要使⽤Component()来注册组件,并提供组件的属性定义、内部数据和⾃定义⽅法

// components/Tabs/Tabs.js
Component({
    /**
     * 组件的属性列表
     */
    properties: {
        tabs: {
            type: Array,
            value: []
        }
    },
    /**
     * 组件的初始数据
     */
    data: {},

    /**
     * 组件的方法列表
     */
    methods: {
        hanldeItemTap(e) {
            const { index } = e.currentTarget.dataset;
            this.triggerEvent("itemChange", { index });
        }
    }
})

声明引入自定义组件

在⻚⾯的json⽂件中进⾏引⽤声明。还要提供对应的组件名和组件路径。

{
    "usingComponents": {
        "Tabs": "../../components/Tabs/Tabs"
    }
}

页面中使用自定义组件

<Tabs tabs="{{tabs}}" binditemChange="handleItemChange">
  <block wx:if="{{tabs[0].isActive}}">0</block>
  <block wx:elif="{{tabs[1].isActive}}">1</block>
  <block wx:elif="{{tabs[2].isActive}}">2</block>
  <block wx:else>3</block>
</Tabs>

父子组件之间的传值

父组件向子组件传值

  • 首先在父组件的 json 文件中定义子组件
{
    "usingComponents": {
        "StepDevice": "/components/StepDevice/StepDevice"
    }
}
  • 之后在父组件wxml中使用定义的组件
<StepDevice stepNum="{{item.shopNum}}"/>
  • 子组件规定的写法

    获取定义的数据使用: this.properties.stepNum
    改变数据的写法:this.setData({stepNum: 2 })

Component({
	properties:{
		stepNum: {
			type: Number,
			value: 1
		}
	},
	// 子组件的生命周期函数
	lifetimes: {
        // 在组件实例进入页面节点树时执行
        attached: function () {
            console.log(this.properties.stepNum)
        },
    },
})

子组件向父组件传值

  • 子组件的写法

如果向父组件传值使用到的固定写法this.triggerEvent('父组件定义的事件名称',{传递的数据})
也是在事件触发的时候向父组件传递数据

<!-- 子组件的写法 -->
<text class="add-btn" bindtap="addBtn">+</text>
<!-- 父组件 -->
<StepDevice bind:changeStepNum="stepChange"/>
<!-- stepChange 为父组件用来获取子组件的数据的方法 -->
  • 子组件方法

this.triggerEvent('父组件定义的事件名称',{传递的数据})父组件定义的事件名称就是bind绑定的事件名称这里的就是changeStepNum

Component({
	properties: {
        stepNum: {
            type: Number,
            value: 1
        }
    },
    methods:{
    	// 给父组件传值
        stepChange() {
            this.triggerEvent("changeStepNum", {
                stepNum: this.properties.stepNum
            })
        },
        // 每次点击的时候就把 数据传递给父组件
        addBtn() {
            this.stepChange()
        }
	 }
})
  • 父组件的写法

stepChange 为父组件用来获取子组件的数据的方法

<!-- 父组件 -->
<StepDevice bind:changeStepNum="stepChange"/>
<!-- stepChange 为父组件用来获取子组件的数据的方法 -->
  • 获取数据

数据保存在 e.detail

stepChange(e) {
   const getStepNum = e.detail.stepNum
    console.log(getStepNum)
},

参考

生命周期

分为应⽤⽣命周期和⻚⾯⽣命周期

应用生命周期

注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

Object object
属性类型默认值必填说明最低版本
onLaunchfunction生命周期回调——监听小程序初始化。
onShowfunction生命周期回调——监听小程序启动或切前台。
onHidefunction生命周期回调——监听小程序切后台。
onErrorfunction错误监听函数。
onPageNotFoundfunction页面不存在监听函数。1.9.90
onUnhandledRejectionfunction未处理的 Promise 拒绝事件监听函数。2.10.0
onThemeChangefunction监听系统主题变化2.11.0
其他any开发者可以添加任意的函数或数据变量到 Object 参数中,用 this 可以访问

页面生命周期

注册小程序中的一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

属性类型默认值必填说明
dataObject页面的初始数据
optionsObject页面的组件选项,同 Component 构造器 中的 options ,需要基础库版本 2.10.1
onLoadfunction生命周期回调—监听页面加载
onShowfunction生命周期回调—监听页面显示
onReadyfunction生命周期回调—监听页面初次渲染完成
onHidefunction生命周期回调—监听页面隐藏
onUnloadfunction生命周期回调—监听页面卸载
onPullDownRefreshfunction监听用户下拉动作
onReachBottomfunction页面上拉触底事件的处理函数
onShareAppMessagefunction用户点击右上角转发
onShareTimelinefunction用户点击右上角转发到朋友圈
onAddToFavoritesfunction用户点击右上角收藏
onPageScrollfunction页面滚动触发事件的处理函数
onResizefunction页面尺寸改变时触发,详见 响应显示区域变化
onTabItemTapfunction当前是 tab 页时,点击 tab 时触发
其他any开发者可以添加任意的函数或数据到 Object 参数中,在页面的函数中用 this 可以访问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值