mpvue_mpvue2 - CSDN
  • mpVue是美团开发团队推出的一个小程序的框架, 是现在市面上最火的小程序框架之一, 其优点是可以使用vue.js的开发模式去开发小程序, 具备模块化, 组件化, 工程化的优点, 也可以使用第三方库如:Vuex, flyio等。...
  • mpvue 是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心, 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。 本课程以项目...
  • 本项目使用的框架是美团团队推出的小程序框架Mpvue,项目为模块化、组件化、工程化的项目。涵盖了原生小程序API的使用、Vue.js核心语法及flyio第三方Ajax请求库,后端使用Koa框架进行搭建。学习本课程内容可以快速...
  • mpvue搭建小程序框架

    2019-07-13 13:26:56
    美团开源了mpvue 由于mpvue框架是完全基于Vue框架的(重写了其runtime和compiler) 运行时框架 runtime 和代码编译器 compiler 实现 mp:mini program 的缩写 mpvue:Vue.js in mini program mpvue-loader ...

    http://mpvue.com/mpvue/

    美团开源了mpvue

    由于mpvue框架是完全基于Vue框架的(重写了其runtime和compiler)
    运行时框架 runtime 和代码编译器 compiler 实现

    mp:mini program 的缩写
    mpvue:Vue.js in mini program

    image.png

    image.png

    npm set registry https://registry.npm.taobao.org/
    
    npm install vue-cli -g
    

    image.png

    开始创建项目

    vue init mpvue/mpvue-quickstart mpvueTest
    

    image.png

    image.png

    image.png

    image.png

    引入一些项目需要的基本第三方库

    package.json,加入一下内容

      "dependencies": {
        "mpvue": "^2.0.0",
        "vuex": "^3.0.1",
        "weapp-qrcode": "^0.9.0",
        "flyio": "^0.5.9",
        "install": "^0.12.2",
        "mp-weui": "^1.0.3",
        "mpvue-zanui": "^1.0.2",
        "common-mpvue": "^0.4.6",
        "mpvue-config-loader": "^0.1.3"
      },
    

    image.png

    第三方库

    import Vue from 'vue'
    import App from './App'
    import store from '@/store';
    import WeUI from 'mp-weui/packages';
    
    Vue.use(WeUI);
    Vue.config.productionTip = false
    App.mpType = 'app'
    
    const app = new Vue({
        store,
        ...App
    });
    app.$mount();
    

    main.json

    {
        "navigationBarTitleText": "页面标题",
        "enablePullDownRefresh": true
    }
    

    utils目录下index.js常用方法:

    // /**
    //  * 获取storage
    //  */
    export function getCache(key) {
      var value = wx.getStorageSync(key)
      if (value) {
        return value
      }
      return ""
    }
    
    // /**
    //  * 删除storage
    //  */
    export function removeCache(key) {
      wx.removeStorage(key);
    }
    
    /**
     * 存储storage
     */
    export function setCache(key, value) {
      try {
        wx.setStorageSync(key, value)
      } catch (e) { }
    }
    
    /**
      获取url参数
     */
    export function getUrlParam(path) {
      var result = {},
        param = /([^?=&]+)=([^&]+)/gi,
        match;
      while ((match = param.exec(path)) != null) {
        result[match[1]] = match[2];
      }
      return result;
    }
    
    /**
      数组是否包含某个字符串
     */
    export const carrContainStr = (a, obj) => {
      for (var i = 0; i < a.length; i++) {
        if (a[i] == obj) {
          return i;
        }
      }
      return -1;
    }
    
    
    /**
       克隆
     */
    export const clone = (obj) => {
      // Handle the 3 simple types, and null or undefined
      if (null == obj || "object" != typeof obj) return obj;
    
      // Handle Date
      if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
      }
    
      // Handle Array
      if (obj instanceof Array) {
        var copy = [];
        for (var i = 0, len = obj.length; i < len; ++i) {
          copy[i] = clone(obj[i]);
        }
        return copy;
      }
    
      // Handle Object
      if (obj instanceof Object) {
        var copy = {};
        for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
      }
    
      throw new Error("Unable to copy obj! Its type isn't supported.");
    }
    
    
    /**
       判断机型
     */
    export const isiOS = () => {
      var u = navigator.userAgent;
      var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
      var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
      if (isiOS) {
        return true
      }
      return false;
    }
    

    https://vuex.vuejs.org/zh/guide/

    flyio封装网络请求

    image.png
    flyio请求,封装代码

    var Fly=require("flyio/dist/npm/wx") 
    import { getCache } from '../utils'
    
    const request = new Fly()
    
    
    // 全局加载提示 - 设定时间
    let ltime = 0;
    
    function closeLoading(param) {
        ltime--
     }
    request.interceptors.request.use((request) => {
        // 全局加载提示 - 展示提示
        // wx.showNavigationBarLoading() 
        ltime++
    
        let dataSource = getCache("dataSource")
        request.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "source": "miniApp",
            "dataSource": dataSource ? dataSource : ''
        }
        // 没用到
        if (request.url.indexOf('getReviewInfo') != -1) {
            closeLoading()
            return request
        }
        // 登录
        console.log('这是token');
        console.log();
        let type = '';
        if(request.url.indexOf("wxLogin") != -1) {
            type = request.body.loginType;
        }
        console.log(getCache("token"));
        console.log('这是token');
        if (request.url.indexOf("wxLogin") == -1 || type == 'WORKBENCH') {
            // let storeId = getCache("storeId");
            let storeCode = getCache("storeCode");
            let inviter = getCache("inviter");
            let token = getCache("token");
            request.headers = {
                "Content-Type": "application/x-www-form-urlencoded",
                "source": "miniApp",
                "token": token,
                "storeCode": storeCode,
                "inviter": inviter
            }
            console.log('打印request');
            console.log(request);
            console.log('打印request');
            let dataSource = getCache("dataSource")
            if (dataSource) {
                request.headers['dataSource'] = dataSource
            }
        }
        return request
    })
    
    request.interceptors.response.use((response, promise) => {
             closeLoading()
            // wx.hideNavigationBarLoading()
            // 微信运维统计
            if (response.status) {
                wx.reportMonitor('0', +(response.status))
            }
            if (response.headers.date) {
                let time = new Date().getTime() - new Date(response.headers.date).getTime()
                wx.reportMonitor('1', +(time))
            }
            // 错误提示
            if (response.status != 200) {
                wx.showToast({
                    title: '出错啦!请稍后再试试哦~',
                    icon: 'none',
                    duration: 2000
                })
            }
            return promise.resolve(response.data)
        },
        (err, promise) => {
            wx.hideNavigationBarLoading()
            return promise.resolve()
        }
    )
    export default request
    

    新建utils/api.js文件

     export const baseUrlApi = 'http://:8080'//---开发调试环境
    //export const baseUrlApi = 'https://test.mini.com'//---测试环境https
    //export const baseUrlApi = 'https://product.mini.com'//---生产环境https
    

    src下新建service文件夹
    login-service.js,order-service.js

    import { baseUrlApi } from '../utils/api'
    import request from '../utils/request'
    
    export default {
     // 登录
        wxLogin: (data) =>
            request.post(`/store-miniApp-web/external/interface/wechat/wxLogin`, data, { baseURL: baseUrlApi }),
    
     // 收藏
      addCollect: (goodId, status) =>
        request.get(`/store-miniApp-web/store/member/addCollect?goodId=${goodId}&status=${status}`,
          null, {
            baseURL: baseUrlApi
          }),
    
    }
    

    接口请求的使用

    import loginApi from "@/service/login-service";
    
      methods: {
    //-登录
        clickLoginBtn() {
          var data = {
            phone: '',
            password: "",
          };
          console.log("登录参数==", data);
          loginApi.wxLogin(data).then(
            data => {
              if (!data) {
                this.$toast(data.msg);
                return;
              }
              if (data.code==0) {
                console.log("登录成功", data);   
              }
            },
            err => {
    
            }
          );
        },
        //-收藏
        collect() {
          let isCollect = "1"; //1收藏 0取消
          let goodId = "";
          loginApi.addCollect(goodsId, isCollect).then(data => {
            if (data.code != 0) {
              console.log("收藏失败", data);
              return;
            }
            if (isCollect == 1) {
              this.$toast("取消成功");
            } else {
              this.$toast("收藏成功");
            }
          });
        }
      }
    

    mapGetters
    mapMutations

    const store new Vuex.Store({
        state: {
            count: 0
        },
        mutations: {
            increment(state,n){
                state.count += n
            }
        }
    })
    
    new Vue({
        el:"#app",
        store,
        computed: {
            count() {
               return store.state.count
            }
        },
        methods: {
            add() {
               //传参
               store.commit('increment',10) 
            }
        }
    })
    

    mapMutations辅助函数的传参

    //store.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    //定义state,并将listName设置为一个空对象
    const state = {
        listName: {}
    }
    //定义mutations,可以传参,用于设置state里的listName
    const mutations = {
        set_listname: (state,value) => {
            state.listName=value
        }
    }
    //定义getters,用于获取出state里的对象
    const getters = {
        get_listname: state => {
            return state.listName
        }
    }
    
    export default new Vuex.Store({
        getters,
        state,
        mutations
    })
    

    在vue实例中注册store

    //main.js
    import Vue from 'vue'
    import App from './App'
    import store from './store'
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      template: '<App/>',
      components: { App }
    })
    

    image.png
    image.png

    Fly.js

    一个支持所有JavaScript运行环境的基于Promise的、支持请求转发、强大的http请求库。可以让您在多个端上尽可能大限度的实现代码复用。

    image.png

    image.png

    image.png

    image.png

    https://wendux.github.io/dist/#/doc/flyio/readme

    vuex的定义

    Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式

    集中存储和管理应用的所有组件的状态

    store(仓库),new Vue.store({…})


    请点赞!因为你的鼓励是我写作的最大动力!

    官方微信公众号

    吹逼交流群:711613774

    吹逼交流群

    展开全文
  • 能看这篇文章应该已对mpvue有所了解,此处不做赘述。 构成 1、采用mpvue 官方脚手架搭建项目底层结构 2、采用Fly.js 作为http请求库 目录结构 ├── src // 我们的项目的源码编写文件 │ ├── ...

    源码

    mpvue-vuex-demo

    构成

    1、采用mpvue 官方脚手架搭建项目底层结构
    2、采用Fly.js 作为http请求库
    3、引入mpvue-router-patach,以便在mpvue小程序中能使用vue-router的写法

    当当当当!mpvue2更新啦,感动,我爱vue(雾)
    为了庆祝一波,作者决定近期进行2.0版本的mpvue-vuex-demo的开发,预计将有以下改动:

    1. 适配最新的mpvue等所有依赖版本~~
    2. 大幅优化api部分的代码封装,使其更接近真实的生成环境,解决api权限和封装代码臃肿丑陋的问题。个人认为,对前端新人来说,会是一个很好学习和增强代码能力的体验
    3. 下下版本更新计划:增加分支,新增自定义navgation(更个性)、自定义tabbar的功能(个性化+伪tabbar热更新)
    4. 待补充…欢迎issue提建议意见

    咳咳,因在下时间不足及对mpvue开发团队莫得信心,这个级就先不升了,就是这么任性
    建议要做小程序多端开发的同学使用taro,不做多端使用原生小程序

    目录结构

    ├── src // 我们的项目的源码编写文件
    │ ├── components // 组件目录
    │ ├── common //静态资源
    │ │ └── font // iconfont图标
    │ │ └── img // 图片
    │ │ └── js // js
    │ │ │└──  mixins.js // js
    │ │ │└──  tips.js // js
    │ │ │└──  utils.js // js
    │ │ └── scss // scss样式
    │ │ │└──  base.scss // 自定义样式
    │ │ │└──  icon.scss // iconfont图标
    │ │ │└──  index.scss // 基础汇总
    │ │ │└──  mixin.scss // 混合等工具样式
    │ │ │└──  reset.scss // 初始化样式
    │ │ │└──  variable.scss // 全局主题色样式
    │ ├── http //http请求配置文件
    │ │ └── api // 接口调用文件
    │ │ └── config //fly 配置文件
    │ ├── pages //项目页面目录
    │ ├── components //项目复用组件目录
    │ ├── store //状态管理 vuex配置目录
    │ │ └── actions.js //actions异步修改状态
    │ │ └── getters.js //getters计算过滤操作
    │ │ └── mutation-types.js //mutations 类型
    │ │ └── mutations.js //修改状态
    │ │ └── index.js //我们组装模块并导出 store 的地方
    │ │ └── state.js //数据源定义
    │ ├── untils //工具函数目录
    │ │ └── index.js
    │ ├── App.vue // APP入口文件
    │ ├── main.js // 主配置文件
    │ ├── config.js // host等配置
    

    快速创建一个mpvue项目

    # 全局安装 vue-cli
    $ npm install -g vue-cli
     
    # 创建一个基于 mpvue-quickstart 模板的新项目,记得选择安装vuex
    $ vue init mpvue/mpvue-quickstart mpvue-demo
     
    # 安装fly
    $ npm i flyio --save
     
    # 安装依赖
    $ cd mpvue-demo
    $ npm i
    # 启动构建
    $ npm run dev
    

    配置fly

    1、配置公共设置
    src/http/config.js

    /*
        fly配置文件
        by:David 2018.6.14
    */
    //引入 fly
    var Fly = require("flyio/dist/npm/wx")
    var fly = new Fly;
    import config from '@/config'
    //配置请求基地址
    // //定义公共headers
    // fly.config.headers={xx:5,bb:6,dd:7}
    // //设置超时
    fly.config.timeout = 20000;
    // //设置请求基地址
    fly.config.baseURL = config.host
    
    //添加请求拦截器
    fly.interceptors.request.use((request) => {
        //给所有请求添加自定义header
        request.headers["X-Tag"] = "flyio";
        //打印出请求体
        // console.log(request.body)
        //终止请求
        //var err=new Error("xxx")
        //err.request=request
        //return Promise.reject(new Error(""))
    
        //可以显式返回request, 也可以不返回,没有返回值时拦截器中默认返回request
        return request;
    })
    
    //添加响应拦截器,响应拦截器会在then/catch处理之前执行
    fly.interceptors.response.use(
        (response) => {
            //只将请求结果的data字段返回
            return response.data
        },
        (err) => {
            //发生网络错误后会走到这里
            //return Promise.resolve("ssss")
        }
    )
    // Vue.prototype.$http=fly //将fly实例挂在vue原型上
    
    export default fly
    

    2、配置个性设置
    src/http/api.js

    import fly from './config'
    import qs from 'qs'
    
    import config from '../config'
    const host = config.host;
    const appKey = config.appKey;
    const appid = config.appid;
    
    /**
     * 接口模版====post
     *
     * export const test = params => {return fly.post(`${root}/xx/xx`, qs.stringify(params))};
     *
     * 接口模版====get
     *
     * export const test1 = function(){return fly.get(`${root}/api/getNewsList`)}
     *
     *
     * 用法:
     * 在 页面用引入 test
     * import {test} from '../../http/api.js'
     *
     * test(params).then(res=>{ console.log(res) })
     */
    
    // 通用的get请求
    export const get = (params) => {
        return fly.get(`${host}${params.url}`, qs.stringify(params.data))
    };
    
    // 通用的post请求
    export const post = (params) => {
        return fly.post(`${host}${params.url}`, qs.stringify(params.data))
    };
    // 封装的登录请求,根据后台接收方式选择是否加qs.stringify
    export const login = params => {
        return fly.post('/login', params)
    };
    
    
    

    host配置
    config.js

    const host = 'http://xxx.xxx';
    const appid = '';
    const appKey = '';
    const config = {
    	host,
    	appid,
        appKey,
    }
    export default config
    

    配置vuex

    1、目录结构

    │ ├── store      //状态管理 vuex配置目录
    │ │  └── actions.js    //actions异步修改状态
    │ │  └── getters.js    //getters计算过滤操作
    │ │  └── mutation-types.js    //mutations 类型
    │ │  └── mutations.js    //修改状态
    │ │  └── index.js    //我们组装模块并导出 store 的地方
    │ │  └── state.js    //数据源定义
    

    2、main.js中引入store, 并绑定到Vue构造函数的原型上,这样在每个vue的组件都可以通过this.$store访问store对象。

    import store from './store/index'
    Vue.prototype.$store=store;
    

    3、定义初始变量store/state.js

    const state={
     openId: '',
    }
    export default state
    

    4、mutation类型
    方便检测错误和书写,一般写方法

    export const SET_OPEN_ID = 'SET_OPEN_ID'
    

    5、store/mutations.js
    写处理方法

    import * as types from './mutation-types'
    const matations={
    	 /**
    	  * state:当前状态树
    	  * v: 提交matations时传的参数
    	  */
    	 [types.SET_OPEN_ID] (state, v) {
    		 state.openId = v;
    	 },
     
    }
     
    export default matations
    

    6、store/index.js
    汇总配置

    import Vue from 'vue';
    import Vuex from 'vuex';
    import state from './state'
    import mutations from './mutations'
     
    Vue.use(Vuex);
     
    export default new Vuex.Store({
    	state,
    	mutations,
    })
    

    使用vuex

    ps:没有用到复杂计算,因此没有引入getters.jsactions.js
    栗子:App.vue

     <script>
        import { login } from '@/http/api'
        import { mapState, mapMutations } from 'vuex'
        import { SET_OPEN_ID } from './store/mutation-types'
        const App = getApp();
        export default {
            data: {
                globalData: {}
            },
            computed: {
                ...mapState([
                    'openId'
                ])
            },
            methods: {
                ...mapMutations({
                    setOpenId: 'SET_OPEN_ID'
                }),
                // 使用了async+await的语法,用同步的方式写异步脚本
                async login(code) {
                    let _this = this;
                    try {
                        const resData = await login({ code: code });
                        if (resData.returnCode == 200) {
                            _this.setOpenId(resData.data.accountId)
                        }
                    } catch (err) {
                        console.error(err);
                    }
    
                },
                // 拆分wx.login,结构更清晰
                _login() {
                    let _this = this;
                    wx.login({
                        success(res) {
                            if (res.code) {
                                console.log('wx.login成功,code:', res.code);
                                let code = res.code;
                                _this.login(code)
                            } else {
                                _this.$tips.toast('微信登录失败')
                            }
                        }
                    });
                }
            },
            onLaunch() {
                this._login()
            }
        }
    </script>
    

    使用vuex-persistedstate,使vuex状态持久化(缓存到本地)

    store/index.hsexport default中添加配置:

    // 引入vuex-persistedstate,将vuex的数据持久化到本地
    export default new Vuex.Store({
        state,
        mutations,
        getters,
        actions,
        plugins: [
            createPersistedState({
                storage: {
                    getItem: key => wx.getStorageSync(key),
                    setItem: (key, value) => wx.setStorageSync(key, value),
                    removeItem: key => {}
                }
            })
        ]
    })
    

    Tips

    • 遇到安装依赖后,运行项目,但dist下没有app.js等入口文件的,将package.json里的mpvue-loader的版本前的^去掉,删除依赖,重新安装即可
    • 在onLoad周期内执行获取数据等初始化操作,因为mpvue的created钩子执行要早得多(小程序运行时)

    mpvue踩坑及相关教程见:mpvue

    源码在我的github上,链接在文章开头
    如有帮助,欢迎star,不胜感激~

    欢迎加入vue学习交流填坑q群:585472963,群很活跃,氛围很好~

    展开全文
  • mpvue官网

    2018-04-10 11:04:02
    http://mpvue.com/mpvue/
    展开全文
  • mpVue

    2019-05-13 16:54:22
    http://mpvue.com/ 全局安装 vue-cli $ npm install --global vue-cli ...$ vue init mpvue/mpvue-quickstart my-project 安装依赖 $ cd my-project $ npm install 启动构建 $ npm run dev 新增的页...

    http://mpvue.com/

    全局安装 vue-cli

      $ npm install --global vue-cli
    

    创建一个基于 mpvue-quickstart 模板的新项目

      $ vue init mpvue/mpvue-quickstart my-project
    

    安装依赖

      $ cd my-project
      $ npm install
    

    启动构建

      $ npm run dev
    

    新增的页面需要重新 npm run dev 编译

    小程序配置 app.json
    app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。
    pages字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。
    window字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等。

      {
        "pages": [
          "pages/index/index",
          "pages/logs/index"
        ],
        "window": {
          "navigationBarTitleText": "Demo"
        },
        "tabBar": {
          "list": [{
            "pagePath": "pages/index/index",
            "text": "首页"
          }, {
            "pagePath": "pages/logs/logs",
            "text": "日志"
          }]
        },
        "networkTimeout": {
          "request": 10000,
          "downloadFile": 10000
        },
        "debug": true
      }
    

    https://developers.weixin.qq.com/miniprogram/dev/framework/config.html
    工具配置 project.config.json
    通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,例如界面颜色、编译配置等等,当你换了另外一台电脑重新安装工具的时候,你还要重新配置。
    考虑到这点,小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。
    其他配置项细节可以参考文档 开发者工具的配置 。
    页面配置 page.json
    这里的 page.json 其实用来表示 pages/logs 目录下的 logs.json 这类和小程序页面相关的配置。
    如果你整个小程序的风格是蓝色调,那么你可以在 app.json 里边声明顶部颜色是蓝色即可。实际情况可能不是这样,可能你小程序里边的每个页面都有不一样的色调来区分不同功能模块,因此我们提供了 page.json,让开发者可以独立定义每个页面的一些属性,例如刚刚说的顶部颜色、是否允许下拉刷新等等。
    其他配置项细节可以参考文档 页面配置 。
    WXML 模板
    标签名字 小程序的 WXML 用的标签是 view, button, text 等等
    wx:if 这样的属性以及 {{ }} 的表达式

      <view class="container">
        <view class="userinfo">
          <button wx:if="{{!hasUserInfo && canIUse}}"> 获取头像昵称 </button>
          <block wx:else>
            <image src="{{userInfo.avatarUrl}}" background-size="cover"></image>
            <text class="userinfo-nickname">{{userInfo.nickName}}</text>
          </block>
        </view>
        <view class="usermotto">
          <text class="user-motto">{{motto}}</text>
        </view>
      </view>
    

    WXML

      <text>{{msg}}</text>
    

    JS

      this.setData({ msg: "Hello World" })
    

    WXSS 样式
    WXSS 在底层支持新的尺寸单位 rpx
    提供了全局的样式和局部样式。和前边 app.json, page.json 的概念相同,你可以写一个 app.wxss 作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。
    WXSS 仅支持部分 CSS 选择器
    更详细的文档可以参考 WXSS 。
    JS 交互逻辑

      <view>{{ msg }}</view>
      <button bindtap="clickMe">点击我</button>
    

    点击 button 按钮的时候,我们希望把界面上 msg 显示成 “Hello World”,在 button 上声明一个属性: bindtap ,在 JS 文件里边声明了 clickMe 方法来响应这次点击操作:

      Page({
        clickMe: function() {
          this.setData({ msg: "Hello World" })
        }
      })
    

    事件可以参考文档 WXML - 事件
    调用了 wx.getUserInfo 获取微信用户的头像和昵称,最后通过 setData 把获取到的信息显示到界面上。更多 API 可以参考文档 小程序的API

      Page({
        data: { // 参与页面渲染的数据
          logs: []
        },
        onLoad: function () {
          // 页面渲染后 执行
        }
      })
    

    组件

      <map bindmarkertap="markertap" longitude="广州经度" latitude="广州纬度"></map>
    

    更多的组件可以参考 小程序的组件。
    API
    要获取用户的地理位置时:

      wx.getLocation({
        type: 'wgs84',
        success: (res) => {
          var latitude = res.latitude // 经度
          var longitude = res.longitude // 纬度
        }
      })
    

    调用微信扫一扫能力:

      wx.scanCode({
        success: (res) => {
          console.log(res)
        }
      })
    

    需要注意的是:多数 API 的回调都是异步,你需要处理好代码逻辑的异步问题。
    更多的 API 能力见 小程序的API。

    实例生命周期
    同 vue,不同的是我们会在小程序 onReady 后,再去触发 vue mounted 生命周期

      beforeCreate
      created
      beforeMount
      mounted
      beforeUpdate
      updated
      activated
      deactivated
      beforeDestroy
      destroyed
    

    除了 Vue 本身的生命周期外,mpvue 还兼容了小程序生命周期,这部分生命周期钩子的来源于微信小程序的 Page, 除特殊情况外,不建议使用小程序的生命周期钩子。

    app 部分:

      onLaunch,初始化   相当于react的componentDidMount
      onShow,当小程序启动,或从后台进入前台显示
      onHide,当小程序从前台进入后台
      page 部分:
      onLoad,监听页面加载
      onShow,监听页面显示
      onReady,监听页面初次渲染完成
      onHide,监听页面隐藏
      onUnload,监听页面卸载
      onPullDownRefresh,监听用户下拉动作
      onReachBottom,页面上拉触底事件的处理函数
      onShareAppMessage,用户点击右上角分享
      onPageScroll,页面滚动
      onTabItemTap, 当前是 tab 页时,点击 tab 时触发 (mpvue 0.0.16 支持)
      onPageNotFound,页面找不到
    

    用法示例:

      new Vue({
        data: {
          a: 1
        },
        created () {
          // `this` 指向 vm 实例
          console.log('a is: ' + this.a)
        },
        onShow () {
          // `this` 指向 vm 实例
          console.log('a is: ' + this.a, '小程序触发的 onshow')
        }
      })
    

    微信小程序的页面的 query 参数是通过 onLoad 获取的,mpvue 对此进行了优化,直接通过 this.root.root.mp.query 获取相应的参数数据,其调用需要在 onLoad 生命周期触发之后使用,比如 onShow 等,具体生命周期调用顺序,

    1.不支持 纯-HTML
    小程序里所有的 BOM/DOM 都不能用,也就是说 v-html 指令不能用。

    2.不支持部分复杂的 JavaScript 渲染表达式
    我们会把 template 中的 {{}} 双花括号的部分,直接编码到 wxml 文件中,由于微信小程序的能力限制(数据绑定),所以无法支持复杂的 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>
    

    3.不支持过滤器
    渲染部分会转成 wxml ,wxml 不支持过滤器,所以这部分功能不支持。
    4.不支持函数
    不支持在 template 内使用 methods 中的函数。

    5.不支持 官方文档:Class 与 Style 绑定 中的 classObject 和 styleObject 语法。
    class 支持的语法:

      <p :class="{ active: isActive }">111</p>
      <p class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">222</p>
      <p class="static" :class="[activeClass, errorClass]">333</p>
      <p class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">444</p>
      <p class="static" v-bind:class="[{ active: isActive }, errorClass]">555</p>
      style 支持的语法:
      <p v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">666</p>
      <p v-bind:style="[{ color: activeColor, fontSize: fontSize + 'px' }]">777</p>
    
      <template>
          <!-- 支持 -->
          <div class="container" :class="computedClassStr"></div>
          <div class="container" :class="{active: isActive}"></div>
      
          <!-- 不支持 -->
          <div class="container" :class="computedClassObject"></div>
      </template>
    

    列表渲染
    全支持 官方文档:列表渲染
    只是需要注意一点,嵌套列表渲染,必须指定不同的索引!
    示例:

      <template>
          <ul v-for="(card, index) in list">
              <li v-for="(item, itemIndex) in card">
                  {{item.value}}
              </li>
          </ul>
      </template>
    

    事件处理器
    几乎全支持啦 官方文档:事件处理器
    我们引入了 Vue.js 的虚拟 DOM ,在前文模版中绑定的事件会被挂在到 vnode 上,同时我们的 compiler 在 wxml 上绑定了小程序的事件,并做了相应的映射,所以你在真实点击的时候通过 runtime 中 handleProxy 通过事件类型分发到 vnode 的事件上,同 Vue 在 WEB 的机制一样,所以可以做到无损支持。同时还顺便支持了自定义事件和 $emit 机制。
    // 事件映射表,左侧为 WEB 事件,右侧为 小程序 对应事件

      {
          click: 'tap',
          touchstart: 'touchstart',
          touchmove: 'touchmove',
          touchcancel: 'touchcancel',
          touchend: 'touchend',
          tap: 'tap',
          longtap: 'longtap',
          input: 'input',
          change: 'change',
          submit: 'submit',
          blur: 'blur',
          focus: 'focus',
          reset: 'reset',
          confirm: 'confirm',
          columnchange: 'columnchange',
          linechange: 'linechange',
          error: 'error',
          scrolltoupper: 'scrolltoupper',
          scrolltolower: 'scrolltolower',
          scroll: 'scroll'
      }
    

    在 input 和 textarea 中 change 事件会被转为 blur 事件。
    踩坑注意:
    列表中没有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上将bind改为@ @regionchange,同时这个事件也非常特殊,它的 event type 有 begin 和 end 两个,导致我们无法在handleProxy 中区分到底是什么事件,所以你在监听此类事件的时候同时监听事件名和事件类型既 <map @regiοnchange=“functionName” @end=“functionName” @begin=“functionName”>
    小程序能力所致,bind 和 catch 事件同时绑定时候,只会触发 bind ,catch 不会被触发,要避免踩坑。
    事件修饰符
    .stop 的使用会阻止冒泡,但是同时绑定了一个非冒泡事件,会导致该元素上的 catchEventName 失效!
    .prevent 可以直接干掉,因为小程序里没有什么默认事件,比如submit并不会跳转页面
    .capture 支持 1.0.9
    .self 没有可以判断的标识
    .once 也不能做,因为小程序没有 removeEventListener, 虽然可以直接在 handleProxy 中处理,但非常的不优雅,违背了原意,暂不考虑
    其他 键值修饰符 等在小程序中压根没键盘,所以。。。
    表单控件绑定
    建议开发过程中直接使用 微信小程序:表单组件 。用法示例:
    select 组件用 picker 组件进行代替

    <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)
       }   } }
    </script>
    

    表单元素 radio 用 radio-group 组件进行代替

      <template>
        <div>
          <radio-group class="radio-group" @change="radioChange">
            <label class="radio" v-for="(item, index) in items" :key="item.name">
              <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('radio发生change事件,携带value值为:', e.target.value)
          }
        }
      }
      </script>
    

    页面跳转

      <navigator  :class="matchState?'gen-matchCard-warp gen-matchCard-begin': 'gen-matchCard-warp gen-matchCard-end'"
        url="../../pages/schedule/index">
        :url="'../../pages/schedule/index?name=' + macthData.name">
      </navigator>
    

    mptoast 组件代替官方提供的 wx.showToast,

    npm i vuex
    npm i mptoast 
    
    展开全文
  • mpvue的一点心得

    2018-06-25 18:04:10
    页面上为:data里定义一些变量:在methods里定义获取用户信息的函数:然后就可以在mounted里面调用了。2.新增页面的时候,要注意,main.js里的东西不要动,新增页面之后,要执行 npm run dev ,重新运行一下代码。...
  • mpVue的基本介绍

    2018-05-18 16:04:12
    1、快速上手先甩一个官方的教程:http://mpvue.com/mpvue/quickstart/2、目录的基本介绍 src下的目录:其中main.js可以修改我们的TitleBar和颜色,相当于app.json3、事件处理映射表...
  • mpvue踩坑总结

    2019-02-09 23:11:30
    最近使用mpvue进行小程序开发,整理一下各种坑 1、无法使用vue.component进行组件的全局注册; 解决方案:由于mpvue暂时不支持组件的全局注册,所以只能在使用组件的页面中单独引入; 2、在组件中使用wx....
  • 原生小程序开发有哪些痛点? 频繁调用 setData及 setData过程中页面跳闪 强制将WXSS、WXML和JS代码分离到3个不同的文件中 没有状态管理,参考Vuex和Redux 没有过滤器 不能使用 less、scss 等预编译器 ...
  • Mpvue介绍

    2019-08-31 16:12:50
    Mpvue是什么? Mpvue是一个基于Vue的微信小程序前端框架,可以让我们用vue的语法写小程序的项目。简单来说就是,以前我们写微信小程序,必须借助微信小程序的开发者工具,微信开发工具提供的语法才能写小程序,Mpvue...
  • 先列举出来 慢慢填 钩子函数不运行 上来做前后端通信测试,就遇到一个奇怪的问题,钩子函数不运行了。 我也不知道具体是为什么,我觉得可能的原因是删除了东西之后dist是不会直接重新编译的。 ...
  • mpvue虽然同时兼容vue和小程序的生命周期,但有先后之差 了解更多请戳:理解mpvue的生命周期 解决方案 用v-if控制子组件的渲染,判定条件为传入的值,如: 这样,在没有父组件没有获取到数据的情况下,就不会编译子...
  • 原生开发小程序 和 wepy 、 mpvue 对比 本文横向对比、探讨了下原生开发小程序,和目前比较热门的 wepy 、mpvue 开发小程序三种方式的优势和劣势;由于三者的篇幅都比较多,本文只是简单介绍。如有错误,请大神们...
  • 本文编写时间较早,随着时间的推移,mpvue及其周边生态越来越完善,文中的案例已经不适合在项目使用。希望大家参考其他更新的文章~ 简介 微信小程序上线已有一年多时间啦,自美团的mpvue(基于 Vue.js 的小程序开发...
  • mpvue是什么?为什么使用它? 目前小程序开发主要有三种形式:原生、wepy、mpvue,其中wepy是腾讯的开源项目;mpvue是美团开源的一个开发小程序的框架,全称mini program vue(基于vue.js的小程序),vue开发者使用了...
  • 简介:mpvue-entry是集中式页面配置,自动生成各页面的入口文件,优化目录结构,支持新增页面热更新 1.废话不多说,要使用mpvue-entry管理首先需要在package.json中引入依赖后,运行npm install加载依赖 2.引入...
  • 【原文地址】mpvue入门系列教程: 如何在mpvue中正确的引用小程序的原生自定义组件 使用mpvue开发小程序教程(六) 使用mpvue开发小程序教程(五) 使用mpvue开发小程序教程(四) 使用mpvue开发小程序教程(三...
  • mpvue样式绑定总结

    2018-10-27 21:53:24
    mpvue样式绑定 在使用mpvue的时候,很多同学应该会感到很不方便,比如没法用vue-router,没法在js中控制节点的style属性样式,只能通过样官方推荐的样式绑定的办法控制样式,最难受的是不能用slot,不过总的来说...
1 2 3 4 5 ... 20
收藏数 6,497
精华内容 2,598
关键字:

mpvue