bhbc开发Q&A

感谢!!!

中途文章被覆盖了!!!
感谢大佬!!救命帖!!
!!!!!!!!!!!

git相关

git拉取报错

拉取时报错 The project you were looking for could not be found.
在这里插入图片描述

1.首先确认vpn连接正常
2.前往控制面板-用户账户-凭据管理器控制面板-所有控制面板选项-凭据管理器在"Windows凭据"下找到git地址,更新git账号。(尝试有效!)
在这里插入图片描述
3.还是报错可以尝试通过以下命令卸载重装git credentials manager
$ git credential-manager uninstall 卸载
$ git credential-manager install 安装
参考博客

git报错 Cannot do a soft resset in the middle of a merge

git reset --merge 取消合并 (亲测有效)
or
git rebase 将当前分支重新设置基线

git提交修改的时候报错: 无法推送refs到远端

运行命令 git pull origin yourBranch -f

git有冲突,解决冲突

1.提交代码时有冲突会把有冲突的版本的更改全拉下来,不要慌
2.在源代码管理会有显示冲突的文件,点开文件可以看到冲突的两版本内容
3.可以选择"now…“(当前版本)或”"(上一版本)解决冲突
4.解决后保存,在源代码管理中暂存解决完冲突的文件
5.最后将所有的更改提交,推送就ok了(完美)

vue相关

引用自定义组件,多次使用组件间会相互影响

同一组件在页面中使用多次,对其中一个进行操作后会对其他组件有影响而产生报错

1、使用组件时绑定了同一变量,试试区分两个组件绑定值
2、引用时只创建里一个组件实例,试试区分两个实例
参考博客

IOS页面会上下弹性滚动

再IOS中一个页面存在一个滑动框,滑动滑动框里内容,会偶尔将整个页面滑动,类似bounce回弹

使用代码 ([参考博客] (https://blog.youkuaiyun.com/a460550542/article/details/90598711)) --亲测不可用!只会禁止整个页面的滚动

document.body.addEventListener('touchmove', function (e) {
  e.preventDefault(); //阻止默认的处理方式(阻止下拉滑动的效果)
}, {passive: false}); //passive 参数不能省略,用来兼容ios和android

亲测可用,只需要再整个页面加个样式
height: 100%; width: 100%; position: fixed; top: 0; left: 0;

复制文本到剪切板

//复制文本
  copyText(text) {
    // 直接构建input
    const _input = document.createElement("input");
    // 设置内容
    // _input.value = text;
    _input.setAttribute("value", text);
    // 添加临时实例
    document.body.appendChild(_input);
    // 选择实例内容
    _input.select();
    // 执行复制
    document.execCommand("Copy");
    // 删除临时实例
    document.body.removeChild(_input);
  },

但是还会有个问题… 如果文本是需要发接口查询返回,查完接口success里调用复制方法,会导致复制失败
目前的解决办法: 更换发接口时间,避免发完接口直接复制(还没有完美解决办法)

使用emoji

带有emoji的文本想要保存到后端,但是因为编码问题导致直接传到后台会乱码$*d@&1K(瞎写的)

可以传后端之前将带有emoji的文本编码成字符串
从后端取到后再解码成带有emoji的文本

//emoji编码
  emojiEncode(e) {
    var n = /[\ud800-\udbff][\udc00-\udfff]/g;
    return e = e.replace(n, function (e) {
      var n, r;
      return 2 === e.length ? (n = e.charCodeAt(0), r = e.charCodeAt(1), "&#" + (1024 * (n - 55296) + 65536 + r - 56320) + ";") : e
    })
  },

  //emoji解码
  emojiDecode(e) {
    var n = /\&#.*?;/g;
    return e.replace(n, function (e) {
      var n, r, t;
      return 9 == e.length ? (t = parseInt(e.match(/[0-9]+/g)), n = Math.floor((t - 65536) / 1024) + 55296, r = (t - 65536) % 1024 + 56320, unescape("%u" + n.toString(16) + "%u" + r.toString(16))) : e
    })
  }

在页面显示网络链接图片

需要显示链接图片,例如https://i0.hdslb.com/bfs/archive/ca375eb31fa90b8e23b88ed3433c2f60de1c2e6e.png

需要再img标签里添加一个属性

<!--let url = "https://i0.hdslb.com/bfs/archive/ca375eb31fa90b8e23b88ed3433c2f60de1c2e6e.png";-->
<img
   class="img"
   :src="url"
   referrerpolicy="no-referrer"
 />

在页面显示base64图片

需要显示base64图片,例如 (base64太长了)

需要在标签里的src属性拼接一下

<!--let url = "bolabolabola(base64)";-->
<img
   class="img"
   :src="'data:image/png;base64,' + url"
 />

input想要只输入数字

<input type="number" :maxlength="20"/> 这样安卓没有问题,ios还是能输入其他

<input type="number" pattern="[0-9]*" :maxlength="20"/> 这样ios会弹出是有数字的键盘

input类型为number限制字数

<input type="number" :maxlength="20"/>

字数没有限制,number换成其他就可以

在输入回调里控制 (这里是组件的回调)
@on-change="
() => {
if (idNo.length > 20) idNo = idNo.slice(0, 20);
}
"

实现播放mp3

实现播放MP3文件
参考博客

<template>
  <x-view id="P180301">
  	<!--触发播放音频按钮-->
    <x-view @click.native="playAudio">Play</x-view>
    <audio id="audioPlayer" autoplay="autoplay">
    <!--音频资源-->
      <source
        id="tts_source_id"
        src="../../../assets/beinvited.mp3"
        type="audio/mpeg"
      />
    </audio>
  </x-view>
</template>
<script>
export default Page({
	playAudio() {
	    var ttsAudio = document.getElementById('audioPlayer');
	    ttsAudio.play(); //播放音频
	},
})
</script>

样式还没有实现(凑合)

运行程序时报错'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序

切换分支后运行程序报错了↓
在这里插入图片描述

原因还不太清楚,突然就不行了(难道突然版本就不对了??)
解决方法:重新下载安装最新的 webpack-dev-server
命令:npm install webpack-dev-server --save-dev

地图&搜索

这里使用的sdk已被弃用,无法限制搜索类型,最新需要使用WebService
需求:进入页面显示当前定位,搜索展示位置列表

参考文档:腾讯位置服务

<!--xMap组件-->
<template>
  <div :id="id">
    <slot></slot>
    <div class="x-map-relocate" v-if="local" @click="onLocalClick">
      <img
        width="25"
        height="25"
        src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAYFBMVEUAAABRUVFRUVFSUlJRUVFRUVFRUVFRUVFSUlJSUlJSUlJSUlJSUlJRUVFSUlJSUlJSUlJTU1NSUlJSUlJSUlJOTk5SUlJSUlJSUlJRUVFTU1NSUlJSUlJRUVFSUlJSUlJ5TLkYAAAAH3RSTlMAqhzjh/K7FUTa7T1f1Z2PVCWwLGgNfnY3owjLyL5OoP/65AAAA9RJREFUeNrtm9ly6yAMQAXYxmscr82u///Le6fTQnaEgZJ2cp4TIYOEJBDw5o0TnKVp30E0eIn/KTnEguEnDGKR4icpxAK/ACJvBf6SAlNVz6sMv8hWc11N8FMM46rBOzSrcYDgDHODTxBtDgHhiUAjIuEQhrxHIn2Iacj3aEGzBr9sjmjJoQJ/yC0ugEnwRF3iDQVLxhy/yMeE3THPsvZj+tnN4O1a3u6Ect0WeEUmwZm8vDKveXi8FQ/JlQ7C2RLGq086mWJBxfCCGVzYXUpbcUow6lZ4DnMJOdmFpI4aDbsLvY8TLEQeUFPkNuG4alCzlwvHPxeS7OzygV2CmmaRBtMeFWLzLCkt4R4bcTYH0wL7y8zu3D81M3kuYbcg51ck8IDOUJi0Dr7wgYqP56UZ43QpdHJU1OBAjYoKLJCCMj5dA+sSMqPPHH0tsyVqJ+BMaz+ZsqQobT+dpbT1QEH6B92gtkCiwm824IWNpcCjNgBPJCowWm0BxQ48sVNhLQcze/udg76qB4sJYOARRp8CVX8N4JGO/Flc5X/gFZUncqrBcvBKR3Ut8V3gglf00gqiuebgF23cG9IKNOCdgrQGhUM9Q7SuAp4wOPogSXZnrAS1lkHWYCR4awsBaAk7zHfQWEMA1mYDn/ALSRTJijQtmFKXuMlOxl2goA0vVOCmqSCMYbbWEYO+pPTcpTcmp7MWRx/f/i+z0QlGskVpTvTjnpUxgc7JTq0R9HCQ3S0y8Q5p39EmQLvuMtm8xAeU3Fi8G5J+kmyGD2GkFbjvu3TZKT4khbukDr9UpJQflQEV0LJ7H0vQwDl2sjv/RkiSbXYVxsO5IeOvtBG9ylZsE4wSx2DkHo6TAOG4UutJ4aTsoDg5JCROKdm2SdNma52SvW5SGj8tH5UReEebQP3KpZm5hHUvThuXEjZ8eb4JdkBxUgcUkY5oMqJ9JwZTcT6kmiMd023V6VuUg0rtgyzSUW2vjDvKYbX+qkOk4/pCTUCUCwtdymdRrmzsBW6DXVr9lmu7s4vL1uvF5e+5ug1yeS2kveG6azCiogrVwNB3RCmWMDRbIg/QwqExNLGYe8vl8UxC0Dae9L4ZCVQcpt/YyAQg96gpKhsF8gI1B+mnmS0bqAoM7OJ/k792vm5BO9/2hxsac62z+16ujVlTJOFaOg09aQrRrvmtAnzdCnJTq3tbr+gv23p7Q1tvjMbmrQR/bLJIrd2a6mg1fJD+eoZEmGH4wA8cZg4Ggj7xqCA4Xf3okUvdgYG/8cznJR46vRV4EQVUb3ks+thPPru4j151b/mbNy78A1GCgngNVC3TAAAAAElFTkSuQmCC"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'x-map',
  data() {
    return {};
  },
  // 接收外部请求
  props: {
    // id
    id: {},
    // 经度
    longitude: {
      default: 116.39747,
    },
    // 纬度
    latitude: {
      default: 39.908823,
    },
    // 缩放级别
    scale: {
      default: 16,
    },
    // 标记点
    markers: {},
    // 路线
    polyline: {},
    // 多边形
    polygons: {},
    // 圆
    circles: {},
    // 缩放视野以包含所有给定的坐标点
    'include-points': {},
    // 显示带有方向的当前定位点
    'show-location': {},
    // 是否支持缩放
    'enable-zoom': {
      default: true,
    },
    // 是否支持拖动
    'enable-scroll': {
      default: true,
    },
    local: {
      default: true,
    },
  },
  // 监听器
  watch: {
    latitude(value) {
      //
      this.myLatlng = new qq.maps.LatLng(this.latitude, this.longitude);
      //
      this.mapObj.setCenter(this.myLatlng);
      //
      this.initMaks(this.myLatlng);
    },
    longitude(value) {
      //
      this.myLatlng = new qq.maps.LatLng(this.latitude, this.longitude);
      //
      this.mapObj.setCenter(this.myLatlng);
      //
      this.initMaks(this.myLatlng);
    },
    enableScroll(value) {
      // 设置选项
      let myOptions = {
        zoom: this.scale,
        center: this.myLatlng,
        // 街道地图
        mapTypeId: qq.maps.MapTypeId.ROADMAP,
        // 缩放控件
        zoomControl: false,
        // 拖动
        draggable: value,
        // 地图类型控件
        mapTypeControl: false,
      };
      // 地图对象
      this.mapObj.setOptions(myOptions);
    },
  },
  //
  methods: {
    onLocalClick() {
      //
      this.$emit('bindlocal');
    },
    // 返回地图对象
    getMap() {
      return this.mapObj;
    },
    //
    initMaks(myLatlng) {
      // 标记
      this.marker && this.marker.setMap(null);
      //
      this.marker = new qq.maps.Marker({
        position: myLatlng,
        animation: qq.maps.MarkerAnimation.DROP,
        map: this.mapObj,
      });

      //
      if (this.geocoder) {
        this.geocoder.getAddress(this.myLatlng);
        this.geocoder.setComplete((result) => {
          //
          this.geoInfo = result;
          this.$emit('bindmaks', result);
        });
      }
    },
    // 显示地图
    initMap() {
      //
      if (!window.qq) {
        $Fw.Logger.debug('加载地图组件失败!');
        return;
      }
      // 地址解析
      this.geocoder = new qq.maps.Geocoder();

      // 经纬度
      this.myLatlng = new qq.maps.LatLng(this.latitude, this.longitude);
      // 设置选项
      let myOptions = {
        zoom: this.scale,
        center: this.myLatlng,
        // 街道地图
        mapTypeId: qq.maps.MapTypeId.ROADMAP,
        // 缩放控件
        zoomControl: false,
        // 拖动
        draggable: this.enableScroll,
        // 地图类型控件
        mapTypeControl: false,
      };
      // 地图对象
      this.mapObj = new qq.maps.Map(
        document.getElementById(this.id),
        myOptions
      );

      // 标记
      this.initMaks(this.myLatlng);
      //添加监听事件
      window.qq.maps.event.addListener(this.mapObj, 'click', (event) => {
        console.log(11);
        //
        event.geoInfo = this.geoInfo || {};
        //
        this.$emit('bindtap', event);
      });
    },
  },
  mounted() {
    // 移除腾讯地图logo
    this.$el.addEventListener('DOMNodeInserted', (e) => {
      let del = e.target.innerHTML;
      if (del.includes('到腾讯地图查看此区域') || del.includes('map.qq.com')) {
        e.target.remove();
      }
    });
    // 初始化地图
    this.initMap();
  },
  //
  // beforeDestroy(){
  //   window.qq.maps.event.removeListener(this.mapObj);
  //   this.$el && this.$el.removeListener('DOMNodeInserted')
  // }
};
</script>

<style lang="less">
/* .x-map-relocate {
    position: absolute;
    width: 25px;
    height: 25px;
    bottom: 10px;
    left: 15px;
    z-index: 1;
  } */
</style>

又包装了一个可以搜索的地图组件

组件里mounted不执行

写组件时mounted不执行 created执行

因为代码里本来就写了一个mounted = =

0false''

代码里遇到的,了解并记录一下
0 == false; //true
原理: 布尔值作比较的时候,会先把布尔转为数值,即 true→1 false→0
'' == false; //true
原理: 字符串比较的时候会转为布尔类型,即 空字符''→false 其他→true
0 == ''; //true
原理: 同上

接着
'0' == false; //true
原理: 字符串和数值类型比较的时候string会转化成number
'0' == ''; //false
原理: 字符串和字符串比较,不转类型
!!'0'; //true
原理: 懂?

比较灵异事件

两个值做等于比较,打印出来为"BB1092323","BB1092323",false
完全一模一样,但结果是false

第二个字符串开头有个空格!!

ios搜索组件弹出的键盘右下角按键名为“换行”

搜索组件中input中type为search,安卓弹出键盘有“搜索”按键,苹果键盘仍为“换行”

可以在组件内部或组件调用处,外部套一层<form action="javascript:return true"></form>
有的说<form action=""></form>也行,实测后发现不可用,这样点击“搜索”后会跳转页面

ios中input输入过长文字不可滑动

在input中输入过长文字会隐藏并可滑动查看,安卓如此
但ios中隐藏不可滑动,只可以长按选中文字形式滑动内容

暂无解决办法

数字格式修改

根据需求,数字展示万以上以万为单位,亿以上以亿为单位,整数不补0

// 数据格式处理 
// 超过万单位用万,超过亿单位用亿,整数不补0
// defValue--默认值,无value时显示
export function numberDataFormat(value, defValue) {
  if (!value) return defValue;
  let reValue = value < 0 ? -Number(value) : Number(value); //修改为整数值
  if (reValue >= 100000000) { // 亿
    reValue = Number(parseFloat((Number(value) / 100000000).toFixed(2))).toLocaleString() + '亿';
  } else if (reValue >= 10000) { // 万
    reValue = Number(parseFloat((Number(value) / 10000).toFixed(2))).toLocaleString() + '万';
  } else {
    reValue = Number(parseFloat(Number(value).toFixed(2))).toLocaleString();
  }
  return reValue;
}

数据加密解密

跳转三方链接页面,需要传送敏感字段,需要加密

参考文档
有两种加密引用包,crypto-js和JSEncrypt
可根据所需的不同加密形式进行选择
需要提供秘钥,放到配置中(一般后端提供)

// 使用AES加密
import CryptoJs from 'crypto-js'
getJSEncrypt(cfg, keyString){
  const key = CryptoJs.enc.Utf8.parse(keyString);
  const word = CryptoJs.enc.Utf8.parse(cfg);
  const encrypted = CryptoJs.AES.encrypt(word, key, {mode: CryptoJs.mode.ECB, padding: CryptoJs.pad.Pkcs7});
  return encrypted.toString();
},

获取本地文件

获取本地文件并上传到OSS

还没做完,写下大概思路吧
选择文件使用<input type="file"/> 加载文件使用FileReader
tips:
数据格式和网上说的不太一样,需要在浏览器查看数据
手机上会有因权限不允许导致触发error
手动触发onerror方法:在读取前debugger住,再修改文件名称,再继续运行
FileReader文档

<!--accept:限制选择类型 multiple:允许多选-->
<input
  @change="onChangeFile"
  type="file"
  accept="*"
  multiple
  id="fileInput"
/>
<!--加载状态-->
<x-view>{{ readyStateMap[readyState] }}</x-view>
readyState = 0;
readyStateMap = ["未开始加载", "加载中", "加载结束", "加载失败", "加载成功"];
onChangeFile(e) {
    console.log("===========onChangeFile", e, e.target.files[0])
    let files = e.target.files;
    let that = this;
    if (!files || !files.length) return false;
    const fileReader = new FileReader();
    that.readyState = fileReader.readyState;
    console.log("========create fileReader", fileReader, fileReader.readyState);
    fileReader.onloadstart = (p) => {
      console.log("========loadstart", p, fileReader.readyState);
      that.readyState = fileReader.readyState;
    }
    fileReader.onloadend = (p) => {
      console.log("========loadend", p, fileReader.readyState);
    }
    fileReader.onload = () => {
      console.log("========onload", fileReader.result);
      that.readyState = '4';
    }
    fileReader.onerror = (err) => {
      console.log("========onerror", err.target.error.message, err.target.error.code, fileReader.readyState);
      that.readyState = '3';
    }
    // 1表示未找到文件,2表示安全性错误,3表示读取中断,4表示文件不可读,5表示编码错误。
    fileReader.readAsText(files[0]);
  },

CSS相关

换行

word-wrap: break-word;

absolute垂直居中

top: 50%;
margin-top: -10px; //10px为高度的一半

图片显示不变形

需要显示图片在正方形容器里,且不改变原比例
比如: 图片是这样滴
在这里插入图片描述
直接展示:

.pic {
  height: 60px;
   width: 60px;
   margin: 10px 17px 13px 0;
}

在这里插入图片描述
改为根据最大边保持原比例,保留左下角

.pic {
    height: 60px;
    width: 60px;
    margin: 10px 17px 13px 0;
    object-fit: cover; // 根据最大边保持比例
    object-position: bottom left; // 显示左下角
  }

在这里插入图片描述
改为根据最小边保持原比例

.pic {
  height: 60px;
   width: 60px;
   margin: 10px 17px 13px 0;
   object-fit: contain;
 }

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值