微信小程序 -mpvue

本贴最后更新于 1508 天前,其中的信息可能已经时移世易

微信小程序——mpvue

  • mpvue 继承于 Vue.js 其技术规范和语法特点与 Vue.js 保持一致。
  • 官网地址:http://mpvue.com/mpvue/
  • 开发者文档地址:https://developers.weixin.qq.com/miniprogram/dev/component/button.html
  • 创建运行 mpvue 项目:
    # 全局安装 vue-cli
    $ npm install --global vue-cli
    
    # 创建一个基于 mpvue-quickstart 模板的新项目
    $ vue init mpvue/mpvue-quickstart my-project
    
    # 安装依赖
    $ cd my-project
    $ npm install
    # 启动构建
    $ npm run dev
    
  • 启动 微信开发者工具 , 引入刚启动搞得项目,就可以进行操作预览。

框架原理

  • mpvue 保留了 vue 的核心方法,
  • mpvue-template-compiler 提供了将 vue 的模板语法转换到小程序的 wxml 语法的能力
  • 修改了 vue 的建构配置,使之构建出符合小程序项目结构的代码格式: json/wxml/wxss/js 文件

生命周期函数

  • 同 vue , 不同的是会在小程序 onReady 后,再去触发 vue mounted 生命周期。
    beforeCreate
    created
    beforeMount
    mounted
    beforeUpdate
    updated
    activated
    deactivated
    beforeDestroy
    destroyed
    
    除了 Vue 本身的生命周期外,mpvue 还兼容了小程序生命周期,这部分生命周期钩子的来源于
    
    
  • 除了 Vue 本身的生命周期外,mpvue 还兼容了小程序生命周期,这部分生命周期钩子的来源于:微信小程序的 Page, 除特殊情况外,不建议使用小程序的生命周期钩子。
    app 部分:
    onLaunch,初始化
    onShow,当小程序启动,或从后台进入前台显示
    onHide,当小程序从前台进入后台
    onError起到错误监听的作用。
    
    
    page 部分:
    onLoad,监听页面加载
    onShow,监听页面显示
    onReady,监听页面初次渲染完成
    onHide,监听页面隐藏
    
    onUnload,监听页面卸载
    onPullDownRefresh,监听用户下拉动作
    onReachBottom,页面上拉触底事件的处理函数
    onShareAppMessage,用户点击右上角分享
    onPageScroll,页面滚动
    onTabItemTap, 当前是 tab 页时,点击 tab 时触发 (mpvue 0.0.16 支持)
    
  • 总体执行流程:
    beforeCreate—>  created  —> onLunch/onLoad  -->  onShow  -->  onReady  -->  beforeMounte  -->  mounted……
    
  • 周期图:img

注意事项:

  • 几乎全支持 Vue 的模板语法。
  • 不支持 纯-HTMLv-html 指令不能用。
  • 在插值表达式 {{}} 中不支持复杂的 JavaScript 渲染表达式:
    <!-- 这种就不支持,建议写 computed -->
    <p>{{ message.split('').reverse().join('') }}</p>
    
    <!-- 但写在 @event 里面的表达式是都支持的,因为这部分的计算放在了 vdom 里面 -->
    <ul>
        <li v-for="item in list">
            <div @click="clickHandle(item, index, $event)">{{ item.value }}</p>
        </li>
    </ul>
    
  • 不支持 ElementUI 和 Vue-router
  • 列表渲染: 只是需要注意一点,嵌套列表渲染,必须指定不同的索引!
    <!-- 在这种嵌套循环的时候, index 和 itemIndex 这种索引是必须指定,且别名不能相同,正确的写法如下 -->
    <template>
        <ul v-for="(card, index) in list">
            <li v-for="(item, itemIndex) in card">
                {{item.value}}
            </li>
        </ul>
    </template>
    
  • 原生组件上的事件绑定,需要以 vue 的事件绑定语法来绑定。
    • bindchange="eventName" 事件,需要写成 @change="eventName"

表单控件绑定 picker

  • 表单控件绑定 picker
  • picker 有多种选择形式,参考官网:https://developers.weixin.qq.com/miniprogram/dev/component/picker.html
  • select 组件用 picker 组件进行代替
  • 默认 mode 格式:
    <template>
      <div>
        <picker @change="bindPickerChange" :value="index" :range="array">
          <view class="picker">
            当前选择:{{array[index]}}
          </view>
        </picker>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          index: 0,
          array: ['A', 'B', 'C']
        }
      },
      methods: {
        bindPickerChange (e) {
          console.log(e)
          // 切换index位置
          this.index = e.mp.detail.value
        }
      }
    }
    </script>
    
  • 日期 mode=date 格式选择:
    <template>
      <div>
        <!-- value选中的日期 ,start有效开始日期 , end有效结束的日期 ,所选择的日期需要在start-end之间 -->
        <picker mode="date" :value="date" start="2015-09-01" end="2017-09-01" @change="bindDateChange">
          <view class="picker">
            当前选择: {{date}}
          </view>
        </picker>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          date: '2020-05-01'
        }
      },
      methods: {
        bindDateChange (e) {
          console.log(e)
          // 修改时间
          this.date = e.mp.detail.value
        }
      }
    }
    </script>
    

radio-group 组件

  • radio 使用 radio-group 组件代替:
  • 代码如下:
    <template>
      <div>
        <!-- radio-group 一组radio的集合 , @change 为触发选中单选时调用的方法,会传入一个默认的 e 标签对象 -->
        <radio-group class="radio-group" @change="radioChange">
          <label v-for="(item, index) in items" :key="index">
            <!-- value设置单选绑定搞得值,当选中后可以作为参数到method方法中 -->
            <!-- checked默认刚进来 选中的 -->
            <radio :value="item.name" :checked="item.checked"/> {{item.value}}
          </label>
        </radio-group>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          items: [
            {name: 'USA', value: '美国'},
            {name: 'CHN', value: '中国', checked: 'true'},
            {name: 'BRA', value: '巴西'},
            {name: 'JPN', value: '日本'},
            {name: 'ENG', value: '英国'},
            {name: 'TUR', value: '法国'}
          ]
        }
      },
      methods: {
        radioChange (e) {
          console.log(e)
          console.log('radio发生change事件,携带value值为:', e.target.value)
        }
      }
    }
    </script>
    

目录介绍

  • vue 页面中的 属性介绍 主要包含 <template> <script> <style> 三个标签。
  • template 中可以使用 html 常用标签,无法使用小程序专属标签。但是在对页面进行编译后,在 dist 中会生成小程序专属标签。
  • script 中,包含 config , data , components , methods 和 各种生命周期函数
    • config 是对小程序的一些配置,最后会生成为 json 文件
    • Data 是对数据的初始化,可以与页面进行绑定。Data 中使用 return 将变量名包起来,使其只在当前组件中生效,不会造成变量污染。
    • methods 是方法和函数的集合,里面可以生成一些函数和方法。并向后台发送请求
  • src/main.js 文件(全局的配置文件):
    import Vue from 'vue'
    import App from './App'
    
    var Fly = require('flyio/dist/npm/wx')
    var fly = new Fly()
    // 添加全局配置、拦截器等
    Vue.prototype.$http = fly
    // 将fly实例挂在vue原型上
    
    // 阻止启动生产消息 , 阻止更多的消息产生,增加App的沉余体积
    Vue.config.productionTip = false
    
    // 设置 mpvue 的类型
    App.mpType = 'app'
    // 进行注册App
    const app = new Vue(App)
    // 挂机app实例 在src根目录的 main.js中,设置的是整个 小程序App
    app.$mount()
    
  • src/app.json(全局的页面配置)
    
    

页面跳转

  • 小程序自带五中页面跳转方法,分别为 , ,
    • wx.navigateTo() :保留当前页面,跳转到另一个页面(主要表现为左上角含有返回按钮)
    • wx.navigateBack() : 配合 navigateTo 使用,跳回到上 N 层界面
    • wx.redirectTo() : 关闭当前页面,跳转到某一个页面上(左上角没有返回按钮)
    • wx.switchTab() : 主要用于跳转到 tabBar 的操作,如果想要跳转 tabBar 只能使用这个。
    • wx.relaunch() : 关闭所有页面,跳转到某一页面

发送 Http 请求

  • 小程序中只有 Get , Post 两种请求方式。
  • 使用 wx.request 发送 http 网络请求。具体参数有 url,data,header,method,success 等。
  • 列如代码:
    wx.request({
        url: 'http://47.95.199.43/abnormalFlight/ninfo',
            method: 'POST',
            header: {
              'content-type': 'application/json'
            },
            data: {
              flightdateid: this.flightdateid,
              createdate: this.plandt
            },
            success: (res) => {
              this.ninfos = res.data.data
            }
            Fail:(res)=>{
              Console.log(“失败”)
        }
            Complete:(){
          Console.log(“回调函数”)
        }
    })
    

推送消息功能

  • 小程序推送消息给用户。

小程序登录流程:

  • 详情图:img
  1. 小程序前端通过 wx.login() 的方法。可以获取一个 code 值。
  2. 携带着 code 值,访问 java 后端。
  3. java 后端,通过 appId 和 secret,+code 值。访问 微信 的 API 接口。获取到 用户登录的 openID 和 session_key。
  4. 将 openId 和 session_key 返回给前端。
  5. 每次进入页面,前端调用 wx.checkSession 方法,判断 session_key 是否过期,过期的话,就 调用 wx.login 进行访问 java 后端登录。

注意点:

  1. session_key 默认的有效时间为 3 天
  2. openId 为登录用户的 唯一 Id,一般存储在 数据表中
  3. wx.login 中的 code 值,是根据用户的信息进行生成的。虽然每次都不一样,但是均代表用户的信息。所以传递给后台,调用微信 API 接口后,不会生成新的 openID,还是和以前一致,会刷新 session_key 会话 ID。
  4. session_key 的作用为,可以解密出用户的 个人信息,手机号,所在地区..等等

获取用户信息

  • 通过 wx.getUserInfo 可以获取到用户的个人信息。 encryptedData 和 iv ..等等
    // 必须是在用户已经授权的情况下调用
        wx.getUserInfo({
          success(res) {
            const userInfo = res.userInfo  //整体user对象
            const nickName = userInfo.nickName  //用户昵称
            const avatarUrl = userInfo.avatarUrl   //用户头像
            const gender = userInfo.gender // 性别 0:未知、1:男、2:女
            const province = userInfo.province  //用户国家  
            const city = userInfo.city       //用户所在城市
            const country = userInfo.country   
            console.log(res)
          }
        })
    

引入 Vant Weapp 样式 UI

  • 官网地址:https://youzan.github.io/vant-weapp/#/quickstart
  • 引入方式(官网的不好用):
    # 通过 npm 安装
    npm i @vant/weapp -S --production
    
    //进入node_modules\@vant\weapp包下,将dist 复制到 项目的 static 目录下
    
    //在需要使用 Vant组件 的页面目录中创建 main.json 文件。
    //需要什么组件就引入什么
    {
        "navigationBarTitleText": "home首页",
        "usingComponents": {
          "van-button": "/static/vant/dist/button/index"
        }
    }
    
  • 效果如下:1589012081677.png
  • 使用组件:
    <van-button type="primary">主要按钮</van-button>
    
  • 在微信开发者平台,需要在详情中设置 ES6 转 ES5 , 不勾选无法使用1589012175200.png

注意事项(踩坑点)

  1. 组件的函数调用属性 bind:change="xxx" 要写为 @change="xxx",调用 methods 中的方法
  2. 上传组件 Uploader 的上传回调函数, after-read 不能用,要修改引入的 index.js。
    在 dist/uploader/index.js 文件中
    
    将after-read 修改为 afterread
    
    然后在组件中 就以 @afterread="xxx" 的方式使用(貌似是不能中间有 - ) 
    
  3. 修改组件的样式,自定义样式:
    custom-style="background-color=xxx"
    

小程序原生组件

小程序事件

touchstart	手指触摸动作开始
touchmove	手指触摸后移动
touchcancel	手指触摸动作被打断,如来电提醒,弹窗
touchend	手指触摸动作结束
tap	手指触摸后马上离开
longpress	手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发	1.5.0
longtap	手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend	会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart	会在一个 WXSS animation 动画开始时触发
animationiteration	会在一个 WXSS animation 一次迭代结束时触发
animationend	会在一个 WXSS animation 动画完成时触发
touchforcechange	在支持 3D Touch 的 iPhone 设备,重按时会触发

页面 style 中 设置 page 全局样式:


获取用户的个人信息

  • 获取用户的信息 需要用户的授权。 通过 button 来进行
  • 如果没有授权,就会弹出一个 是否确认授权的 按钮。
    获取用户信息
    
    // 获取用户的个人信息
    getUser (event) {
      console.log(event)
    }
    
  • 自动获取用户的 信息。 需要进行过 授权处理。不然无法获取 会走 fail 方法
      // 需要写在 mounted 函数中
      mounted () {
        wx.getUserInfo({
          withCredentials: true,
          // 成功方法
          success: function (res) {
            console.log(res)
            var userInfo = res.userInfo
            console.log(userInfo)
          },
          fail () {
          	// 失败方法
          }
        })
      },
    
  • 进入页面 自动弹出 获取信息 授权窗口(暂时不能使用):
  • 授权网址:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/authorize/wx.authorize.html
    // 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
        var self = this
        wx.getSetting({
          success (res) {
            if (!res.authSetting['scope.userInfo']) {
              wx.authorize({
                scope: 'scope.userInfo',
                success () {
                  // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
                  console.log('授权成功')
                  self.getUser()
                }
              })
            }
          }
        })
    

无需授权获取用户信息

  • 使用 open-data 可以获取用户的个人信息。但仅限展示效果,不能作为 js 中的数据进行交互操作:
  • 文档地址:https://developers.weixin.qq.com/miniprogram/dev/component/open-data.html
        
          
          
          
            
          
          
        
    
    // css样式 , 圆形头像
      .userinfo-avatar {
        text-align: center;
        margin: 0 auto;
        overflow: hidden;
        display: block;
        width: 130rpx;
        height: 130rpx;
        border-radius: 50%;
        border: 2px solid #ebebef;
      }
    

原生跳转页面

  • 进行页面跳转的是可使用小程序提供的 API
  • 在组件中 按钮 进行跳转:https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html
      跳转到新页面
      在当前页打开
      切换 Tab
      打开绑定的小程序
    
    
  • 在 js 方法中 进行跳转:https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab.html
    wx.navigateTo()  保留当前页面,可回退
    wx.redirectTo()  不保留,不能回退
    wx.switchTab()  使用于tabBar页面
    
    //代码示例
    wx.navigateTo({
      url: 'page/list/main',  // 路径要写成 对应的main.js文件
      events: {
        // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
        acceptDataFromOpenedPage: function(data) {
          console.log(data)
        },
        someEvent: function(data) {
          console.log(data)
        }
        ...
      },
      success: function(res) {
        // 通过eventChannel向被打开页面传送数据
        res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
      }
    })
    
    //test.js文件中,可以获取参数
    const eventChannel = this.getOpenerEventChannel()
    // 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
    const eventChannel = this.getOpenerEventChannel()
        eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'});
        eventChannel.emit('someEvent', {data: 'test'});
        // 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
        eventChannel.on('acceptDataFromOpenerPage', function(data) {
          console.log(data)
        })
    

url 请求中参数

  • 在 url 中使用 ? 参数需要。 encodeURIComponent 和 decodeURIComponent 编解码,否则会被截断,导致?后面的数据无法传递后跳转页面。
  • 对于多行字符串,可以使用反引号 `` 拼接,避免使用一大堆 和加号。
    var encodeUrl = encodeURIComponent(param.url)
    
    wx.navigateTo({ url: "../articleDetail/articleDetail?title=" + title + "&mid=" + this.data.mid + "&id=" + id + "&url=" +encodeUrl });
    
    跳转后页面js文件
    ...
    onLoad:function(options){
         this.setData({
             title:options.title,
             id:options.id,
             url: decodeURIComponent(options.url),  // 使用 decode进行解码
          }),
    

使用 flyio 发送 HTTP 请求

  • 需要下载并且在 需要的组件 main.js 中引入使用
  • 官方文档:https://github.com/wendux/fly
    npm install flyio // 下载
    
    // 在需要的组件 main.js中引入
    // pages/logs/main.js中进行配置
    // 配置网络请求 flyio
    var Fly = require('flyio/dist/npm/wx')
    var fly = new Fly()
    // 添加全局配置、拦截器等
    Vue.prototype.$http = fly
    
    // 使用
    this.$http.post('url' , { request playod中的请求数据 })
    .then((d) => {
    	console.log(d) // 返回的数据
    }).catch(err =>{
    	console.log(err.status , err.message) // 错误信息
    })
    
  • post 请求默认会在 request playod 中发送数据。但是可以设置为以 requestBody 中发送请求数据:
    // 第一种,通过 content-type设置
    fly.post("../package.json",{aa:8,bb:9,tt:{xx:5}},{headers:{
        "content-type":"application/x-www-form-urlencoded"
    }})
    .then(console.log)
    
    // 第二种 使用 qs 库
    var qs = require('qs');
    fly.post('/foo', qs.stringify({ 'bar': 123 }));
    

使用 Vuex 数据管理

  • 需要下载 vuex
    // 下载 vuex
    npm install vuex
    
  • 创建 vuex 声明文件
    //在src下创建store/store.js文件
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    // 声明使用vuex
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        state: {
    
        },
        actions: {
    
        },
        getters: {
    
        },
        mutations: {
    
        }
    })
    
  • 在 src 根目录下的 main.js 文件中,配置 Vuex,使每一个实例组件都可以使用
    import store from './store/store'
    // 将store 对象防止Vue的原型上,每个实例都可以使用 Vuex
    Vue.prototype.$store = store
    
  • 具体组件 (page/index/index.vue) 中使用 vuex 管理状态
    import {mapState} from 'vuex'
    
    // 在计算属性中,注册使用 vuex中的数据
    computed: {
    	...mapState(['state中的数据名称'])
    }
    
    // 调用 vuex中 mutations 的方法
    this.$store.commit("add")
    

分包管理

  • 微信小程序规定,一个包的总大小不能超过 2M , 所有包的总大小不能超过 10M
  • 小程序分为 主包 和 分包。
    • 主包:是 app.json 中 pages 属性定义的 路径内容,都是主包。
    • 分包:subpackages 中定义的路径是分包。
  • 当我们主包的大小超过 2M 就会报错。 所以我们要将 主包的 一些代码。可以放在分包中,当我们进入分包页面,才会加载其里面的内容。
  • app.json 中分包设置:
    {
      // 主包设置
    "pages": [
        "pages/login/main",
        "pages/index/main",
        "pages/logs/main",
        "pages/counter/main"
      ],
        // 分包设置 , 分包页面不能设置 tabBar 导航标签
      "subpackages": [
        {    						// {} 为一个分包
          "root": "pages/custom",  // root设置 这个分包的 根目录 , 不能与主包的相同
          "pages": [
            "main"  				// 设置这个分包下几个 路径页面,写main.js
          ],
          "plugins": {				// 当前分包可以使用的 plugins 插件
            "myPlugin": {
              "version": "0.0.5",
              "provider": "wxfea216762bcf4ad9"
            }
          }
        }
      ],
    }
    
  • 主包 跳转 到分包:
    wx.navigateTo({ url: '../custom/main' })
    

第三方插件使用:

快递查询插件

地图导航插件

反编译出微信小程序

  • 可以反编译出,微信上已经上线的小程序源码。
  • 是 微信小程序原生代码。 可以 扒下来,参考 css 样式编写。
  • 教程地址:https://zhuanlan.zhihu.com/p/138936448

需要工具

  • 夜神模拟器,node 环境,反编译脚本代码:
  • 反编译代码:M:\wxapp\wxappUnpacker-master

反编译过程

  1. 在夜神模拟器上下载 微信 软件。进行登录。
  2. 安装 PE 文件管理器: E:\百度云下载\Root_Explorer-v4.2.4(3.0 )-Origin_icon_group-Patched_by_Alphaeva.apk . (直接拉进夜神中即可安装)
  3. 在微信程序中,打开一个小程序。
  4. 然后通过 PE 找到 /data/data/com.tencent.mm/MicroMsg/{一串 16 进制字符}/appbrand/pkg/ 目录。(通过事件判断,哪个是刚打开的小程序)
  5. 一般文件大小不会超过 2M .
  6. 长按文件,进行压缩。 然后通过微信发送给一个好友。
  7. 电脑端也能查看这个发送的文件 (.wxapkg 结尾)。
  8. 通过 反编译 脚本。进行反编译:
    cmd 进入到 反编译文件夹中: M:\wxapp\wxappUnpacker-master
    安装依赖:
    1、npm install esprima
    2、npm install css-tree
    3、npm install cssbeautify
    4、npm install vm2
    5、npm install uglify-es
    6、npm install js-beautify
    7、npm install escodegen -g
    
    //进行反编译命令   C:_163200311_32.wxapkg 为要编译的 小程序代码
    node wuWxapkg.js C:_163200311_32.wxapkg
    
  9. 编译出的代码文件夹,直接在 微信小程序开发者工具中,导入打开即可。
  10. 出现 _vd_version_info_is not defined 错误:: 解决:https://www.cnblogs.com/wukong8/p/11612470.html

Git 拉取代码强制覆盖

  • 拉取代码覆盖本地的:
  • 在项目 跟目录下
    $ git fetch --all
    $ git reset --hard origin/master 
    $ git pull
    
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1348 回帖 • 2 关注
  • 小程序
    77 引用 • 219 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...