最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Vue, App与我(十三)

运维笔记admin33浏览0评论

Vue, App与我(十三)

Vue, App与我(十三)

Vue, App与我(十三)

前言:

  • Big-man需要开发一个论坛模块, 论坛模块的话,简而言之, 就是一个发帖和回帖的模块。但是Big-man的这个论坛模块还是比较复杂的。在接下来的实现中Big-man会进一步地去进行分析。所以Big-man怀着好奇的心态进入了移动端的论坛模块。

首页:

  • 从这个首页的设计图上就可以得出, 需求是多么地繁杂,特别是涉及到图片上传这一块,原来的头像更换代码, 也是相当于图片上传。代码如下:
<template><div><div class="navTop"><i class="iconfont back" onclick="javascript:history.go(-1)">&#xe609;</i><span class="navCon">图片</span><span class="publish" v-on:click="updateUser()" style="display:none;">保存</span></div><div class="ask pt45"><div class="tips"><p class="tips_title">修改图片</p> </div><div class="text"><div id="app"><img id="picture_sourceimg" :src="picture" width="600" height="800"><input type="hidden" id="picture" name="picture" value="picture" ref="picture"> <div class="weui_uploader_input_wrp" v-on:click="changeUpload()"></div></div></div></div></div>
</template>
  • <input type="hidden" id="picture" name="picture" value="picture" ref="picture">
  • input 标签代码中的type=hidden是定义隐藏的字段,这里这样写主要是想要通过样式实现如下的效果:
  • 查看如下的样式修饰代码:
<style scoped>
.navTop .publish{ height:0.45rem; padding-right:0.15rem; color:#ffffff; font-size:0.15rem; line-height:0.45rem;}
.pt45{ padding-top:0.45rem; overflow:hidden;}
.ask{ overflow:hidden; }
.ask .text{ overflow:hidden; padding:0.15rem;}
.ask .text textarea{ width:90%; padding:5%; overflow:hidden; border:none; outline:none; background:#ffffff;}
.ask .tips{ padding:0 0.15rem; overflow:hidden; color:#a5a5a5; font-size:0.12rem;background-color: #E8E5E5;padding-bottom:0.15rem;}
.tips .tips_title{font-size:20px;font-weight:500;padding-top:0.15rem;color:#000000}
ul { list-style: none outside none; margin:0; padding: 0; }
li { margin: 0 10px; display: inline; }
#app{overflow: hidden;text-align: center;}
img {overflow: hidden; width: 150px;height:150px; border-radius: 150px; border: 1px solid #284baa; margin: auto;float: left;display: inline;margin-bottom: 10px;}
.weui_uploader_input_wrp {float: right;position: relative;margin-right: 9px;margin-bottom: 9px;width: 77px; height: 77px;border: 1px solid #d9d9d9;}
.weui_uploader_input_wrp:before {width: 2px;height: 39.5px;}
.weui_uploader_input_wrp:after {width: 39.5px;height: 2px;}
.weui_uploader_input_wrp:before {content: " ";position: absolute;top: 50%;left: 50%;-webkit-transform: translate(-50%,-50%);transform: translate(-50%,-50%);background-color: #d9d9d9;}
.weui_uploader_input_wrp:after, .weui_uploader_input_wrp:before {content: " ";position: absolute; top: 50%;left: 50%;-webkit-transform: translate(-50%,-50%);transform: translate(-50%,-50%);background-color: #d9d9d9;}
.weui_uploader_input {position: absolute;z-index: 1;top: 0;left: 0;width: 100%;height: 100%;opacity: 0;-webkit-tap-highlight-color: rgba(0,0,0,0);}
.weui_uploader_file {float: left; margin-right: 9px;margin-bottom: 9px;width: 79px;height: 79px;background: no-repeat 50%;background-size: cover;}
#picture_uploadimg{float: right;}
.photoclose {position: absolute;display: block;right: 0;top: 0;margin: 2px 2px 0 0;width: 23px;background: #fff;}
.photoshow {display: block;float: left;position: relative;margin-right: 8px;margin-top: 8px;overflow: hidden;zoom: 1;}.contain {width:100%; height:300px;border:1px solid #ccc;}
</style>
  • 其中最为主要的是实现图片上传的这部分代码:
<script>
import Error from '../components/Error.vue'
import Tab from '../components/Tab.vue'
import Config from '../config.js'
import {Toast} from 'mint-ui'
import Store from '../store.js'export default {components: {Error,Tab},data () {return {isError: false,error: '',picture:'',whoami: 'user/whoami/',govUrl:'user/update/'}},beforeMount: function(){if(Store.getAuthUid()){this.$http.get(this.whoami,{}).then((response) => {const ret = JSON.parse(response.data);if(ret && ret['code'] === 0){if(!ret['picture']){if(ret['wx_picture']){this.picture = ret['wx_picture']}else{this.picture = Config.defaultPic}}else{this.picture = Config.baseUrl + ret['picture']}}else{this.$router.push('/login')return}})}else{this.$router.push('/login')return}},methods: {fullUrl: function(url) {return Config.baseUrl + url},defaultPicUrl:function(){return Config.defaultPic},changeUpload:function(e){var share = {action: 'uploadImage',Authorization: 'Xyapp ' + Store.getAuthUid(),api: '/user/upload/'}if(window.postMessage) window.postMessage(JSON.stringify(share),'*');return true},updateUser: function(){var picture = this.$refs.picture.valuethis.getUpdate(picture)},getUpdate(picture) {this.$http.post(this.govUrl,{picture:picture} ).then( (response) => {const ret = JSON.parse(response.data || "[]")if(ret && ret.code === 0){Toast('操作成功!')this.$router.push('/userset')}else{Toast(ret.msg)this.error = (ret && ret.msg) || ""this.isError = true}},(response) => {this.isError = truethis.error = ""if(callback) callback.call(this)});}}
}
</script>
  • changeUpload()函数事件也就是图片的加载事件, 具体代码如下:
changeUpload:function(e){var share = {action: 'uploadImage',Authorization: 'Xyapp ' + Store.getAuthUid(),api: '/user/upload/'}if(window.postMessage) window.postMessage(JSON.stringify(share),'*');return true
},
  • 在以上的代码中, Big-man在书写的时候还犯了一个致命的错误,且这个错误是因为Big-man的经验不足造成的,比如如下的代码:
    • Authorization: 'Xyapp ' + Store.getAuthUid(),
    • Authorization: 'Xyapp' + Store.getAuthUid(),
  • 这两段代码大家可以仔细的推敲一下,在Big-man的书写过程当中就犯了这个错误,由此分享出来以供大家参考,引以为戒。
  • 在图像上传的时候, Big-man的这个项目沿用的是以前的代码, 也就是每点击一下去执行一下changeUpload()函数,而action的函数是在打包代码里面,这里的Big-man的打包代码是react-native。如下便是代码:
import config from "../config/config";
import  ImagePicker from 'react-native-image-picker'; //第三方相机
import {Platform, Alert} from 'react-native'
import Log from "../utils/LogUtil";
var UpLoadImage = {//上传图片upload: function(message,callback,showTips,hidTips) {Log.log("####进入方法内:"+message.api);config.Authorization = message.Authorization;let photoOptions = {//底部弹出框选项title:'请选择',cancelButtonTitle:'取消',takePhotoButtonTitle:'拍照',chooseFromLibraryButtonTitle:'选择相册',quality:0.3,allowsEditing:true,noData:false,storageOptions: {skipBackup: true,path:'images'}};// 选择图片ImagePicker.showImagePicker(photoOptions,(response) => {if (response.didCancel){Log.log('User cancelled image picker');return;} else if (response.error) {Log.log('ImagePicker Error: ', response.error);return;}  else if (response.customButton) {Log.log('User tapped custom button: ', response.customButton);return;}if (Platform.OS === 'ios') {const source = {uri: response.uri.replace('file://', ''), isStatic: true};this.uploadImageNetWork(source.uri,callback,message,showTips,hidTips);} else {const source = {uri: response.uri, isStatic: true};this.uploadImageNetWork(source.uri,callback,message,showTips,hidTips);}});},// 上传图片的网络请求uploadImageNetWork : function(uri,callback,message,showTips,hidTips) {let split = uri.split('/');let p = split[split.length - 1];// 这里还没有对 Uri 的非空判断let formData = new FormData();let file = {uri, type: 'multipart/form-data', name: p};   // name截取Uri的最后字段formData.append("file",file);   //这里的files就是后台需要的keyshowTips();fetch(config.api+message.api,{method:'post',// mode: "cors",// 允许跨域访问headers:{'Authorization':config.Authorization,'Content-Type':'multipart/form-data',},body:formData,}).then((response) => {if (response.ok){hidTips();Alert.alert('提示','上传成功',[{text:'确定',onPress:()=>{}}]);callback();}else {hidTips();Alert.alert('提示','上传失败',[{text:'确定',onPress:()=>{}}]);}}).catch((e)=>{hidTips();Alert.alert('提示','系统错误',[{text:'确定',onPress:()=>{}}]);});}
}
export default UpLoadImage
  • 更新图片的逻辑很是复杂,Big-man会在接下来分析一下图片的上传过程。

进入图片更新页面之前:

  • 在进入图片更新之前, Big-man需要去插入一条空的数据, 类似于下面的代码:
common: function () {let type = 3this.$http.get(this.barAddUrl + type + '/').then((response) => {const ret = JSON.parse(response.data || "[]")if(ret && ret.code === 0) {this.id = ret.idthis.$router.replace('/postcommon/' + this.id)} else {Toast(ret.msg)}})
},
  • 因为Big-man书写的论坛里面还存在帖子的类型(活动帖普通帖), 所以在这一步同时也需要上传一个类型(type),接下来看数据分析:
  • barAddUrl的代码分析:
$app->get('/bar/add/{type}/', function($request, $response, $args) {global $g_tbwuserid,$timestamp,$g_city_id;if ($g_tbwuserid > 0) {$bar = [];$bar['type'] = $args['type'];$bar['istop'] = 1;$bar['addtime'] = $timestamp;$bar['cityid'] = $g_city_id;$ret = template_add('cache_postbar', NO_CHECK_POWER, $bar, $request,$response);}else{$ret['code'] = 1;$ret['msg'] = COMMENT_LOGIN;return_result($request, $response, $ret);}return $response;
});
  • 后台是采用PHP书写的代码, 这样的操作是为了方便图片的插入, Big-man这样去想过这个数据的走势,图片需要插入,但是图片处理需要与bar的主键值(也就是上图中的id值)结合起来(不然怎么知道这张图片是是那个帖子的图片了),但是这个id值是DataBase自带的自增属性值(这里Big-man并没有对每一个帖子设计一个主键值,因为MySQL中自带的数据库递增值,很明显可以处理完这类的需求),对于操作过的小伙伴们很明白这一点的,所以我在图片上传的页面需要知道这个id值,如下图:
  • 上图中的linkid也就是我这里的barid,与这个barid对应的也就是上述中的id值。

插入一条空数据:

  • 很多的小伙伴可能会存在像Big-man这样的疑问,为什么需要去插入一条空数据了?插入一条空数据有什么意义了?
  • 占过座的伙伴们或者暗恋过别人的伙伴们就比较好理解这个内容,为什么了?因为这群伙伴很明白自己所占的东西虽然是空白的没人使用,但是却是实实在在属于自己的物品。
  • 插入图片前插入一条空数据也是同样的道理的,虽然那是一条空的数据, 但是却是属于这部分上传图片的空数据,当图片上传进来的时候,就回归到这条空数据上的。当其他数据想要来强行插入的时候,不好意思,没有那个通行证的同志不准进入

图片上传刷新页面:

  • react-native中的机制,上传图片是app触发的,所以需要查看app的代码。代码在上一部分已经给出,react-native老实说Big-man不是很熟悉, 曾经在一个大项目中接触过几个简单的功能,曾经的Big-man还被一位经验丰富的面试官打击了,曾经的历程就不再赘述。

react基本语法:

  • Big-man先来解释一下react的基本语法:
    • ReactDOM.render(): 就这个问题曾经有一位伙伴问过Big-man这个问题, React中的render()如何理解, Big-man沉思了一下,就在这时这位伙伴又发过来说是不是渲染的含义,Big-man就回复了如果你在牛津英汉词典或者有道翻译上都是这个解释,而且还会出现是计算机专业名称解释,但是如果是渲染的话,Big-man想不通,浏览器加载任何一个静态的html文件,也会称作浏览器渲染,但是为什么html文件里面没有render这个词汇,既然是说react中的render,Big-man就应该从react这群开发者”怪咖”出发,

Jackdan9 Thinking

发布评论

评论列表(0)

  1. 暂无评论