本博客主要用于记录开发的过程以及开发问题处理方式,不粘贴开发代码。问题的解决原理我会单独做文章。
失物平台(邑丢丢)的开发代码的码云地址是https://gitee.com/MyKyle/yidd
1.今日完成进度
1.完成了拾物信息上传模块的布局设计以及数据处理
2.利用Promise处理测距模块的异步回调
2.今日问题以及处理
2.1 chrome 67版本后无法拖拽离线安装CRX格式插件的解决方法
修改文件格式,加载扩展程序
有时候要在 chrome安装本地插件时,会报错,这时候将插件的后缀名 .crx 改为 .zip或者 .rar,然后将改好后缀名的文件解压到本地文件夹中,然后在 chrome 的设置 -> 更多工具 -> 扩展程序:
2.2 重写 van-field 组件
官方目前不支持多行文本,故我自己利用官方的类样式自己做了一个模块组件,同时 $emit 来传递填入的信息。目前这个重写的van-field支持多行文本,有需要的同学可以直接复制利用。
第一步:新建 vantFieldTextarea.js 文件存放组件模板代码
<template>
<!-- van-field组件的多行配置 -->
<div data-v-c9a74598 class="van-cell van-field">
<div class="van-cell__title van-field__label">
<span>{{label}}</span>
</div>
<div class="van-cell__value van-field__value">
<div class="van-field__body">
<textarea
class="van-field__control Textarea"
autocomplete="off"
placeholder="只限于100字以内噢"
maxlength="100"
cols="30"
rows="3"
v-model="pickUpMsg"
></textarea>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
pickUpMsg: ''
}
},
props: {
label: String
},
watch: {
pickUpMsg () {
this.$emit('inputValue', this.pickUpMsg)
}
}
}
</script>
<style lang="less" scoped>
.Textarea {
border: 1px solid #ced4da;
border-radius: 0.25rem;
padding: 0.5rem;
}
</style>
第二步:在需要引入组件内
<script>
import vantFieldTextarea from '../Base/Vant/vantFieldTextarea'
export default {
components: {
'vant-file-textarea': vantFieldTextarea
},
data () {
return {
pickUpMsg: ''
}
},
methods: {
getInputMsg (msg) {
this.pickUpMsg = msg
}
}
}
</script>
HTML 中
<vant-file-textarea v-bind:label="'拾取信息'" @inputValue="getInputMsg" />
上面代码中实现了 Vue-li 中组件相互通信的一个操作,父组件对子组件通信利用 props ,而子组件对父组件通信利用的是$emit 。更多具体的学习可以参考我的另外一篇文章:原创 一眼看完Vue组件化的使用以及理解
2.3 Vue的watch用法
watch用于监视数据发生变化,具体详解我会单独出文章。在这里主要用于在数据发生改变时,实时发送给2.2中父组件。
watch: {
// pickUpMsg 是双向绑定的数据属性名
pickUpMsg () {
this.$emit('inputValue', this.pickUpMsg)
}
}
2.4 在模块中利用Promise处理回调
上次说的我们把测距功能封装在一个JS模块中,利用引入模块的思想可以动态的使用测距函数。
当初导出的是一个测距功能函数:
export function rangeFinding (){ 功能代码... }
但其实这样做是不够完美的,在使用的时候就会发现我们通过下面的调用方式不能使用函数中的值。这个具体原因是由于存在函数内部作用域的问题,导致外部函数无法读取内部函数信息。
// 在需要调用的文件内引入 import { rangeFinding } from '../../functionJS/rangeFinding' 利用 rangeFinding() 调用
解决方案一开始我定了几套,分别是:
1.利用浏览器存储(sessionStorage,由于测距为一次性不考虑localStorage) 2.利用全局对象window,给window赋属性值的形式保存起来。 3.利用闭包的形式,一步步从内 return 数据到最外层 4.利用 Promise 的方式 ,可以进行异步处理。
下面根据需求进行最终选择:
1. 查看功能函数代码,可以看到有的函数体是以外部函数参数的形式存在的,故利用闭包进行获取内部值有些不合理。排除了做法三。
2. 考虑到我们的项目是要在移动终端运行,移动终端对sessionStorage会有一定的失误,有时候会丢失。所以为了确保出现错误的概率小,我们不选择做法一。
3. 没什么事就不要污染全局对象,这个是基本要求。就由此排除做法二。
做法四的实现:由于这个功能函数存在计时器,所以利用Promise做异步回调最好。当然我们可以使用 Generator 函数 或者async 函数 ,建于简单理解这里写的是Promise的教程。
// ranggeFinding.js文件中 var promise = new Promise(function (resolve, reject) { .... //测距反馈 if (status === 'complete') { // log.success(`快递点距离您 ${result.routes[0].distance} 米`) resolve(result) } else { // log.error('步行路线数据查询失败' + result) reject(result) } .... //定位错误 } else { result.message = errorMsg(result.message) reject(result.message) } } // 对错误信息分类 function errorMsg (msg) { switch (msg) { case 'Get geolocation time out.Get ipLocation failed.' : return '浏览器定位超时' // 浏览器定位超时 case 'Geolocation permission denied.': return '用户禁用了定位权限' // 需要用户开启设备和浏览器的定位权限,并在浏览器弹窗中点击“允许使用定位”选项。 case 'Browser not Support html5 geolocation' : return '浏览器不支持定位功能' // 如IE较低版本的浏览器等; } return '出现未知错误' }
// 所需测距功能文件中 import { promise } from '../../functionJS/rangeFinding' promise.then(function (value) { // eslint-disable-next-line no-undef log.success(`快递点距离您 ${value.message.routes[0].distance} 米`) }, function (value) { // eslint-disable-next-line no-undef log.error(value) }) }
2.5 浏览器报错 error Expected indentation of 8 spaces but found ? indent
由于Vue-li 初始配置了ESLint 让我们书写代码规范,所以存在一些各类型的报错。
今天由于使用了 HBuilderX 编译器开发,自己写代码时报 error Expected indentation of 8 spaces but found 2 indent 错误。主要原因在于该行代码前面的空格使用的是两个Tab,而不是8个空格出现的报错。报错的小伙伴自己敲8个空格即可。
主要是懒得改配置,嘻嘻。