关于mpvue:微信小程序传参及接参

// 原生跳转<navigator url=`/pages/counter/main?param=${param}`>去往示例页面</navigator>// a标签跳转<a href=`/pages/counter/main?param=${param}` class="counter">去往示例页面</a>// 传参办法wx.navigateTo({url:`../${page}/main?param=${param}`});// 原生接参办法onLoad(options){ console.log(options); //{'param' : param}}// mpvue接参办法mounted(){ console.log(this.$root.$mp.query) //{'param' : param}}

July 20, 2020 · 1 min · jiezi

mpvue开发小程序的那点小事

mpvuempvue是由美团点评团队开发的, 是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现。 对于拥有Vue开发经验的开发者,使用mpvue开发小程序那是一种不错的体验。与此同时还有一个叫wepy的东东,是一个类Vue的开发风格,但也仅仅是类似,并没有从像mpvue从底层改写。 mpvue的目录架构和使用vue-cli2搭建vue项目的架构可以说是基本差不多,大同小异,包含了 ├── build ├── src│ ├── components│ ├── pages│ ├── utils│ ├── App.vue│ └── main.js├── config│ ├── index.js│ ├── dev.env.js│ └── prod.env.js└── static 其实使用mpvue开发小程序那种感觉和使用vue开发H5网页,只是对应的插件和API有所不同,当然mpvue也有很多坑在里面,在这里就和大家分享一下。 ①·就目前来说,没有专属于mpvue的UI组件,当然可以把其他UI组件的代码复制过来也是可以的。②·在跳转页面的时候,如果使用mpvue开发,那么跳转的之前页面的数据并没有重置,而原生小程序是会重置的,所以对于没有重置的数据,会带来一定的数据混乱隐患,需要去手动清除数据。③·mpvue的性能问题,有人做过测试,根据实验的结果来看,mvpue的性能不太好,并且我自身在使用mpvue-parse解析富文本内容的时候,数据如果达到几十K,那么渲染的页面会很卡顿,包括JS的响应也很慢。④·mpvue由于没有app.js,那么也就没有globaldata,对于全局变量,我们可以利用global对象来存储⑤·在使用vue开发过程中,如果获取的ajax数据没有涉及到dom,我们一般会选择在created阶段中获取。但是在mpvue中,created的生命周期在APP Launch之前,如果选择在created获取数据的话,后果可想而知,所有页面的在首页进入的时候就会获取数据,所以在mpvue中,获取数据一般选择在mounted阶段。 mpvue这个框架如果在开发时间成本的约束下,是具有一定的优势,如果在时间充裕的情况下,建议使用原生开发!

June 17, 2019 · 1 min · jiezi

小程序scrollview安卓机隐藏横向滚动条的实现

一、实践踩坑项目使用mpvue开发 1.使用flex布局 // html大概长这样 <div class="worth-wraper"> <scroll-view scroll-x="true" scroll-left="0"> <div class="worth-list"> <div class="worth-item-img"> <img src="/static/images/index/brand1.png" alt=""> </div> <div class="worth-item-img"> <img src="/static/images/index/brand2.png" alt=""> </div> <div class="worth-item-img"> <img src="/static/images/index/brand3.png" alt=""> </div> <div class="worth-item-img"> <img src="/static/images/index/brand4.png" alt=""> </div> </div> </scroll-view></div>// css相应就大概长这样 .worth-wraper{ margin-top: 60rpx;height: 560rpx;box-sizing: border-box;display: flex;width: 750rpx;overflow: hidden;font-size: 28rpx;color: #7a7269;line-height: 42rpx;.worth-list{ display: flex; margin-left: 30rpx; .worth-item-img{ flex: 1; margin-right: 20rpx; width: 290rpx; height: 560rpx; } img{ width: 290rpx; height: 560rpx; } .worth-item{ padding: 0 35rpx 0 40rpx; flex: 1; box-sizing: border-box; background: url("../../../static/images/index/worth-bg1.png") no-repeat; background-size: 100% 100%; width: 290rpx; height: 560rpx; margin-right: 20rpx; }}} ...

May 15, 2019 · 1 min · jiezi

mpvue小程序循环动画开启暂停

用小程序的animation属性实现循环动画的开启与暂停,并封装到组件。 实现一个字体图标组件的循环旋转动画开启/暂停 用于点击图标,字体颜色变换,开始循环旋转动画,并刷新内容刷新结束,停止动画,并设置字体颜色为原来的主要利用setInterval定时器循环执行动画首先,组件写出来添加点击事件,动画属性,style属性(用来动态修改样式) src/components/refresh.vue<template> <div> <div class="iconfont icon-shuaxin" :animation='refreshA' @click="refresh" :style='style'></div> </div></template>设置初始数据使用一个 布尔 数据refreshing判断动画的状态为开启true/暂停false <script>export default { data () { return { refreshA: null, style: 'color: #eee;', // 用来设置存储旋转的度数 rotate: 0, // 存储定时器id refreshI: null } }, props: ['refreshing']}</script>添加点击事件函数<script>export default { methods: { // 刷新按钮点击 refresh () { // 正在刷新 则跳出,避免在循环动画执行时,再次出发点击刷新事件 if (this.refreshing) return // 否则提交刷新事件 this.$emit('refresh') }, // 刷新动画结束 refreshend () { // 当动画结束,字体颜色恢复原来 this.style = 'color: #eee;' } }}</script>监听refreshing状态<script>export default { watch: { refreshing (newV, oldV) { // 没有正在刷新 > 正在刷新 设置循环动画 if (newV && !oldV) { this.style = 'color: #fff;' this.refreshI = setInterval(() => { // 每次 +360 实现每 300 毫秒旋转 360 度 this.rotate += 360 let animation = wx.createAnimation() animation.rotateZ(this.rotate).step() this.refreshA = animation.export() }, 300) return } // 从正在刷新 > 刷新完成 清空循环定时器动画 if (!newV && oldV) { // 防止网速过快,动画队列还没生成就刷新完成,这里判断动画队列是否为空 // 为空,就重置一下样式 if (!this.refreshA) this.style = 'color: #eee;' clearInterval(this.refreshI) this.refreshA = null } } }}</script>需要注意的是定时器时间必须和动画的过渡时间设置为相同组件调用src/pages/index/index.vue<template> <div> <Refresh @refresh='refresh' :refreshing='refreshing'/> </div></template><script>import Refresh from '@/components/refresh'export default { data: { // 初始状态肯定为 false ,点击刷新组件后,在事件函数中再设置为 true refreshing: false }, components: { Refresh }, methods: { async refresh () { this.refreshing = true // 这里为一个异步请求api let data = await api.getData() // 请求完成,执行想要操作的代码后,设置动画为 false // this.data = data this.refreshing = false } }}</script><style lang="stylus" scoped></style>refresh组件完整代码<template> <div> <div class="iconfont icon-shuaxin" :animation='refreshA' @click="refresh" :style='style'></div> </div></template><script>export default { data () { return { refreshA: null, style: 'color: #eee;', rotate: 0, refreshI: null } }, props: ['refreshing'], watch: { refreshing (newV, oldV) { if (newV && !oldV) { this.style = 'color: #fff;' this.refreshI = setInterval(() => { this.rotate += 360 let animation = wx.createAnimation() animation.rotateZ(this.rotate).step() this.refreshA = animation.export() }, 300) return } if (!newV && oldV) { if (!this.refreshA) this.style = 'color: #eee;' clearInterval(this.refreshI) this.refreshA = null } } }, methods: { refresh () { if (this.refreshing) return this.$emit('refresh') }, refreshend () { this.style = 'color: #eee;' } }}</script><style lang="stylus" scoped></style>效果正常效果,看图中右上角 ...

May 14, 2019 · 2 min · jiezi

mpvue骨架屏vue骨架屏原生微信小程序wxml骨架屏分享笔记

mpvue小程序骨架屏可查看这篇文章《小程序骨架屏》 原生微信小程序wxml骨架屏可参考作者腾讯的git项目:《skeleton》 vue骨架屏vue-skeleton-webpack-plugin 骨架屏框架,多种样式 方法一:(SPA 中单个 Skeleton) 可参考这个文章《vue-cli 构建的项目如何加入骨架屏 skeleton》 方法二:(SPA 中多个 Skeleton)这里和方法一相同的创建和build里创建流程一样。主要修改的里面的代码: src下创建2种骨架屏展示,然后可根据不同路由页面,进行显示其他一种,下面实现路由分配 /build/webpack.skeleton.conf.js 修改为: 'use strict';const path = require('path')const merge = require('webpack-merge')const baseWebpackConfig = require('./webpack.base.conf')const nodeExternals = require('webpack-node-externals')const utils = require('./utils')const config = require('../config')const isProduction = process.env.NODE_ENV === 'production'const sourceMapEnabled = isProduction ? config.build.productionSourceMap : config.dev.cssSourceMapfunction resolve(dir) { return path.join(__dirname, dir)}let skeletonWebpackConfig = merge(baseWebpackConfig, { target: 'node', devtool: false, entry: { app: resolve('../src/entry-skeleton.js') }, output: Object.assign({}, baseWebpackConfig.output, { libraryTarget: 'commonjs2' }), externals: nodeExternals({ whitelist: /\.css$/ }), plugins: []})// important: enable extract-text-webpack-pluginskeletonWebpackConfig.module.rules[0].options.loaders = utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: true}),module.exports = skeletonWebpackConfig/build/webpack.dev.conf.js 和 /build/webpack.prod.conf.js 修改为 ...

April 29, 2019 · 1 min · jiezi

基于mpvue小程序使用echarts画折线图

第一次使用mpvue框架来写小程序,项目开发直接搬用mpvue-shop(一个仿网易严选的小程序开发项目),项目结构清楚,实现了大部分功能,对于初次使用mpvue的小伙伴们来说,是一个很好的选择。关于组件的选择:1.echarts-for-weixin,官方echarts的小程序版本。使用参考:echarts-for-weixin介绍,如果你是原生开发小程序版本,这个组件非常适合你,开发过程中可使用echarts官方提供的所有配置和Api,但并不适合mpvue项目。 2、wx-charts,一个个人开发的微信小程序图表插件,体积只有30K,可用于mpvue项目和原生小程序项目,支持大部分图表绘制,缺点是可配置化不强,对于UI没有太大要求的可使用此组件,比较适合于个人项目开发。 3、mpvue-echarts与echarts结合。特别适合mpvue项目,mpvue-echarts是一个基于mpvue开发的echarts组件,echarts的加入可完全使用官方所有的图表绘制功能,让echarts在小程序当中得到全部应用。 mpvue-echarts配合echarts的使用下载相关包 npm install mpvue-echarts --save echarts的下载可到官网上下载,由于小程序中对文件大小有限制,建议通过勾选所需要的功能按需下载。 vue文件中使用 template: <mpvue-echarts :echarts="echarts" :onInit="initChart" canvasId="demo-canvas" /> js: import mpvueEcharts from 'mpvue-echarts';let echarts = require("../../../static/lib/echarts.min.js"); //按需下载的压缩文件放在项目文件夹中import charts from './charts'; //本地mixin文件,图表的所有配置let chart = null;export default { data() { return { echarts, }; }, async mounted() { let data = await post("/product/marketInfo",{ }); this.initCombineLineData(data.trendData); chart.setOption(this.trendChart); }, mixins: [charts], methods: { initChart(canvas, width, height) { chart = echarts.init(canvas, null, { width: width, height: height }); canvas.setChart(chart); chart.setOption(this.trendChart); return chart; } }, components: { mpvueEcharts }}charts.js文件 ...

April 24, 2019 · 2 min · jiezi

【已解决】mpvue使用微信小程序map中的bindregionchange失效问题

<map @regionchange=“regionChange” @begin=“regionChangeBegin” @end=“regionChangeEnd”><map>官方微信小程序只写bindregionchange即可,但是mpvue需要上面三个方法都需要写。如果不写@regionchange,则不会触发后面两个方法@begin和@end

April 18, 2019 · 1 min · jiezi

mpvue设置标题navigationBarTitleText问题,新版需要创建main.json

{ “navigationBarTitleText”: “电池更换记录”}新版需要创建main.json文件旧版是在main.js里export default {}

April 11, 2019 · 1 min · jiezi

使用mpvue开发微信小程序——音乐小程序源码分享

使用mpvue开发微信小程序——音乐小程序项目源码分享:文章链接源码链接:https://github.com/XieTongXue…

April 9, 2019 · 1 min · jiezi

mpvue 学习笔记 ------ 一、简介

正在学习中 当笔记记录一下什么是 mpvuempvue 是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。参考网站:http://mpvue.com配置好后 小程序和编辑器连接电脑里搜索git bush 右键 以管理员的身份运行cd进入自己项目目录 (cd ~/Desktop cd 你的目录 如果不行就一层一层的进 cd E: cd WX)最后跑起来 就可以和小程序连接了 npm run dev

April 8, 2019 · 1 min · jiezi

小程序多端框架全面测评:chameleon、Taro、uni-app、mpvue、WePY

摘要: 微信小程序开发技巧。作者:coldsnap原文:小程序多端框架全面测评Fundebug经授权转载,版权归原作者所有。最近前端届多端框架频出,相信很多有代码多端运行需求的开发者都会产生一些疑惑:这些框架都有什么优缺点?到底应该用哪个?作为 Taro 开发团队一员,笔者想在本文尽量站在一个客观公正的角度去评价各个框架的选型和优劣。但宥于利益相关,本文的观点很可能是带有偏向性的,大家可以带着批判的眼光去看待,权当抛砖引玉。那么,当我们在讨论多端框架时,我们在谈论什么:多端笔者以为,现在流行的多端框架可以大致分为三类:1. 全包型这类框架最大的特点就是从底层的渲染引擎、布局引擎,到中层的 DSL,再到上层的框架全部由自己开发,代表框架是 Qt 和 Flutter。这类框架优点非常明显:性能(的上限)高;各平台渲染结果一致。缺点也非常明显:需要完全重新学习 DSL(QML/Dart),以及难以适配中国特色的端:小程序。这类框架是最原始也是最纯正的的多端开发框架,由于底层到上层每个环节都掌握在自己手里,也能最大可能地去保证开发和跨端体验一致。但它们的框架研发成本巨大,渲染引擎、布局引擎、DSL、上层框架每个部分都需要大量人力开发维护。2. Web 技术型这类框架把 Web 技术(JavaScript,CSS)带到移动开发中,自研布局引擎处理 CSS,使用 JavaScript 写业务逻辑,使用流行的前端框架作为 DSL,各端分别使用各自的原生组件渲染。代表框架是 React Native 和 Weex,这样做的优点有:开发迅速复用前端生态易于学习上手,不管前端后端移动端,多多少少都会一点 JS、CSS缺点有:交互复杂时难以写出高性能的代码,这类框架的设计就必然导致 JS 和 Native 之间需要通信,类似于手势操作这样频繁地触发通信就很可能使得 UI 无法在 16ms 内及时绘制。React Native 有一些声明式的组件可以避免这个问题,但声明式的写法很难满足复杂交互的需求。由于没有渲染引擎,使用各端的原生组件渲染,相同代码渲染的一致性没有第一种高。3. JavaScript 编译型这类框架就是我们这篇文章的主角们:Taro、WePY 、uni-app 、 mpvue 、 chameleon,它们的原理也都大同小异:先以 JavaScript 作为基础选定一个 DSL 框架,以这个 DSL 框架为标准在各端分别编译为不同的代码,各端分别有一个运行时框架或兼容组件库保证代码正确运行。这类框架最大优点和创造的最大原因就是小程序,因为第一第二种框架其实除了可以跨系统平台之外,也都能编译运行在浏览器中。(Qt 有 Qt for WebAssembly, Flutter 有 Hummingbird,React Native 有 react-native-web, Weex 原生支持)另外一个优点是在移动端一般会编译到 React Native/Weex,所以它们也都拥有 Web 技术型框架的优点。这看起来很美好,但实际上 React Native/Weex 的缺点编译型框架也无法避免。除此之外,编译型框架的抽象也不是免费的:当 bug 出现时,问题的根源可能出在运行时、编译时、组件库以及三者依赖的库等等各个方面。在 Taro 开源的过程中,我们就遇到过 Babel 的 bug,React Native 的 bug,JavaScript 引擎的 bug,当然也少不了 Taro 本身的 bug。相信其它原理相同的框架也无法避免这一问题。但这并不意味着这类为了小程序而设计的多端框架就都不堪大用。首先现在各巨头超级 App 的小程序百花齐放,框架会为了抹平小程序做了许多工作,这些工作在大部分情况下是不需要开发者关心的。其次是许多业务类型并不需要复杂的逻辑和交互,没那么容易触发到框架底层依赖的 bug。那么当你的业务适合选择编译型框架时,在笔者看来首先要考虑的就是选择 DSL 的起点。因为有多端需求业务通常都希望能快速开发,一个能够快速适应团队开发节奏的 DSL 就至关重要。不管是 React 还是 Vue(或者类 Vue)都有它们的优缺点,大家可以根据团队技术栈和偏好自行选择。如果不管什么 DSL 都能接受,那就可以进入下一个环节:生态以下内容均以各框架现在(2019 年 3 月 11 日)已发布稳定版为标准进行讨论。1. 开发工具就开发工具而言 uni-app 应该是一骑绝尘,它的文档内容最为翔实丰富,还自带了 IDE 图形化开发工具,鼠标点点点就能编译测试发布。其它的框架都是使用 CLI 命令行工具,但值得注意的是 chameleon 有独立的语法检查工具,Taro 则单独写了 ESLint 规则和规则集。在语法支持方面,mpvue、uni-app、Taro 、WePY 均支持 TypeScript,四者也都能通过 typing 实现编辑器自动补全。除了 API 补全之外,得益于 TypeScript 对于 JSX 的良好支持,Taro 也能对组件进行自动补全。CSS 方面,所有框架均支持 SASS、LESS、Stylus,Taro 则多一个 CSS Modules 的支持。所以这一轮比拼的结果应该是:uni-app > Taro > chameleon > WePY、mpvue2. 多端支持度只从支持端的数量来看,Taro 和 uni-app 以六端略微领先(移动端、H5、微信小程序、百度小程序、支付宝小程序、头条小程序),chameleon 少了头条小程序紧随其后。但值得一提的是 chameleon 有一套自研多态协议,编写多端代码的体验会好许多,可以说是一个能戳到多端开发痛点的功能。uni-app 则有一套独立的条件编译语法,这套语法能同时作用于 js、样式和模板文件。Taro 可以在业务逻辑中根据环境变量使用条件编译,也可以直接使用条件编译文件(类似 React Native 的方式)。在移动端方面,uni-app 基于 weex 定制了一套 nvue 方案 弥补 weex API 的不足;Taro则是暂时基于 expo 达到同样的效果;chameleon 在移动端则有一套 SDK 配合多端协议与原生语言通信。H5 方面,chameleon 同样是由多态协议实现支持,uni-app 和 Taro 则是都在 H5 实现了一套兼容的组件库和 API。mpvue 和 WePY 都提供了转换各端小程序的功能,但都没有 h5 和移动端的支持。所以最后一轮对比的结果是:chameleon > Taro、uni-app > mpvue > WePY3. 组件库/工具库/demo作为开源时间最长的框架,WePY 不管从 Demo,组件库数量 ,工具库来看都占有一定优势。uni-app 则有自己的插件市场和 UI 库,如果算上收费的框架和插件比起 WePy 也是完全不遑多让的。Taro 也有官方维护的跨端 UI 库 taro-ui ,另外在状态管理工具上也有非常丰富的选择(Redux、MobX、dva),但 demo 的数量不如前两个。但 Taro 有一个转换微信小程序代码为 Taro 代码的工具,可以弥补这一问题。而 mpvue 没有官方维护的 UI 库,chameleon 第三方的 demo 和工具库也还基本没有。所以这轮的排序是:WePY > uni-app 、taro > mpvue > chameleon4. 接入成本接入成本有两个方面:第一是框架接入原有微信小程序生态。由于目前微信小程序已呈一家独大之势,开源的组件和库(例如 wxparse、echart、zan-ui 等)多是基于原生微信小程序框架语法写成的。目前看来 uni-app 、Taro、mpvue 均有文档或 demo 在框架中直接使用原生小程序组件/库,WePY 由于运行机制的问题,很多情况需要小改一下目标库的源码,chameleon 则是提供了一个按步骤大改目标库源码的迁移方式。第二是原有微信小程序项目部分接入框架重构。在这个方面 Taro 在京东购物小程序上进行了大胆的实践,具体可以查看文章《Taro 在京东购物小程序上的实践》。其它框架则没有提到相关内容。而对于两种接入方式 Taro 都提供了 taro convert 功能,既可以将原有微信小程序项目转换为 Taro 多端代码,也可以将微信小程序生态的组件转换为 Taro 组件。所以这轮的排序是:Taro > mpvue 、 uni-app > WePY > chameleon流行度从 GitHub 的 star 来看,mpvue 、Taro、WePY 的差距非常小。从 NPM 和 CNPM 的 CLI 工具下载量来看,是 Taro(3k/week)> mpvue (2k/w) > WePY (1k/w)。但发布时间也刚好反过来。笔者估计三家的流行程度和案例都差不太多。uni-app 则号称有上万案例,但不像其它框架一样有一些大厂应用案例。另外从开发者的数量来看也是 uni-app 领先,它拥有 20+ 个 QQ 交流群(最大人数 2000)。所以从流行程度来看应该是:uni-app > Taro、WePY、mpvue > chameleon5. 开源建设一个开源作品能走多远是由框架维护团队和第三方开发者共同决定的。虽然开源建设不能具体地量化,但依然是衡量一个框架/库生命力的非常重要的标准。从第三方贡献者数量来看,Taro 在这一方面领先,并且 Taro 的一些核心包/功能(MobX、CSS Modules、alias)也是由第三方开发者贡献的。除此之外,腾讯开源的 omi 框架小程序部分也是基于 Taro 完成的。WePY 在腾讯开源计划的加持下在这一方面也有不错的表现;mpvue 由于停滞开发了很久就比较落后了;可能是产品策略的原因,uni-app 在开源建设上并不热心,甚至有些部分代码都没有开源;chameleon 刚刚开源不久,但它的代码和测试用例都非常规范,以后或许会有不错的表现。那么这一轮的对比结果是:Taro > WePY > mpvue > chameleon > uni-app最后补一个总的生态对比图表:未来从各框架已经公布的规划来看:WePY 已经发布了 v2.0.alpha 版本,虽然没有公开的文档可以查阅到 2.0 版本有什么新功能/特性,但据其作者介绍,WePY 2.0 会放大招,是一个「对得起开发者」的版本。笔者也非常期待 2.0 正式发布后 WePY 的表现。mpvue 已经发布了 2.0 的版本,主要是更新了其它端小程序的支持。但从代码提交, issue 的回复/解决率来看,mpvue 要想在未来有作为首先要打消社区对于 mpvue不管不顾不更新的质疑。uni-app 已经在生态上建设得很好了,应该会在此基础之上继续稳步发展。如果 uni-app 能加强开源开放,再加强与大厂的合作,相信未来还能更上一层楼。chameleon 的规划比较宏大,虽然是最后发的框架,但已经在规划或正在实现的功能有:快应用和端拓展协议通用组件库和垂直类组件库面向研发的图形化开发工具面向非研发的图形化页面搭建工具如果 chameleon 把这些功能都做出来的话,再继续完善生态,争取更多第三方开发者,那么在未来 chameleon 将大有可为。Taro 的未来也一样值得憧憬。Taro 即将要发布的 1.3 版本就会支持以下功能:快应用支持Taro Doctor,自动化检查项目配置和代码合法性更多的 JSX 语法支持,1.3 之后限制生产力的语法只有 只能用 map 创造循环组件 一条H5 打包体积大幅精简同时 Taro 也正在对移动端进行大规模重构;开发图形化开发工具;开发组件/物料平台以及图形化页面搭建工具。结语那说了那么多,到底用哪个呢?如果不介意尝鲜和学习 DSL 的话,完全可以尝试 WePY 2.0 和 chameleon ,一个是酝酿了很久的 2.0 全新升级,一个有专门针对多端开发的多态协议。uni-app 和 Taro 相比起来就更像是「水桶型」框架,从工具、UI 库,开发体验、多端支持等各方面来看都没有明显的短板。而 mpvue 由于开发一度停滞,现在看来各个方面都不如在小程序端基于它的 uni-app 。当然,Talk is cheap。如果对这个话题有更多兴趣的同学可以去 GitHub 另行研究,有空看代码,没空看提交:chameleon: https://github.com/didi/chameleonmpvue: https://github.com/Meituan-Dianping/mpvueTaro: https://github.com/NervJS/tarouni-app: https://github.com/dcloudio/uni-appWePY: https://github.com/Tencent/wepy(按字母顺序排序)关于FundebugFundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家免费试用! ...

March 28, 2019 · 2 min · jiezi

微信小程序scroll-view横向滚动的实践踩坑及隐藏其滚动条的实现

一、实践踩坑项目使用mpvue开发1. scroll-view默认是不滚动的。。所以要先设置scroll-x=“true"或者scroll-y=“true"2. 在scroll-view里面添加定宽元素,超过scroll-view宽度(设置了100%,即屏幕宽度)后,它竟然换行了。所以要scroll-view的样式要这样设置: scroll-view { width: 100%; white-space: nowrap; // 不让它换行 }3. 然后在定宽元素里边添加子容器:// html大概长这样<scroll-view scroll-x=“true”> <div class=“tab-item”> <img class=“content-icon”/> <div></div> </div> <div class=“tab-item”> <img class=“content-icon”/> <div></div> </div> <div class=“tab-item”> <img class=“content-icon”/> <div></div> </div></scroll-view>// css相应就大概长这样scroll-view { display: flex; flex-wrap: nowrap;}.tab-item { display: flex; justify-content: center; width: 25%; …}然后发现.tab-item并没有排在一行上。。说明scroll-view和.tab-item都设置display: flex无效?无奈之下,只好在它外边再包一层,然后样式设置display: inline-block。此时正确姿势如下:// html<div class=“scroll-view-container”> <scroll-view scroll-x=“true” :scroll-into-view=“toView”> <div class=“tab-container”> <div class=“tab-item”> <img class=“content-icon”/> <div></div> </div> </div> </scroll-view></div>// css变成这样子scroll-view { width: 100%; white-space: nowrap; // 不让它换行}.tab-container { display: inline-block; width: 25%;}.tab-item { display: flex; flex-direction: column; align-items: center; …}到这里,scroll-view就基本如我所愿了,大概长这样:二、隐藏滚动条在网上搜了很多,都是说加上这段代码就可以:/隐藏滚动条/::-webkit-scrollbar{ width: 0; height: 0; color: transparent;}或者有的人说这样子:/隐藏滚动条/::-webkit-scrollbar{ display: none;}然而两种方法我都试过,scroll-view的滚动条依然存在。。测试机型是安卓机子。但是用display: none这种方法是可以隐藏掉页面的滚动条的,就是scroll-view的滚动条没隐藏掉。后来,在小程序社区看到官方人员这样子解答:是的,就是这种野路子。当然 ,它下面的评论里也有人提供了另一种解决思路方法,但我还是选择了官方说的那种野路子方法。传送门实现思路就是,在scroll-view外边再包一个容器,它的高度小于scroll-view的高度,这样就会截掉滚动条,达到隐藏了滚动条的效果。// scss.scroll-view-container { // 包裹scroll-view的容器 height: $fakeScrollHeight; overflow: hidden; // 这个设置了就能截掉滚动条啦 scroll-view { width: 100%; white-space: nowrap; } } .tab-container { // 我这里是用.tab-container来撑开scroll-view的高度,所以高度在它上面设置,加上padding,那么它就会比外层容器(.scroll-view-container)要高 display: inline-block; width: 26%; height: $fakeScrollHeight; padding-bottom: $scrollBarHeight; }大概意思是这样: ...

March 14, 2019 · 1 min · jiezi

mpvue开发音频类小程序踩坑和建议

前言这是我第一次开发小程序,开发的产品是音频类的,在大佬的建议下采用了mpvue,一周时间把功能都做出来,由于不太熟悉mpvue和微信小程序,足足用了一周时间来改bug才出来一个能用的版本,在这里整理分享下我开发时遇到的一些问题和给出一些建议。在Linux上开发小程序在公司电脑装了双系统,日常用的是Ubuntu系统,Linux或Mac的开发环境对前端相对来说会友好一些。微信小程序官方的开发者工具只有Windows和Mac版本,所以这就尴尬了。不过还好,发现已经有大神在GitHub上做了Linux的支持,推荐给大家:Linux微信web开发者工具。根据教程安装使用即可,使用时就用./bin/wxdt命令打开。不过用了几天后面觉得不太方便,就索性切回Windows系统用官方最新的版本了。封装wx.request为Promisewx.request用于发起http请求,但平时习惯了Promise的写法,所以还是封装一下这个方法为Promise的形式。我看很多小程序会使用fly这个库。但个人觉得发起请求不需要那么强大的功能,小程序本身就应该是一个轻量级的东西,引入一个库可能会导致项目打包变大,可能让小程序更卡,所以本着能自己写就自己写吧的心态,索性自己封装一下算了。在src/utils,新建一个request.js:const apiUrl = ‘https://your server.com/api/‘const request = (apiName, reqData, isShowLoading = true) => { // 某些请求可能不需要显示loading if (isShowLoading) { wx.showLoading({ title: ‘正在努力加载中’, mask: true }) } return new Promise(function (resolve, reject) { wx.request({ url: apiUrl + apiName, method: ‘POST’, data: reqData, header: { ‘content-type’: ‘application/json’ // 默认值 }, success (res) { if (res.data.code === 0) { // 与后端约定code=0时才是正常的 resolve(res) } else { reject(res) } }, fail (err) { reject(err) }, complete (res) { wx.hideLoading() } }) })}export default request当然这是个简化版的,我实际项目中还会在初始化时加入一些token之类的参数,大家能看明白是这样封装成Promise的就可以啦。使用vant-weapp小程序已经支持了npm安装,但不太会弄。还是按网上方法,将项目clone下来放进static目录下。git clone https://github.com/youzan/vant-weapp.git然后将vant-weapp的dist目录拷贝到项目的static目录下(尽可能精简,删掉一些奇奇怪怪的如.github的东西,所以直接使用dist目录),改名为vant(也可以不改名)。全局使用时,可以在app.json引入: “usingComponents”: { “van-button”: “/static/vant/button/index”, “van-field”: “/static/vant/field/index” },注意:需要打开微信开发者工具中的ES6转ES5功能一开始以为使用起来和web端的没啥差别,但没想到那么麻烦。比如:在vue中是可以使用v-model的,但在mpvue中的小程序中不能使用,只能<van-field :value=“password” type=“password” @change=“pwdChange” input-class=“myClass” />而且不能随意灵活添加class修改组件的样式,需要vant组件支持提供外部样式才可修改,比如上面的van-field是通过input-class来添加样式控制的,很不方便。而且某些内部样式由于没有外部样式表,根本改不了。综上: 在微信小程序使用第三方组件库不太方便,样式修改比较麻烦,如果产品是有UI设计时,尽量不使用,有时候自己实现样式可能更快,而且项目体积更小。使用vuexmpvue官方的快速模板中是将vuex放在counter 这个page目录下,可能习惯了vue官方写法的很多同学(包括我)不太喜欢,所以最好就改为vuex官方的写法。在src目录下建一个store的文件夹,分别建以下文件:项目不太复杂时不建议使用modules,使用起来比较麻烦。贴一下index.js的代码,其他的actions.js,getters.js按官方的写法就好啦。import Vue from ‘vue’import Vuex from ‘vuex’import * as actions from ‘./actions’import * as getters from ‘./getters’import state from ‘./state’import mutations from ‘./mutations’import createLogger from ‘vuex/dist/logger’Vue.use(Vuex)const debug = process.env.NODE_ENV !== ‘production’export default new Vuex.Store({ actions, getters, state, mutations, strict: debug, plugins: debug ? [createLogger()] : []})vuex/dist/logger是vuex在开发环境可以自动打印日志的工具,debug比较方便,建议使用。然后在src/main.js引入:import Vue from ‘vue’import App from ‘./App’import store from ‘@/store’Vue.config.productionTip = falseApp.mpType = ‘app’Vue.prototype.$store = storeconst app = new Vue({ store})app.$mount()这样就可以在项目中正常使用啦,完全支持mapState,mapActions,mapGetters的写法,比如在pages/index/index.vue中使用:<script>import { mapState, mapActions } from ‘vuex’export default { computed: { …mapState([‘myAudio’]) }, methods: { …mapActions([‘myActions’]) }, created () { this.myActions() //调用vuex中的方法 }}</script>踩坑指南其实大多数坑可能是mpvue的,很多情况也是自己不熟悉小程序生命周期导致的一些奇奇怪怪的bug。mpvue是支持小程序原生组件的mpvue会将div编译为小程序中的view。一开始我不了解,以为用了mpvue后就不能使用小程序原生支持的组件了,比如swiper,scroll-view等,小程序是支持的,可以放心使用哈哈。npm run build后样式丢失本来在开发环境正常的,然后准备发版npm run build后发现样式丢失了。然后重新npm start排查问题,样式还是丢失的。内心此时是mmp的:npm run build丢失就算了,我没改什么东西重新npm start后为什么还是丢失,之前还是正常的呀?刚开始怀疑是缓存什么的问题,删掉的dist目录,重启开发者工具,甚至重启电脑都试了一下,这是我遇到的超级诡异的问题之一。冷静下来想到:之前的版本是正常的,一定是新版本引入了什么导致了打包样式的丢失。于是回滚版本一个个build排查问题,最后找到了原因:在一个page中引入了其他page,即在页面中import另一个页面。在我这里的具体例子是:我在pages/index/index.vue 中想做底部共用一个tabbar,页面根据tabbar的值来显示对应的子级页面:pages/page1/index.vue和pages/page2/index.vue。所以我将这两个页面当做子组件来引入了:import Page1 from ‘@/pages/page1’,一开始没有问题,等重启项目,或者build后就发现样式丢失了。这可能是mpvue打包机制的一个限制,即页面不能将另一个页面当子组件来引用,否则会导致样式丢失。背景音频的src无法读取项目中希望用户退出小程序后依然能播放音频,所以用到了背景音频的api: wx.getBackgroundAudioManager()。this.audio = wx.getBackgroundAudioManager()this.audio.src = ‘http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E061FF02C31F716658E5C81F5594D561F2E88B854E81CAAB7806D5E4F103E55D33C16F3FAC506D1AB172DE8600B37E43FAD&fromtag=46' this.audio.title = ‘此时此刻’ //注意必填this.audio.epname = ‘此时此刻’this.audio.singer = ‘许巍’this.audio.coverImgUrl = ‘http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000'title和src赋值后会直接播放音频,后面的几个属性建议也填上,因为播放背景音频时微信是有个界面需要封面图和歌手名称等的。如果想要获取当前正在播放的音频src,本来以为通过this.audio.src来获取就可以了但是有bug。在开发者工具中是可以正常获取的,即开发时是没问题的,但在真机上返回的是undefined,因此不能用this.audio.src来获取当前播放的音频url,得用一个变量来存这个数据。直接使用音频的currentTime可能渲染不及时currentTime用于显示当前的播放进度,但我用在子组件中时经常更新不及时,打印是正常的,但试图渲染不及时,有时候需要点击一下才能重新渲染,这可能是mpvue使用时才会遇到。所以建议还是项目自身维护一套背景音频的变量比较好一点,比如放在vuex中。监听BackgroundAudioManager.onTimeUpdate()方法每次赋值到自身维护的变量中。音频的onCanplay方法不一定每个音频都会触发一开始我监听在onCanplay方法,将音频的时长信息duration赋值到vuex中存起来,但发现onCanplay有时候是不会触发的,比如重新赋值src播放下一首时,很尴尬。所以不要太依赖onCanplay这个方法,还好目前直接使用audio.duration好像不会出现像上面的currentTime渲染不及时的问题,所以就这样用着先。音频播放结束,即onStop后,不能再通过audio.play()的方法重新播放,得重新赋值src正常来说,音频播放结束后,音频的src是不变的,再次play()应该是可以的。但在小程序中偏偏不行,得重新赋值src才能重新播放,这应该是小程序的一个bug。。。所以需要判断一下暂停和停止的情况,用不同的办法播放。正常来说,音频暂停时currentTime是不为0的,而结束时currentTime会为0。所以可以通过currentTime(最好是自己维护的变量)来判断暂停和停止的情况:如果currentTime不为0,表示是暂停的情况,可以用play(),如果小于等于0,则重新赋值src播放:if (currentTime) { this.audio.play()} else { this.audio.src = ‘xx.mp3’}mpvue不支持直接在template上直接绑定函数这个是mpvue文档上有写的,不过一开始并不是很理解,也踩坑了,所以在这里提一下,避免不知道的同学踩坑找半天。<template> <div v-for="(item, index) in list" :key=“index”>{{ formatItem(item) }}</div></template> <script>export default { data () { return{ list: [1, 2, 3] } }, methods: { formatItem (item) { return 我是${item} } }}</script>上面的代码应该是日常vue中比较常用的,就是将数据传参给方法做一些处理,这个在mpvue中是不支持的,会被编译成一个空字符串。小程序中可放心使用css3的一些特性比如高斯模糊filter: blur(50px);如果要使用动画,尽量用css动画代替wx.createAnimation在实际使用时,wx.createAnimation做动画其实很卡,性能很差,所以在需要使用动画时,建议尽量使用css做动画。在小程序中是支持css动画的,transition,animation,@keyframes这些特性都支持。比如做一个div一直旋转的动画,大家可以对比一下两个版本:wx.createAnimation版本原理:通过setInterval()不断更新div的旋转位置<template> <div class=“cover” :animation=“animationData”></div></template><script>export default { data () { return { animationData: ‘’, animation: ‘’, rotateCount: 0, timer: ’’ } }, components: { }, methods: { startRotate () { this.timer = setInterval(() => { this.rotateAni(++this.rotateCount) }, 100) }, rotateAni (n) { if (!this.animation) { return } // 每100毫秒旋转10度 this.animation.rotate(10 * n).step() this.animationData = this.animation.export() } }, onShow () { // 页面从隐藏到显示时才执行 if (!this.animation) { this.animation = wx.createAnimation() this.startRotate() } }, onReady () { // 第一次初始化时会执行 if (!this.animation) { this.animation = wx.createAnimation() this.starRotate() } }, onHide () { // 页面隐藏时会执行,避免频繁的setData操作,将定时器停掉 this.timer && clearInterval(this.timer) }, beforeDestroy () { // 页面卸载,也停掉定时器 this.timer && clearInterval(this.timer) }}</script><style scoped lang=“scss”> .cover { left: 20px; bottom: 70px; border-radius: 50%; background: #fff; position: absolute; width: 50px; height: 50px; background: rgba(0, 0, 0, 0.2); box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.5); overflow: hidden; z-index: 10000; }</style>使用css的@keyframes做旋转动画<template> <div class=“cover” :style=“coverStyle”></div></template><script>export default {}</script><style scoped lang=“scss”> // 定义一个动画名为 rotate @keyframes rotate { 0%, 100% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .cover { left: 20px; bottom: 70px; border-radius: 50%; background: #fff; position: absolute; width: 50px; height: 50px; background: rgba(0, 0, 0, 0.2); box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.5); overflow: hidden; z-index: 10000; // 使用动画 animation: rotate 4s linear infinite; }</style>用js写的动画需要控制好setInterval的间隔时间和旋转角度,比较难调。而用css写动画很简单,性能比js好,代码量也很少。使用css动画时建议开启硬件加速为了动画更流畅,想尽办法做优化,虽然不知道有没效果,反正用了再说[手动滑稽]。可以用will-change和transform: translate3d(0,0,0)开启硬件加速。我也不太会用,具体用法大家自行百度Google。will-change: auto;transform: translate3d(0, 0, 0);iPhoneX需要底部导航条预留34px(68rpx)的高度。由于小程序中不能设置viewport-fit=cover,所以也就没有web中的安全区域说法,目前主流的做法是通过wx.getSystemInfoSync()判断是否是ipx,若是则给页面底部撑高34px。const res = wx.getSystemInfoSync()if (res.model.indexOf(‘iPhone X’) >= 0) { this.isIpx = true}注意是用res.model.indexOf(‘iPhone X’),在开发者工具的iPhone X中,model是全等于iPhone X的,但在真机中往往拿到的值是iPhone X GZxxx,即后面可能会带一串东西,所以用indexOf才是比较稳的,而且对iPhone XR等机型也适用。由于还有其他安卓机的全面屏,不太可能一一判断,而且某些安卓全面屏是没有用iPhone底部的工具条的(不存在冲突的情况),所以我们只判断iPhone X的情况就可以了,其他全面屏就不需要给底部预留了。至于全面屏布局的适配,需要用flex布局或者获取屏幕宽高来慢慢调了,建议最好用flex布局自适应处理。for循环中的子组件click事件无法触发Page -> 父组件 -> 子组件,在子组件click后$emit一个事件出来,发现无法触发。这个bug一开始没有出现,但偶然npm run build出现的,然后排查原因,后面即使回滚所有版本再npm start也还会出现。好像不触发则已,一发就不可收拾,这又是一个大坑,搜issue和加群问人,当晚下班回家研究到1点多都没有解决。第二天继续研究,感觉可能是框架的原因,最后尝试升级一下mpvue版本,没想到就正常了。直接使用quick-strat项目的mpvue版本是 2.0.0,mpvue和mpvue-template-compiler升级到最新2.0.6就解决了。事后查看mpvue版本记录,果然是框架本身原因,并且找到了issue。npm run build后代码报错,再build一次可能报另一些错解决: 没找到原因,可能是引入vant导致的,打包时丢失了部分文件。多build几次,或者重启下小程序开发者工具就正常了。mpvue中created() 钩子会在页面初始化时全部一起触发,尽量不要用小程序生命周期的理解进入已销毁的page组件时依次触发: onLoad,onShow,onReady,beforeMount,mounted第一次进入已销毁的子组件时依次触发: onLoad,onReady,beforeMount,mounted第二次进入已销毁的子组件时依次触发: onLoad,onShow,onReady再次进入 未被销毁的page组件、子组件时只触发: onShowmpvue文档中建议尽量不要使用小程序的生命周期,这个应该是为了让项目更好地适应支付宝小程序和头条小程序等,所以才这样建议大家尽量不要使用某一个小程序自身的api。如果你们的小程序只是微信小程序(不考虑兼容其他平台小程序),我建议直接用小程序的生命周期,而不要用mpvue的生命周期,坑太多了。比如mpvue的created周期,初始化时所有的page都会执行,所以created这个周期是不能用了。onUnload不触发小程序中与平常web开发不同的是,它的页面会被缓存。举个例子:从page1跳转到page2,再从page2返回page1,此时的page1还没销毁,不会触发onLoad再重新渲染,而是直接使用之前的数据。从性能上来说,单纯的返回不应该再请求api获取数据重新渲染,这是对的,符合我们的预期。而有时候,从page2返回page1时,我们希望page1是重新获取数据渲染的。比如在page2做了一个退出登录的操作,此时再返回page1时,还是会看到之前的数据。实际上我们的预期是:由于已经退出登录了,page1的数据应该被销毁了。在平常的web开发中,遇到上面的问题,我们可能是不管缓存,每次返回page1都再次请求api渲染最新的数据,牺牲掉部分性能从而保证逻辑的正确性。在mpvue中我也尝试这样干了:想在page1的onUnload()生命周期中销毁数据,但是没有成功。即使在page2退出登录时,采用wx.reLaunch()重新刷一遍,page1的onUnload()生命周期也没有执行。所以onUnload()是有可能不执行的,建议慎用。最后还是得想办法做到在page2控制page1的数据销毁或保留。想到这里,vuex就不自觉浮现在眼前了,如果page1的数据是通过vuex来控制的,那么我在page2就可以用vuex来灵活管理其他页面的数据了。如果page2做退出登录操作时,就让page1的数据销毁,如果是不退出登录正常返回,page1的数据还是正常,做到灵活控制。个人平时web开发很少用vuex,因为项目比较简单不用那么复杂的全局数据传递。但在小程序中,建议全局使用vuex来控制所有数据(当然是得根据需求来用)。总结第一次开发小程序就直接上了mpvue,可能有些坑已经很多同学总结过了,有些坑可能是不熟悉而导致的,但自己没有去踩过一遍可能不够深刻。有两种坑会比较难啃:框架本身的问题,如mpvue2.0.0出现的子组件无法触发事件的问题。开发者工具和真机运行环境不一致导致的坑。遇到真机和开发者工具不一致的情况,可按以下步骤排查:有可能是缓存,可以杀掉之前的版本再跑起来手机微信版本太低,可能api不支持,用wx.canIUse打印一下手机端某些属性不支持读取,比如上面的this.audio.src,可以在真机打印调试一下代码在手机端运行有报错,可以在手机端开启调试,看一下log微信设计上的坑,百度下是否有相关的案例和解决办法而遇到mpvue框架的问题可以:去搜一下mpvue的issue看有没相关解决办法尽量使用最新版本的框架,可能某些问题已经修复了的。实在解决不了的,建议想办法绕过,换一种方法来实现。希望对大家有所帮助。 ...

March 12, 2019 · 3 min · jiezi

微信小程序刷新页面

有时候我们会遇到这样的问题,退出小程序以后重新进入小程序历史数据还在。需要我们手动清除历史数据,而页面属性那么多不能一个一个去初始化。最佳解决办法: onLoad: function (option) { Object.assign(this, this.$options.data()); // 重置页面数据 }其它解决办法:page.onshow();page.onLoad();

March 5, 2019 · 1 min · jiezi

微信小程序mpvue项目使用WuxWeapp前端UI组件

前言:这是一篇简单粗暴的使用指南在最近的小程序项目里前端UI框架最后选择使用WuxWeapp,这篇文章记录一下如何在小程序mpvue项目中使用该UI组件。步骤一:下载源码(地址在这里)主要是里面的dist文件夹,下载下来之后就把dist文件夹放到mpvue脚手架自动生成的static文档中。具体的目录层级各位都可以按自己的喜好来设计。贴上我的仅供参考。步骤二:引入组件我们需要在app.json文件中进行配置,其中有一个"usingComponents"配置属性。需要使用什么组件,按需引入就行。配置如下:步骤三:使用组件最后就是使用啦,该UI组件也有官方的文档,已经写得很详细了。Tips:小程序的限制 由于小程序的定位是轻、快、小吧,所以小程序的代码包的大小也是有限制的,一个包不能超过2M。所以,我们引入到项目中的wux组件的代码小程序也会进行编译因而增加了代码包的大小,所以最好还是按需使用。如何在Wux的基础上自定义样式 比如我想在wux修改wux按钮组件的颜色,因为这种行为是会存在的,可能项目需求要按钮就得是一种特定的颜色,而且我们想直接写css来修改颜色也有点困难。那么不妨,我们可以从组件源码下手,其实加个背景颜色什么的还算是简单的,只要在wxss文件里加一个css 的class就差不多了…这一直是其中一种思路,其实也给了我们机会去看看别人是如何实际出一个UI组件库的。(我想我们大多数人都是用过,却很少看过代码八)写到这里,希望能对你有帮助(#^.^#)

February 17, 2019 · 1 min · jiezi

mpvue小程序《校友来了》成长记 | 给2018画下圆满句号

1、前言很久没有进行更新文章了,2018已经结束,2019已经开启,为了给2018画下圆满的句号,决定在新年来临前写一篇总结。如果有看过我文章的朋友或许知道还有一个小程序《校友足迹》,而《校友来了》正是《校友足迹》的升级版,我在原有的基础上添加了校友圈子功能,通过《校友来了》不仅能看到校友的分布情况,同时还可以与同城校友交流,查看校友名片等。让《校友来了》不仅仅是一个工具,更是一个同城校友发现与交流的圈子。初心《校友来了》旨在帮助更多同城校友交流,在这里你能发现新的机会、新的朋友、甚至可以帮你找到你的另一半!《校友来了》更是一个帮你拓展社交圈的好工具,在家靠父母,出门靠朋友,朋友又是同校校友,你在这个城市就会多一份异乡的温暖。体验2、校友足迹1.0关于《校友足迹》1.0可以查看我以前的另一篇文章mpvue小程序《校友足迹》成长记(一)3、升级原因《校友足迹》发布一段时候后,一直有计划想要升级一些新的功能,让其不再那么单一,但是由于工作上比较忙的原因,一直搁置了下来。直到有一次,有一位在公众号看了我文章的朋友,留言说想要聊一下我的《校友足迹》,他给了我重新升级《校友足迹》的想法。刚好这段时间工作上也不是很忙,那就利用业余时间说干就干,一口气升级一下。4、新增功能4.1 校友圈子校友圈子是这次最大的升级,基于《校友足迹》的思考,同城校友圈是我最想做的功能,先把全国校友按照省市划分,再根据学校划分,每个城市的校友都是不同的圈子。只有同城校友才能看到自己发的话题,这样也符合圈子的定义,既然是圈子就不能太大,要细化一些。同时在顶部Banner部分也做了公有与私有化划分,根据院校与城市会显示不同的轮播图。这也是为了帮助各大高校做宣传使用,因为在举行校友聚会的时候并不是所有的校友都能看到消息,更有一些老校友断了联系,通过这个宣传入口可以让更多的同城校友看到消息。4.2、校友名片校友名片可以通过点击昵称或者头像查看,此页面展示了同城校友的基本信息。由于小程序没有开放直接添加微信好友的接口,所以这里需要校友完善自己的个人信息后,通过点击复制的方式回到微信界面添加。虽然在操作方式上较为繁杂,但目前只能采用此方式。不过手机号是可以直接保存到通讯录中4.3 个人中心个人中心这里主要就是个人信息的基本展示与修改,同时还有自己发布过的话题,与话题相关的评论和点赞消息通知。由于话题功能需要用户基本信息才可,所以这里需要授权得到您的昵称和头像信息,不用担心隐私问题,因为小程序的这个授权也只是基本的头像和昵称,并没有隐私信息。4.4 消息中心消息中心主要分为个人消息与系统公告通知,个人消息可以接收到自己发布话题的点赞与评论消息。4.5 校友足迹页升级改版原有足迹页面比较单一乏味,新版在经过无数次的设计改版后,提升了整体逼格(O(∩_∩)O哈哈~),在分享出去后也是逼格满满,目前只显示排名前三的城市。下载按钮可以生成此页面的图片,方便你分享到朋友圈,聊聊则是直接通往校友圈子的入口。关于技术做的时候远比初想的难,从mysql数据库表的设计,到node,express业务逻辑的拆分和数据的封装与接口统一,一直到mpvue前端页面展示,以及mysql数据库查询优化,redis缓存的使用,还有JWT接口权限的验证,还有小程序的采坑,更有界面设计的优化,在这段时间里都一一经历了。学了不少新的东西,也回顾了以前的不少知识,算是一个伪node全栈的项目了,关于技术的详解我会另开一篇文章进行详细介绍,不仅作为一个分享交流,也作为这个项目的技术总结。如果有兴趣的话可以持续关注一下,在这里先放一下张目录结构前端mpvue + flyio + vuex + stylus + echartsmpvue mpvue 是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。flyio 一个支持所有JavaScript运行环境的基于Promise的、支持请求转发、强大的http请求库。可以让您在多个端上尽可能大限度的实现代码复用。mpvue-echarts ECharts 的 Mpvue 小程序版本。开发者可以通过熟悉的 ECharts 配置方式及 Vue 语法,快速开发图表,满足各种可视化需求。 stylus CSS 的预处理框架,stylus 给 CSS 添加了可编程的特性,也就是说,在 stylus 中可以使用变量、函数、判断、循环一系列 CSS 没有的东西来编写样式文件,执行这一套骚操作之后,这个文件可编译成 CSS 文件后端服务mysql + redis + node (express + superagent + jsonwebtoken +crypto + ioredis + mysql + pm2)mysql 系型数据库管理系统 redis Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。 express Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。 superagent superagent 是一个轻量的,渐进式的ajax api,可读性好,学习曲线低,内部依赖nodejs原生的请求api,适用于nodejs环境下. jsonwebtoken JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案 crypto crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。在这里用做微信小程序加密解密 ioredis ioredis是一个功能强大,功能齐全的Redis客户端 mysql mysql的node.js驱动程序pm2 PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单 最后如果你对本小程序感兴趣的话可以分享到朋友圈,让更多的校友了解到《校友来了》,让同城校友的圈子越来越壮大。同时如果你有更好的想法或者idea,欢迎下方留言交流,如果你的院校有校友会相关的宣传需求,也欢迎联系我,我将免费为贵校提供宣传。 ...

January 16, 2019 · 1 min · jiezi

mpvue配置底部菜单栏图标路径报错

如题,编写微信小程序的页面底部导航,在src目录下的app.json配置底部菜单图标路径时会报路径错误,如下解决方法,需要手动将图标添加到dist文件目录下,如下:期待mpvue官方解决该bug

January 2, 2019 · 1 min · jiezi

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 项目结构:引入第三方组件库踩坑 这里引入的是 iView Weapp (https://weapp.iviewui.com/docs/guide/start) 使用方法:到 GitHub 下载 iView Weapp 的代码,将 dist 目录拷贝到自己的项目中。然后按照如下的方式使用组件,以 Button 为例,其它组件在对应的文档页查看: 1. 添加需要的组件。在页面的 json 中配置(路径根据自己项目位置配置): “usingComponents”: { “i-button”: “../../dist/button/index” } 2.在 wxml 中使用组件: <i-button type=“primary” bind:click=“handleClick”>这是一个按钮</i-button> 备注: 可以在给单独的页面新建一个main.json文件进行相应的配置。如下图: 亦可以在src文件下的app.json进行统一配置(这样就不需要每个页面都去配置一次,方便一点),详情见下图:

December 29, 2018 · 1 min · jiezi

小程序如何处理键盘覆盖输入框

在移动端里, 当输入框处于页面比较下方的时候回发生键盘覆盖输入框的情况, 在小程序中也发生了类似情况, 但小程序提供了一些api, 但不能达到需求. 这里来简单说一下解决思路.小程序的默认行为在发生了键盘覆盖输入框的时候, 在不操作任何api的情况下, 小程序会把屏幕向上推, 推到输入框正好在键盘上方的位置.也就是如果不经过处理, 小程序的键盘是不会覆盖输入框的. 但是在我的需求里这样还不够, 因为页面上部分是需要持续展示的内容, 不希望把页面向上推.所以下面要通过小程序的api来解决这些问题.cursor-spacing在比较正常的UI设计中, 输入框外面实际都会有一层wrapper, 而很明显小程序是默认行为是不知道的, 所以结果是会把这层wrapper的下半部分(输入框以下的)切掉. 那么就非常难看了.引入这个apicursor-spacing, 设多少, input下面就留多少. 这个数字应当是’输入框下边缘到wrapper结束的距离".小程序的坑在于: 文档上的单位是错的, 本来就需要试才知道这个属性的含义是什么, 所以单位错导致无效果就让一(大)部分人放弃了. 正确的单位是带有单位的字符串. 例如10px或者100rpx.adjust-position刚才说到我的需求, 我希望页面不向上推, 而直接把输入框顶上来.于是尝试了这个api. 默认是true, 把他设为false. 效果变成了: 点了输入框, 键盘完美覆盖输入框.于是在加上cursor-spacing, 发现这两个api是不能同时生效的.所以最后结论是: 单纯用提供的api无法实现需求了. 所以只能监听事件自己做.解决方案手动操作输入框思路:adjust-position设为false.在输入框的wrapper的bottom样式绑到本地数据, 并设为absolute定位.在focus事件里改变输入框的位置.在blur事件里复原输入框的位置.按照这个思路操作, 遇到了几个问题:如何确定输入框的位置发现在bindfocus事件中可以获得键盘的高度, 经过尝试, 键盘的高度是以px为单位的. 所以直接把bottom的值设为px高度就行了.如果输入框wrapper的相对定位不是页面底部, 情况就比较复杂, 若是用rpx为单位, 需要获得屏幕宽高来计算px数, 在不麻烦的情况下可以调整布局使wrapper相对于页面底部定位.在改变style后输入框立即失去焦点发生了这个情况后表现为: 点了输入框, 输入框的wrapper闪一下又回原处. (因为失去焦点)经过多次试验, 需要做的是在绑定一个本地变量到focus属性.然后用wx:if根据是否focus隐藏输入框, 放一个假的输入框, 点击以后使改变focus属性来唤起键盘.贴一份实现的代码.

December 27, 2018 · 1 min · jiezi

微信小程序获得微信头像和昵称

{ wx.login({ success: res => { if (res.authSetting && res.authSetting[‘scope.userInfo’]) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称 wx.getUserInfo({ success: function (data) { console.log(data.userInfo); // { // avatarUrl: ‘微信头像img文件path’ // nickname: ‘微信昵称’ // } } }); } else { this.showShouquan = true; // 打开模态框进行授权 } } });}<template> <div> <!– 这里采用vantui进行弹框,只不过把弹出框的button类型设置成了"getUserInfo",原理就是下面这个button <button wx:if="{{showShouquan}}" open-type=“getUserInfo” bindgetuserinfo=“getUserInfoFromWx”>授权登录</button> –> <van-dialog use-slot async-close :show=“showShouquan” show-cancel-button confirm-button-open-type=“getUserInfo” @close=“cancelShouquan” @getuserinfo=“getUserInfoFromWx”> <h4 class=“wx-shouquan-title”>微信授权</h4> <p class=“wx-shouquan-content”> xxxxxxx小程序将获得您的微信头像、昵称等公开消息 </p> </van-dialog> <div></template> getUserInfoFromWx (e) { this.$store.state.user_userinfo = e.mp.detail.userInfo; this.showShouquan = false; }, cancelShouquan () { this.showShouquan = false; }, ...

December 24, 2018 · 1 min · jiezi

小程序静态资源无缝转移到腾讯云COS 使用wepy mpvue 等webpack打包的小程序项目

原文链接:https://callmesoul.cn/xiao-cheng-xu-jing-tai-zi-yuan-wu-feng-zhuan-yi-dao-teng-xun-yun-cos-shi-yong-wepy-mpvue-deng-webpackda-bao-de-xiao-cheng-xu-xiang-mu/今天介绍的工具是wecos原生小程序原生的小程序直接根据wecos的文章操作即可,wecos提供了上传本地资源文件到cos、替换小程序的引用本地路径为上传路径等。这里不作详细说明,主要介绍webpack打包的小程序项目。因为原生写起来很不方便。webpack小程序打包项目最好是开发完再来进行这一步,前期专心开发。我前期开发时,引用静态资源用的是相对路径,用的绝对路径应该也可以的。项目开发完后webpack设置打包后的cdn地址, webpack rules选项:{ test: /.(png|jpg|jpeg|gif|svg)$/, use: { loader: ‘file-loader’, options: { name: ‘/[path][name].[ext]’, publicPath: function (file) { if(isProduction){//判断是否生产环境,自己判断咯。 if(file.indexOf(’tabbar’)>=0){//如果有tabbar的,tabbar用一个tabbar的文件夹装起来,因为tabbar图片只支持本地。 return file; } else{ return ‘https://xxx-1234567.cos.ap-guangzhou.myqcloud.com/'+file;//你的腾讯云cos bucket的域名。 } }else{ return file; } } } }, },安装wecosnpm install -g wecos跟目录创建wecos.config.json文件填写wecos.config.json 配置{ “appDir”: “./dist/assets”, “cos”: { “secret_id”: “xxxxx”, “secret_key”: “xxxxx”, “bucket”: “xxx-1234567”,//bucker-appid “region”: “ap-guangzhou”, //创建 bucket 时选择的地域简称 “folder”: “/assets” //资源存放在 bucket 的哪个目录下 }, “uploadFileSuffix”: [".jpg",".png",".gif",".webp",".svg"], “uploadFileBlackList”: [//不上传的图片,填tabbar的目录 “./dist/assets/images/tabbar”, ]}在根目录运行wecos即可。总结为什么不用webpack的 publicPath 而用file-loader的publicPath ?因为webpack的 publicPath只支持字符串,一但改成线上域名,所有静态资源的前缀都会变成cdn域名。而小城的tabbar并不支持网络图片,base64也不支持,只支持本地图片。这时我们就用file-loader的publicPath ,支持函数且返回文件名,可以写条件去过滤掉tabbar的文件。使tabbar文件使用本地的,而其他使用线上cdn域名的文件。为什么要用wecos?当然你也可以不用自己,本地打包后自己手动上传到cos后台。然后删除了本地的图片文件(除了tabbar的图片)。然后开发者工具再上传代码。你会发现这步骤很累赘。使用wecos后,我们打包后只需要跑一下cos就可以自动上传本地的上cdn,且自动删除本地的(tabbar图片除外)。是不是方便多了?赶紧在你项目用上把! ...

December 13, 2018 · 1 min · jiezi

mpvue 单文件页面配置

前言mpvue 的出现把 vue 的开发体验带到了小程序这个平台中,但其目录结构与传统的 vue 项目却并不完全一致,一个典型的页面包含以下三个文件:index.vue // 页面文件main.js // 打包入口,完成 vue 的实例化main.json // 小程序特有的页面配置,早期写在 main.js 文件中其中,每个页面的 main.js 文件基本都是一致的,可通过 mpvue-entry 来自动生成(weex 也有类似的处理),而 main.json 我个人认为直接在 vue 文件中配置更为合适,于是开发了 mpvue-config-loader 来加以实现本文将介绍如何在 mpvue 官方模板的基础上,通过配置 mpvue-config-loader 来实现在 vue 文件内书写小程序的页面配置步骤初始化项目vue init mpvue/mpvue-quickstart my-project安装依赖npm i mpvue-config-loader -Doryarn add mpvue-config-loader -D修改打包配置build/webpack.base.conf.jsmodule.exports = { module: { rules: [ { test: /.vue$/, loader: ‘mpvue-loader’, options: vueLoaderConfig },+ {+ test: /.vue$/,+ loader: ‘mpvue-config-loader’,+ exclude: [resolve(‘src/components’)],+ options: {+ entry: ‘./main.js’+ }+ } … ] } … plugins: [ new MpvuePlugin(),- new CopyWebpackPlugin([{- from: ‘**/*.json’,- to: ‘’- }], {- context: ‘src/’- }), … ]}修改页面配置src/App.vue - 复制 app.json 中的内容,并修改格式以符合 eslint 规范<script>export default {+ config: {+ pages: [+ ‘pages/index/main’,+ ‘pages/logs/main’,+ ‘pages/counter/main’+ ],+ window: {+ backgroundTextStyle: ’light’,+ navigationBarBackgroundColor: ‘#fff’,+ navigationBarTitleText: ‘WeChat’,+ navigationBarTextStyle: ‘black’+ }+ }, created () { … }}src/pages/logs/index.vue - 同上import { formatTime } from ‘@/utils/index’import card from ‘@/components/card’export default {+ config: {+ navigationBarTitleText: ‘查看启动日志’+ }, …}src/app.json - 删除src/pages/logs/main.json - 删除启动运行npm run devoryarn dev其他使用 mpvue-entry 的项目暂不建议使用该模块,后期会直接集成作为可选模式之一该模块的实现方式有以下两种可选,但由于前者在编辑器中暂无法高亮,所以采用了第二种方式自定义标签 <config></config><script></script> 标签导出对象的 config 属性 ...

December 1, 2018 · 1 min · jiezi