微信小程序开发

1、查看小程序的后台界面

2、找到小程序的开发者账号

3、创建小程序

在空目录

4、了解小程序的目录结构

pages ---- 路由

index

index.js   ---  页面的js文件

index.json ---  页面的配置文件

index.wxml ---  页面的结构 

index.wxss ---  页面的样式

utils ---- 模块

app.js ---- 全局的js文件

app.json -- 全局的配置文件

app.wxss -- 全局的样式文件

project.config.json 项目配置文件

sitemap.json 小程序搜索的配置

5、小程序的配置文件

5.1 全局的配置 --- app.json

用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#全局配置

小程序的启动页面就是pages选项的第一个页面

{
  // 页面路径列表
  "pages": [ // 小程序的路由,一个页面就是一个路由
    "pages/index/index",
    "pages/logs/logs"
  ],
  // 全局的默认窗口表现
  "window": {
    "backgroundTextStyle": "light", // 下拉页面后看到的微信的背景的字体样式
    "navigationBarBackgroundColor": "#fff", // 小程序头部背景
    "navigationBarTitleText": "WeChat", // 小程序的标题
    "navigationBarTextStyle": "white" // 标题的字体颜色 black / white
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

5.2 页面的配置 --- pages/page/page.json

每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html

pages/index/index.json

{
  "navigationBarBackgroundColor": "#f66",
  "navigationBarTitleText": "首页",
  "enablePullDownRefresh": true,
  "backgroundColor": "#00f",
  "usingComponents": {}
}

6、创建小程序的页面以及配置底部选项卡

6.1 创建页面

编辑app.json全局配置文件中的 pages 选项,会自动生成各个页面

"pages": [
  "pages/home/home",
  "pages/kind/kind",
  "pages/cart/cart",
  "pages/user/user",
  "pages/index/index",
  "pages/logs/logs"
],

6.2 配置底部选项卡

app.json 文件中追加一个选项 tabBar (底部 tab 栏的表现)

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar

"tabBar": {
  "color": "#333",
  "selectedColor": "#f66",
  "backgroundColor": "#fff",
  "borderStyle": "black", // 上边框颜色
  "position": "top", // 顶部的选项卡,图标自动失效
  "list": [
    {
      "text": "首页",
      "pagePath": "pages/home/home",
      "iconPath": "/resources/tabs/home.png", // 绝对路径
      "selectedIconPath": "/resources/tabs/home_active.png"
    },
    {
      "text": "分类",
      "pagePath": "pages/kind/kind",
      "iconPath": "/resources/tabs/kind.png",
      "selectedIconPath": "/resources/tabs/kind_active.png"
    },
    {
      "text": "购物车",
      "pagePath": "pages/cart/cart",
      "iconPath": "/resources/tabs/cart.png",
      "selectedIconPath": "/resources/tabs/cart_active.png"
    },
    {
      "text": "我的",
      "pagePath": "pages/user/user",
      "iconPath": "/resources/tabs/user.png",
      "selectedIconPath": "/resources/tabs/user_active.png"
    }
  ]
},

7、首页添加轮播图

小程序提供的默认组件

https://developers.weixin.qq.com/miniprogram/dev/component/

8、小程序的wxml语法

8.1 初始化的状态

// home.js
data: {
  msg: "hello 小程序",
  list: ['a', 'b', 'c', 'd'],
  flag: false
}

// home.wxml
{{ msg }}
<view wx:for="{{ list }}" wx:key="{{ index }}">
  {{ item }}
</view>
<view wx:for="{{ list }}" wx:for-item="itm" wx:for-index="idx" wx:key="{{ idx }}">
  {{ itm }}
</view>
<view wx:if="{{ flag }}">如果为真我就显示</view>
<view wx:else>如果为假我就显示</view>
<view hidden="">如果为假我就显示</view>

小程序的列表渲染,默认选项为item,默认索引值为index,如果需要更改,可以通过wx:for-item 和 wx:for-index修改

小程序的条件判断,wx:if wx:elif wx:else hidden

8.2 模板

// wxml
<template name="md">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>
<template is="md" data="{{...item}}"/>
<template is="md" data="{{...item1}}"/>
<template is="md" data="{{...item2}}"/>

// js
data : {
  item: {
    index: 0,
    msg: 'this is a template',
    time: '2016-09-15'
  },
  item1: {
    index: 0,
    msg: 'this is a template',
    time: '2016-10-15'
  },
  item2: {
    index: 0,
    msg: 'this is a template',
    time: '2016-11-15'
  },
}

8.3 引用

  • import
    我的附庸的附庸不是我的附庸
// md.wxml
<template name="md">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>

// home.wxml
<import src="md.wxml" />
<template is="md" data="{{...item}}"/>
<template is="md" data="{{...item1}}"/>
<template is="md" data="{{...item2}}"/>
  • include
    拷贝代码 但是不拷贝 模板以及wxs代码

9、小程序的生命周期

9.1 小程序App ---- app.js

https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html

属性 类型 默认值 必填 说明

onLaunch function 否 生命周期回调——监听小程序初始化。

onShow function 否 生命周期回调——监听小程序启动或切前台。

onHide function 否 生命周期回调——监听小程序切后台。

onError function 否 错误监听函数。

onPageNotFound function 否 页面不存在监听函数。

其他 any 否 开发者可以添加任意的函数或数据变量到 Object 参数中,用 this 可以访问

可以在小程序 的任何位置 通过 getApp() 获取到小程序全局唯一的 App 实例。

**可以在app.js中设置全局的对象 来管理需要的状态 **

// app.js
globalData: {
  userInfo: null,
  title: '小程序全局的实例'
},
state: {
  test: '1'
}

// home.js
let app = getApp()
console.log(app.globalData.title)
console.log(app.state.test)
app.state.test = 2
console.log(app.state.test)

9.2 页面 Page - 生命周期

属性 类型 默认值 必填 说明

data Object 页面的初始数据

onLoad function 生命周期回调—监听页面加载 ----ajax请求

onShow function 生命周期回调—监听页面显示 ---- vue activated

onReady function 生命周期回调—监听页面初次渲染完成

onHide function 生命周期回调—监听页面隐藏 ---- vue deactivated

onUnload function 生命周期回调—监听页面卸载

onPullDownRefresh function 监听用户下拉动作 ----需要page.json中开启下拉刷新

onReachBottom function 页面上拉触底事件的处理函数

onShareAppMessage function 用户点击右上角转发

onPageScroll function 页面滚动触发事件的处理函数

onResize function 页面尺寸改变时触发,详见 响应显示区域变化

onTabItemTap function 当前是 tab 页时,点击 tab 时触发

其他 any 开发者可以添加任意的函数或数据到 Object 参数中,在页面的函数中用 this 可以访问

getCurrentPages() 获取当前是哪一个页面

10、生命周期钩子中请求数据

小程序的数据请求,必须使用wx.request()函数,而且接口必须是https协议,并且小程序的安全域名必须得配置

但是在开发时可以忽略 请求域名的配置 详情 -> 本地设置 -> 不检验合法域名,一定要记住在项目上线时去掉它

10.1 封装数据请求方法 utils/request.js

https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html

let baseUrl = "http://47.92.152.70";
export default {
  fetch (url, data, method) {
    data = data || {}
    method = method || 'get'
    return new Promise(resolve => {
      // https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
      wx.request({
        url: baseUrl + url,
        data,
        method,
        success: (res) => {
          resolve(res.data)
        }
      })
    })
  }
}

10.2 页面调用数据请求 ---- onLoad()

// home.js
import request from './../../utils/request.js'

onLoad: function (options) {
  request.fetch('/banner').then(data => {
    console.log(data)
    // 修改状态
    this.setData({
      bannerlist: data.data
    })
  })
},

11、列表组件

11.1 创建组件 components/prolist/prolist

// prolist.wxml
<view class="ul prolist">
  <view class="li item">
    <view class="itemimg">
    </view>
    <view class="iteminfo">
    </view>
  </view>
</view>

// prolist.wxss
/* components/prolist/prolist.wxss */
.prolist .item{
  display: flex;
  height: 100px;
  border-bottom: 1px solid #ccc;
}

.prolist .item .itemimg {
  width: 90px;
  height: 90px;
  background: #f66;
  margin: 5px;
}
.prolist .item .iteminfo {
  flex: 1;
}

11.2 注册并且使用组件 --- vue

  • 注册组件 ---- 哪里需要使用组件在哪里的 .json 中注册
// home.json
{
  "navigationBarTitleText": "首页",
  "usingComponents": {
    "prolist": "/components/prolist/prolist"
  }
}
  • 使用组件
<prolist />

12、组件之间传值

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html

12.1 父组件获取数据

// home.js
data: {
  bannerlist: [],
  prolist: []
},
onLoad: function (options) {
  request.fetch('/banner').then(data => {
    console.log(data)
    // 修改状态
    this.setData({
      bannerlist: data.data
    })
  })
  request.fetch('/pro').then(data => {
    console.log(data)
    // 修改状态
    this.setData({
      prolist: data.data
    })
  })
},

12.2 父组件给子组件传值

父组件在调用子组件的时候,给他添加一个自定义的属性,属性的值就是需要传递给子组件的值,如果传递的值是一个变量,或者是一个number类型或者boolean类型的数据,需要用到{{}}

<prolist prolist="{{prolist}}"/>

在子组件定义的地方,有一个properties,自定义属性加上数据类型,这样讲就可以在子组件中直接使用父组件自定义的属性来渲染组件

// prolist.js
properties: {
  prolist: Array
},
// prolist.wxml
<view class="ul prolist">
  <view class="li item" wx:for="{{prolist}}">
    <view class="itemimg">
      <image src="{{ item.proimg }}"></image>
    </view>
    <view class="iteminfo">
      <view>{{item.proname}}</view>
    </view>
  </view>
</view>

12.3子组件给父组件传值

父组件在调用子组件的地方,绑定一个自定义的事件,事件的执行由父组件定义,父组件通过event.detail接收数据,

<prolist prolist="{{prolist}}" bind:myevent = "getData"/>

// 父组件接收子组件的参数
getData (event) {
  console.log(event.detail.item.proname)
},

子组件中在需要的事件内部通过this.triggerEvent触发自定义事件,并且传递参数,注意参数是对象

<button bindtap="sendData" data-item="{{item}}">点击</button>

methods: {
  sendData (event) {
    console.log(event.target.dataset)
    this.triggerEvent('myevent', event.target.dataset)
  }
}

13、点击进入产品的详情

声明式跳转 + 编程式跳转

13.1 声明式跳转

https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html

open-type
值 说明 最低版本
navigate 对应 wx.navigateTo 或 wx.navigateToMiniProgram 的功能 --- push

redirect 对应 wx.redirectTo 的功能 --- replace

switchTab 对应 wx.switchTab 的功能 --- 切换底部选项卡页面

reLaunch 对应 wx.reLaunch 的功能 1.1.0

navigateBack 对应 wx.navigateBack 的功能 1.1.0 --- back

exit 退出小程序,target="miniProgram"时生效 2.1.0

<navigator url="/pages/detail/detail" open-type=""></navigator>

// prolist.wxml
<view class="ul prolist">
  <navigator url="/pages/detail/detail" class="li item" wx:for="{{prolist}}">
    <view class="itemimg">
      <image src="{{ item.proimg }}"></image>
    </view>
    <view class="iteminfo">
      <view>{{item.proname}}</view>
      <!-- <button bindtap="sendData" data-item="{{item}}">点击</button> -->
    </view>
  </navigator>
</view>

传值

<navigator url="/pages/detail/detail?proid={{item.proid}}" class="li item" wx:for="{{prolist}}"></navigator>

详情页面接收参数 onLoad 的 options 就是参数

// detail.js
data: {
  proname:''
},

/**
  * 生命周期函数--监听页面加载
  */
onLoad: function (options) {
  console.log(options)
  const { proid } = options;
  request.fetch('/pro/detail?proid=' + proid).then(data => {
    console.log(data.data)
    this.setData({
      proname: data.data.proname
    })
  })
},

<view>{{proname}}</view>

13.2 编程式跳转

https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab.html

  • wx.switchTab(Object object) 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

  • wx.reLaunch(Object object) 关闭所有页面,打开到应用内的某个页面

  • wx.redirectTo(Object object)关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。

  • wx.navigateTo(Object object)保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层

  • wx.navigateBack(Object object)关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层

<view  class="li item" wx:for="{{prolist}}" >
  <view class="itemimg">
    <image src="{{ item.proimg }}"></image>
  </view>
  <view class="iteminfo" bindtap="toDetail" data-proid = "{{item.proid}}">
    <view>{{item.proname}}</view>
    <!-- <button bindtap="sendData" data-item="{{item}}">点击</button> -->
  </view>
</view>

methods: {
  sendData (event) {
    console.log(event.target.dataset)
    this.triggerEvent('myevent', event.target.dataset)
  },
  toDetail (event) {
    const { proid } = event.target.dataset;
    wx.navigateTo({
      url: '/pages/detail/detail?proid=' + proid
    })
  }
}

14、返回顶部

https://developers.weixin.qq.com/miniprogram/dev/api/ui/scroll/wx.pageScrollTo.html

<button bindtap="backtop">返回顶部</button>
backtop () {
  wx.pageScrollTo({
    scrollTop: 0,
    duration: 300
  })
},

15、下拉刷新上拉加载

在页面的配置文件中开启下拉刷新

// home.json
{
  "navigationBarTitleText": "首页",
  "enablePullDownRefresh": true,
  "usingComponents": {
    "prolist": "/components/prolist/prolist"
  }
}

15.1 home.js处编写它的业务逻辑 ---- 上拉加载

data: {
  pageCode: 1
},
/**
  * 页面相关事件处理函数--监听用户下拉动作
  */
onPullDownRefresh: function () {
  request.fetch('/pro').then(data => {
    this.setData({
      prolist: data.data,
      pageCode: 1
    })
  })
},

/**
  * 页面上拉触底事件的处理函数
  */
onReachBottom: function () {
  console.log('可以加载了')
  request.fetch('/pro?pageCode=' + this.data.pageCode).then(data => {
    let pageCode = this.data.pageCode
    pageCode++;
    this.setData({
      pageCode
    })
    if (data.data.length === 0) {
      wx.showToast({
        title: '没有更多数据了',
        duration: 2000
      })
    } else {
      let prolist = this.data.prolist
      this.setData({
        prolist: [...prolist, ...data.data]
      })
    }
  })
},  

16、获取用户的信息

点击个人中心,可以获取用户信息

<view wx:if="{{username=== ''}}">
  <button open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">获取用户的信息</button>
</view>
<view wx:else>
  欢迎您: {{username}}
</view>


data: {
  username: ''
},
bindGetUserInfo(e) {
  console.log(e.detail.userInfo)
  wx.getSetting({
    success:(res) =>{
      if (res.authSetting['scope.userInfo']) {
        wx.getUserInfo({
          success:  (res) => {
            console.log(res.userInfo)
            this.setData({
              username: res.userInfo.nickName
            })
          }
        })
      }
    }
  })
},

17.打开已经授权过的权限

<button  bindtap="openSeting">打开设置</button>

openSeting () {
  wx.openSetting({
    success(res) {
      console.log(res.authSetting)
      // res.authSetting = {
      //   "scope.userInfo": true,
      //   "scope.userLocation": true
      // }
    }
  })
},

18、获取用户的地理位置

https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.stopLocationUpdate.html

app.json文件授权

"permission": {
  "scope.userLocation": {
    "desc": "你的位置信息将用于小程序位置接口的效果展示" 
  }
}

19、头像

https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html

<button  bindtap="getImg">头像</button>
 getImg () {
    wx.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success(res) {
        // tempFilePath可以作为img标签的src属性显示图片
        const tempFilePaths = res.tempFilePaths
      }
    })
  },

点击编辑器上传,然后去小程序后台扫码体验码查看效果

20、首页轮播图大图预览

https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.previewImage.html

 <image src="{{ 'http://47.92.152.70/' + item.img }}" data-current="{{ 'http://47.92.152.70/' + item.img }}" bindtap="previewImage" />

 previewImage (event) {
    console.log(event.target.dataset)
    let arr = []
    this.data.bannerlist.map(item => {
      arr.push('http://47.92.152.70/' + item.img)
    })
    wx.previewImage({
      current: event.target.dataset.current, // 当前显示图片的http链接
      urls: arr // 需要预览的图片http链接列表
    })
  },
posted @ 2019-11-26 19:35  菜鸟小何  阅读(440)  评论(0编辑  收藏  举报