微信小程序开发入门教程(四)---自己动手做个小程序
前面已将基础知识准备的差不多了,下面实际做一个小程序。
一、目标
用于上传照片和文字。
2个主要页面:我me,设置set
二、开始制作
1、打开微信开发者工具(我用的1.02.1907160 Windows 64版本),点+号,新建项目diary,选择目录E:\wxDEV\diary,填入从微信开发平台申请到的AppID,开发模式默认为小程序,后端服务选择云开发,点新建,生成了云开发QuitStart示例模板。下面在此模板基础上制作。
2、建立me set页面,并给小程序增加tabBar。即修改E:\wxDEV\minishop\miniprogram\app.json并保存。代码如下:
- {
- "pages": [
- "pages/index/index",
- "pages/me/me",
- "pages/people/people",
- "pages/set/set"
- ],
- "window": {
- "backgroundColor": "#F6F6F6",
- "backgroundTextStyle": "light",
- "navigationBarBackgroundColor": "#F6F6F6",
- "navigationBarTitleText": "日记",
- "navigationBarTextStyle": "black"
- },
- "tabBar": {
- "backgroundColor": "#eeeeee",
- "position": "bottom",
- "list": [
- {
- "pagePath": "pages/me/me",
- "text": "我",
- "iconPath": "images/img.jpg",
- "selectedIconPath": "images/img.jpg"
- },
- {
- "pagePath": "pages/set/set",
- "text": "设置",
- "iconPath": "images/img.jpg",
- "selectedIconPath": "images/img.jpg"
- }
- ]
- },
- "sitemapLocation": "sitemap.json"
- }
- 同时,要在images目录中放置一张img.jpg图片(我自己画了一张)
3、我打算将现有的index页作为将来的splash页。所以先修改E:\wxDEV\diary\miniprogram\pages\index\index.js,以实现2秒后跳转me页,代码:
- //index.js
- Page({
- data: {},
- onLoad: function() {
- setTimeout(function() {
- wx.reLaunch({
- url: '../me/me',
- })
- }, )
- }
- })
4、修改me页(为方便调试,可更改app.json中pages值的顺序,将me调整到前面)。原本想在me页上用movable-view增加可拖动的按钮样式,如下:
- <!--可拖动按钮-->
- <movable-area style="height:{{mHeight}}px;width:100%;position:fixed;z-index:999;pointer-events:none;">
- <movable-view direction="all" style="height: 30px; line-height:30px;width: 30px; margin-left:100%; border:2px solid lightblue;border-radius:50%;">
- <cover-view bindtap="writeDiary">
- <cover-image src='../../images/img.jpg'></cover-image>
- </cover-view>
- </movable-view>
- </movable-area>
结果在安卓真机上出现兼容性问题,拖动时cover-view瞬间移动,而cover-image不跟随移动,无法正常工作。(谁知道解决办法给我讲一下?)只好弃用。
云开发的云函数的独特优势在于与微信登录鉴权的无缝整合,参考:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/userinfo.html
所以,对不同用户上传内容可以用openid区分。
5.半成品的me.wxml ,代码如下:
- <!--pages/me/me.wxml-->
- <view style="display:flex;flex-direction: row-reverse;margin-right:20px;font-size:150%;"><text bindtap="writeDiary">{{inputCursor}}</text></view>
- <view style="width:100%;">
- <!-- 上传图片 -->
- <view class="uploader">
- <view class="uploader-text" bindtap="selPic">
- <text>拍照或选择图片(可选)</text>
- </view>
- <view class="uploader-container" wx:if="{{imgUrl}}">
- <image class="uploader-image" src="{{imgUrl}}" mode="aspectFit" bindtap="previewImg"></image>
- </view>
- </view>
- <!-- 表单 -->
- <form class="formpub" bindsubmit="formSubmit" bindreset="formReset">
- <!-- 保存图片临时路径 -->
- <view class="section">
- <input name="img" value="{{imgUrl}}" hidden="true" />
- </view>
- <view class="content">
- <view class="currentWordNumber">{{currentWordNumber|}}/{{max}}</view>
- <!-- 别忘了给textarea加上name属性 -->
- <textarea name="diaryContent" bindblur="getText" bindinput="getValueLength" show-confirm-bar='true' value="{{editText}}" bindconfirm="getText" maxlength="{{max}}" minlength="{{min}}" placeholder="内容..." auto-focus>
- <text class="minWord">{{minWord}}</text>
- </textarea>
- </view>
- <view class="tips">在上面填写内容</view>
- <view class="btn-area">
- <button form-type="submit" style="width: 80%; margin-top: 20rpx;background-color: beige;color: black;border:2px solid lightblue;">写完了</button>
- </view>
- </form>
- </view>
- <block wx:for="{{diarys}}" wx:key="{{index}}">
- <view style="display:flex;width:100%;min-height:50px;background:rgb(248, 248, 248);margin:8px;">
- <view style="border:20px;">
- <image wx:if='{{item["img"]}}' src='{{item["img"]}}'mode="widthFix" style="width:100px;"></image>
- </view>
- <view style="width:100%;border-bottom:solid 1px lightgrey;padding-left:10px;"> {{item["content"]}} </view>
- </view>
- </block>
- <view>
- <image src='../../images/img.jpg' mode="widthFix" style="width:50px"></image>
- </view>
me.js
- // pages/me/me.js
- Page({
- /**
- * 页面的初始数据
- */
- data: {
- //以下变量也可以不写在这里,可直接在代码中声明和使用,但推荐写在这里
- mHeight: ,
- hiddenInput: true,
- inputCursor: '+',
- max: , //限制最大输入字符数
- min: , //限制最小输入字符数
- minWord: '', //提示语句
- imgUrl: '', //要上传的图片的url
- editText: '', //textarea中编辑的内容
- diarys: {},
- curPage:
- },
- /**
- * 生命周期函数--监听页面加载
- */
- onLoad: function(options) {
- },
- //写日记
- writeDiary: function() {
- let tempCursor = ''
- if (this.data.inputCursor == '+') {
- tempCursor = '-'
- } else {
- tempCursor = '+'
- }
- this.setData({
- hiddenInput: !this.data.hiddenInput,
- inputCursor: tempCursor
- })
- //滚动视口,返回顶部
- wx.pageScrollTo({
- scrollTop: ,
- duration:
- })
- },
- /****限制字数与计算 */
- getValueLength: function(e) {
- let value = e.detail.value
- let len = parseInt(value.length)
- //最少字数限制
- if (len <= this.data.min)
- this.setData({
- minWord: "至少填写10个字哦~"
- })
- else if (len > this.data.min)
- this.setData({
- minWord: " "
- })
- //最多字数限制
- if (len > this.data.max) return;
- this.setData({
- currentWordNumber: len //当前字数
- })
- },
- formSubmit: function(e) {
- console.log('form发生了submit事件,携带数据为:', e.detail.value)
- let upDiaryContent = e.detail.value["diaryContent"]
- let upimgUrl = e.detail.value["img"]
- let len = parseInt(upDiaryContent.length)
- //最少字数限制
- if (len <= this.data.min) {
- this.setData({
- minWord: "至少填写10个字哦~"
- })
- return
- }
- wx.showLoading({
- title: '请等待',
- })
- //判断有无图片
- if (typeof upimgUrl == "undefined" || upimgUrl == null || upimgUrl == "") {
- //没有图片,直接上传文字
- const db = wx.cloud.database()
- db.collection('diarys').add({
- data: {
- content: upDiaryContent
- },
- success: res => {
- //无图,文字上传成功了
- this.reset()
- console.log('[数据库] [新增记录] 成功,记录 _id: ', res._id)
- },
- fail: err => {
- wx.showToast({
- icon: 'none',
- title: '新增记录失败'
- })
- console.error('[数据库] [新增记录] 失败:', err)
- }
- })
- } else { //有图片,则先上传图片
- const timestamp = new Date().getTime();
- const relCloudPath = 'diarys/' + timestamp + upimgUrl.match(/\.[^.]+?$/)[]
- console.log()
- console.log(upimgUrl)
- console.log(relCloudPath)
- wx.cloud.uploadFile({
- cloudPath: relCloudPath,
- filePath: upimgUrl,
- success: res => {
- console.log('[上传文件] 成功:', res)
- let imgFileID = res.fileID
- //再上传文字
- const db = wx.cloud.database()
- db.collection('diarys').add({
- data: {
- img: imgFileID,
- content: upDiaryContent
- },
- success: res => {
- //文字也上传成功了
- this.reset()
- console.log('[数据库] [新增记录] 成功,记录 _id: ', res._id)
- },
- fail: err => {
- //文字上传失败
- wx.showToast({
- icon: 'none',
- title: '新增记录失败'
- })
- console.error('[数据库] [新增记录] 失败:', err)
- }
- })
- },
- fail: e => {
- console.error('[上传文件] 失败:', e)
- wx.showToast({
- icon: 'none',
- title: '上传失败',
- })
- }
- })
- }
- //图片和文字全部上传了。
- wx.hideLoading()
- },
- // 选择图片
- selPic: function() {
- var that = this
- wx.chooseImage({
- count: ,
- sizeType: ['compressed'],
- sourceType: ['album', 'camera'],
- success: function(res) {
- wx.showLoading({
- title: '请等待',
- })
- const imgfilePath = res.tempFilePaths[]
- that.setData({
- imgUrl: imgfilePath
- })
- },
- fail: e => {
- this.setData({
- imgUrl: ''
- })
- //console.error(e)
- },
- complete: () => {
- wx.hideLoading()
- }
- })
- },
- //重置
- reset: function() {
- let tempCursor = ''
- if (this.data.inputCursor == '+') {
- tempCursor = '-'
- } else {
- tempCursor = '+'
- }
- this.setData({
- 'imgUrl': '',
- 'editText': '',
- 'hiddenInput': !this.data.hiddenInput,
- minWord: '',
- inputCursor: tempCursor
- })
- },
- // 查询当前用户的数据库集合,暂时没用
- onQuery: function(p) {
- const db = wx.cloud.database()
- db.collection('diarys').skip(p)
- .get()
- .then(res => {
- console.log(res.data)
- console.log(res.data[].img)
- })
- .catch(console.error)
- },
- /**
- * 生命周期函数--监听页面初次渲染完成
- */
- onReady: function() {
- wx.getSystemInfo({
- success: res => {
- let h = res.windowHeight
- //取20条数据
- const db = wx.cloud.database()
- db.collection('diarys')
- .get()
- .then(res => {
- this.setData({
- mHeight: h,
- diarys: res.data
- })
- console.log(res.data)
- console.log(res.data[].img)
- })
- .catch(console.error)
- },
- })
- },
- /**
- * 生命周期函数--监听页面显示
- */
- onShow: function() {
- },
- /**
- * 生命周期函数--监听页面隐藏
- */
- onHide: function() {
- },
- /**
- * 生命周期函数--监听页面卸载
- */
- onUnload: function() {
- },
- /**
- * 页面相关事件处理函数--监听用户下拉动作
- */
- onPullDownRefresh: function() {
- },
- /**
- * 页面上拉触底事件的处理函数
- */
- onReachBottom: function() {
- },
- /**
- * 用户点击右上角分享
- */
- onShareAppMessage: function() {
- }
- })
me.wxss
- /* pages/me/me.wxss */
- .currentWordNumber {
- height: 35px;
- line-height: 35px;
- font-size: 14px;
- float: right;
- margin-right: 15px;
- color: rgba(, , , );
- margin-bottom: 10px;
- }
- .minWord {
- color: rgb(, , );
- font-size: 14px;
- position: absolute;
- top: 30px;
- }
- .tips {
- width: %;
- margin-left: %;
- height: 45px;
- color: rgba(, , , );
- font-size: 14px;
- margin-top: 15px;
- text-align: left;
- font-family: PingFangSC-regular;
- }
- textarea {
- min-height: 500rpx;
- max-height: 500rpx;
- padding: 10rpx 10rpx;
- font-size: %;
- width: %;
- margin-left: %;
- margin-top: 15px;
- }
- .content {
- border-top: 1px solid rgb(, , );
- width: %;
- margin: auto;
- background-color: #ffff;
- }
参考:授权 https://www.jianshu.com/p/480ff10bfb54
textarea https://blog.csdn.net/ChibiMarukoChan/article/details/88659746
...
微信小程序开发入门教程(四)---自己动手做个小程序的更多相关文章
- C#微信公众号开发系列教程四(接收普通消息)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
- 微信小程序开发入门教程
做任何程序开发要首先找到其官方文档,微信小程序目前还在邀请内测阶段,目前官方放出了部分开发文档,经过笔者一天的查看和尝试,感觉文档并不全面,但是通过这些文档已经能够看出其大概面貌了.闲话不多说,我们先 ...
- C#微信公众号开发入门教程
首先打开开发文档: 微信公众号开发者文档:http://mp.weixin.qq.com/wiki/home/index.html 一.创建测试账号 可以先申请一个开发者测试账号
- 微信小程序开发入门教程(二)---分析官方云开发例子中的一些功能
接上一篇文章:https://www.cnblogs.com/pu369/p/11326538.html 1.官方云开发的例子中,点击获取 openid,对应代码在E:\wxDEV\helloyun\ ...
- 微信小程序开发入门教程(一)---hello world
由于无法备案网站,前期做了个微信小程序(开发版)就搁置了,几乎忘了开发过程.现在重新梳理,做个记录. 一.最基本的小程序前端例子hello 1.下载安装 微信开发者工具 官网: https://d ...
- 微信小程序开发入门教程(三)---小程序云开发支付功能
支付(shoukuan)功能真的很重要!由于我还没有商户号,以下代码未实际验证 1.服务端 进入云开发,新建云函数pay(应该也可以在开发者工具编写后上传) 编写后端代码index.js这里用到第三方 ...
- C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
- C#微信公众号开发系列教程五(接收事件推送与消息排重)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
- 微信小程序开发系列教程三:微信小程序的调试方法
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 这个教程的前两篇文章,介绍了如何用下图所示的微信开发者工具自动生成一个Hel ...
随机推荐
- C++继承种类
- MyBatis学习存档(3)——mapper.xml映射文件
MyBatis 真正的强大在于映射语句,专注于SQL,功能强大,SQL映射的配置却是相当简单 所以我们来看看映射文件的具体结构 一.xml节点结构 mapper为根节点 - namespace命名空间 ...
- 植物大战僵尸:寻找召唤僵尸关键CALL
实验目标:通过遍历寻找召唤僵尸的CALL,通过调用CALL出现自定义的僵尸,加速僵尸的出现. 僵尸CALL的遍历技巧: 我们可以通过僵尸出现在屏幕中的个数来遍历寻找僵尸出现的CALL 首先打开CE-& ...
- MySQL 聚合函数(一)聚合(组合)函数概述
MySQL版本:5.7+ 本节介绍对值的集合进行操作的组合(聚合)函数.翻译自:Aggregate (GROUP BY) Function Descriptions 一.MySQL 5.7中的聚合函数 ...
- php对象转换为数组的部分代码
function object_array($array){ if(is_object($array)){ $array = (array)$array; } if(is_array($array)) ...
- lamp :在Linux 下搭建apache、Mysql、php
CentOS下搭建LAMP环境 LAMP: Linux + Apache + PHP + Mysql. 系统: CentOS 7,64位. CentOS安装 我选取了64位的CentOS 7这个Lin ...
- Python的global指令的作用
Python的global指令的作用 学过其他常用编程语言的同学一定清楚,Python是一个语法非常宽容的语言.它是个变量的定义可以省略.直接赋值.根据赋值结果自动确定变量类型的弱类型语言. 但是这样 ...
- Dubbo相关的基础
Dubbo是一款高性能轻量级的java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务注册与发现. Dubbo是阿里开源的一个项目,现在已经是Apache的顶级 ...
- python编程中常见错误
python编程培训中常见错误最后,我想谈谈使用更多python函数(数据类型.函数.模块.类等)时可能遇到的问题.由于篇幅有限,我们试图将其简化,特别是一些高级概念.有关更多详细信息,请阅读学习py ...
- Nginx笔记一
nginx: 为什么选择nginx: nginx是一个高性能的web和反向代理服务器. 作为web服务器:使用更少的资源,支持更多的并发连接,更高的效率,能够支持高达5w个并发连接数的相应, 作为 ...