摸鱼日记一

一、css

1、毛玻璃

https://ithelp.ithome.com.tw/articles/10208692

2、绑定class
方式一内联
 :class="item.itemType==5 ? 'company-info' : 'company-infos'

绑定多个calss:  :class ="[index == 0?'':'op-bg2',index == 2? 'mini-grey':'op-bg']"


简化
<div v-bind:class="[{ active: isActive }, errorClass]"></div>

active为类名 依赖于isActive真值
方式二 -对象
<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

方式三 计算属性
<div v-bind:class="classObject"></div>

data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

3、导航栏滚动分离
ul.left-nav {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    overflow-x: hidden;
}
4.隐藏div滚动条
/deep/.department .ivu-col-span-4 .ivu-card-body::-webkit-scrollbar{
  display: none !important;
}

// 火狐隐藏滚动条
5.对象样式
:value-style="subItem.nums == 0 ?{ 'padding-right': '40rpx' }:''"
6.下拉框 --页面可移动
overfow:hidden
7.字体在标签内平均分布
display: inline-block;
width: calc(100% - 26rpx);
text-align-last: justify;
8.pc端下拉框层级问题
transfer属性
9、渐变边框 border-radius无效问题
利用矩形裁剪
clip-path: inset(0 round 10px);

二、ui框架🕳

uview坑🕳

1.swiper

问题:宽度三栏都定死,无法动态改变uview的值

解决方案:

①给swiper绑定高度样式

<swiper :current=“swiperCurrent” :style=“height:calc( i t e m H e i g h t ∗ {itemHeight}* itemHeight{length}*1rpx)” @change=“change” @transition=“transition” @animationfinish="animationfinish">

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEZexCVy-1673254944983)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20201023114753507.png)]

②在change事件里面重新计算高度

image-20201023114956527

<i:style="{'color':isBling?'red':'white'}" @click=""></i>

2.flex布局文本溢出不换行问题

word-wrap:break-word;

word-break:break-all; //work

仲系唔得就用white-space: normal;

3、form校验日期问题

校验时加上 type:‘date’

4、表格内容为空替换为“-”且加上tooltip


// 定义统一方法
function handleData (h, params){
    return h('Tooltip', {
        props: {
          placement: 'top'
        }
      }, [
        params?params:'--',
          h('span', {
            slot: 'content',             //slot属性
            style: {
              whiteSpace: 'normal',
              wordBreak: 'break-all',
              width:'100%'
            }
          }, params?params:'--')]
    )
}

// 使用
 render: (h, {row:{certLevelName}}) => {
            return handleData(h,certLevelName)
  },

饿了么坑🕳

单选or多选失效

        <!-- <el-checkbox
          v-for="(item, index) in handleList"
          :key="index"
          v-model="resultObj.codeList"
          :label="item.jgczid"
          >{{ item.actionNote }}</el-checkbox
        > -->
  <el-checkbox-group v-model="codeList" >
    <el-checkbox v-for="item in handleList" :label="item.actionCode" :key="item.actionCode">{{item.actionNote}}</el-checkbox>
  </el-checkbox-group>  

未发现乜原因,可能系格式化代码问题

vantui坑🕳

时间选择器

  <van-datetime-picker
  wx:if="{{showTime}}"
  type="date"
  placeholder="xx日前消除隐患"
  value="{{ currentDate }}"
  min-date="{{ minDate }}"
  formatter="{{ formatter }}"
  data-index="{{index}}"
  data-type="cleanDanger"
  bind:confirm="changeAdd"
  bind:cancel="close"
  v-model="currentDate" 
  custom-class='currentDate'
  :min-date="minDate1"
  :formatter="formatter"  // 无用
  bind:input="onInput"
/>
  onInput(e){
    this.setData({
      currentDate:e.detail,
    });
    console.log("时间控件",e)
  },
      
  timeFormat(_time) { // 时间格式化 2019-09-08
    let time = new Date(_time)
    let year = time.getFullYear();
    let month = time.getMonth() + 1;
    let day = time.getDate();
    return year + '-' + month + '-' + day 
  },     

三、js

1.Object.entries() 获取键值对

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-swx0YPc4-1673254944984)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20201102164715654.png)]

2.处理枚举值

image-20201105101830688

3.字符串数组转对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agn33OnP-1673254944984)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20201117144346033.png)]

item.rommateInfo = eval(‘(’+item.rommateInfo+‘)’);

4.解构赋值

}).then(({data: {list}}) => {
				list.map(item => {
					// 改id
					(item.id == id) && (this.docUrl = item.url)
				})

5.object.assign() 展开运算符替换object.assign()

1、数组 = Object.assign({title:title},records)

2、展开运算符
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象: { foo: "baz", x: 42, y: 13 }

6.获取数组某几个值

1、根据索引值
①不改变原数组--slice
②改变原数组--splice
// slice()方法
const sliceArr = arr.slice(-5)
console.log('sliceArr ',sliceArr) // 得到[34,0,56,12,2]

// slice(start,end)表示从下标start开始到下标end(不包括end)进行截取,得到的是一个新数组,不改变原数组。当start为负值时表示从倒数第几个元素开始往后截取,不填end的话就表示从倒数第几个元素开始截取,一直截取到数组末尾元素。


// splice()方法
const spliceArr = arr.splice(-5,5)
console.log('spliceArr',spliceArr) // 得到[34,0,56,12,2]

// splice()方法有三个参数,分别表示从哪个下标开始,删几个,新元素。可以实现增加,删除,替换数组元素的功能。arr.splice(-5,5)表示从倒数第五个元素开始,删五个元素。巧妙的是该方法的返回值是删除的元素集合。同时该方法改变了原数组。原数组变成了除了删除的元素剩下的元素集合。

7、filter用法

https://zhuanlan.zhihu.com/p/260517363

function remove(arr, item) {
    return arr.filter(val => val != item);
}

8、删除数组包含xx数据的某项

this.imgList.splice(imgList.indexOf(file), 1);

9、身份证等信息脱敏处理

{{basicInfo.idcardNo.replace(basicInfo.idcardNo.substr(14, 17), '****')}}

10、计算字符串长度&&按次数拼接字符串

   getByteLen(val) {
    var str = '';
    for (var i = 0; i < val.length -1; i++) {
         str += "*"
    }
    return str;
},

11、获取当前年月日

  // 获取当前日期
  getNowFormatDate() {
    let _this = this
    var date = new Date();
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    // 这里就要拿时分秒,不然会有卡顿情况
    var hh = date.getHours();
    var mm = date.getMinutes();
    var ss = date.getSeconds();
    if(hh < 10) {
      hh = '0' + hh
    }
    if(mm < 10) {
      mm = '0' + mm
    }
    if(ss < 10) {
      ss = '0' + ss
    }
    let str = month + '月' + strDate + '日'
    let dateStr = hh + ':' + mm + ':' + ss
    
    this.setData({
      date: str,
      time: dateStr
    })
  },

12、去掉字符串后几个值

str.substring(0, str.length - 6);

13.获取url参数

 方法一、
 const params = new URLSearchParams(location.search.replace(/\?/ig, ""));  // location.search = "?name=young&sex=male"
params.has("young"); // true
params.get("sex"); // "male"
 方法二、
 // 获取url的某个值
  getUrlkey(url) {
    var params = {};
    var urls = url.split("?");
    var arr = urls[1].split("&");
    for (var i = 0, l = arr.length; i < l; i++) {
      var a = arr[i].split("=");
      params[a[0]] = a[1];
    }
    console.log('5_结果:', params)
    return params;
  },

14、获取对象键值对

for (const [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`)
  console.log(key)
}

2、数组转对象键值对  怎么取怎么赋值
logoEnums[value] = title

15、toString与toLocaleString的区别

1、a.toString()"1234"  a.toLocaleString() "1,234"
2、var sd=new Date()
sd.toLocaleString()
"2017/2/15 上午11:21:31"

16、解构赋值配合rest使用

({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

17、修改对象或数组的键名

var  key =  'abc' ;
var  obj = {key :  '值' };  
// 复制原来的值
obj[key] = obj[ 'key' ];
// 删除原来的键
delete  obj[ 'key' ];

18、换行

\r\n   ---字符串拼接换行

19、关于for循环总返回最后一个值问题

https://es6.ruanyifeng.com/#docs/let

解决方法:将var改为let  因为var 的原因,遍历时候每次都会重写变量 i 的地址  作用域问题

上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。

如果使用let,声明的变量仅在块级作用域内有效,最后输出的是 6

20、js-cookie的使用

let v = JSON.parse(Cookies.get("userInfo"));

Cookies.set("userInfo", JSON.stringify(res.result), {
                        expires: 7
                      });

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4fWywXGf-1673254944985)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210611164554248.png)]

退出的时候清除cookie

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oAcPTY49-1673254944985)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210611164811825.png)]

21、判断android、ios终端

 var u = navigator.userAgent;
      var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android终端
      var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
      if (isAndroid) {
        this.phoneReszie();
      }

22、数组去重

const arr = [...new Set([0, 1, 1, null, null])];

// 更简单的es66666
this.value3 = Array.from(new Set(this.value3))

23、比较时间大小

// 直接用new Date()
changeTime(current,start,end){
          let startDate = new Date(current)
          let endDate = new Date(start)
          if (startDate && endDate) {
            if (startDate > endDate) {
              if (type == "startDate") {
                this.$message({
                  duration: 3000,
                  showClose: true,
                  message: "开始时间不能大于结束时间",
                  type: "warning",
                });
                this.params[current] = "";
              } 
            }
          }
        },

24、获取当前日期前一周时间

getDay(day){
   var today = new Date();
   var targetday_milliseconds=today.getTime() + 1000*60*60*24*day;
   today.setTime(targetday_milliseconds); //注意,这行是关键代码
   var tYear = today.getFullYear();
   var tMonth = today.getMonth();
   var tDate = today.getDate();
   tMonth = this.doHandleMonth(tMonth + 1);
   tDate = this.doHandleMonth(tDate);
   return tYear+"-"+tMonth+"-"+tDate;
 }

doHandleMonth(month){
   var m = month;
   if(month.toString().length == 1){
     m = "0" + month;
   }	
   return m;
 }

25、获取元素距离顶部高度

doc.getBoundingClientRect().top //元素距离顶部高度

25、点样只获取第二个参数

当然是用arguments[index]

25、reduce的使用

1)只获取每项的某个元素

let arr = numbers.reduce((total, currentValue)=> [...total,currentValue.name],[])

26、JSON字符串格式化展示

将字符串转成sjon对象再处理

JSON.stringify(JSON.parse(data), null, "\t")

27、默认参数

将字符串转成sjon对象再处理

const search = (arr, low=0,high=arr.length-1) => {
    return high;
}

27、替代递归处理树形化一维数组

由于递归性能耗费巨大巨大,用一次遍历替代!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XWVEl1q1-1673254944986)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\1669188640852.png)]

var arr = [
    {id: 1, name: '父级部门1', pid: 0},
    {id: 9, name: '父级部门2', pid: 0},
    {id: 2, name: '子级部门1', pid: 1},
    {id: 3, name: '子级部门2', pid: 9},
    {id: 4, name: '孙级部门', pid: 3},
    {id: 5, name: '部门5', pid: 4},
]

function toArr(arr) {
    const resList = []; // 结果
    const map = {}; // 映射
    for(const item of arr){
        let {id, pid} = item;
        map[id] = {...item, map[id]?.children || []}
    	if(pid == 0){
            resList.push(map[id])
        }else {
            map[pid] = map[pid] || {children:[]}
            map[pid].children.push(map[id])
        }
    }
	return resList 
}

四、uniapp

1、两个页面来回跳转,跳转太深导致难以返回上一级页面

使用uni.redirectTo()代替uni.navigateTo使得所跳转的页面唔入栈

https://uniapp.dcloud.io/api/router?id=navigateback

2.uniapp 路由传对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bc29Xbmt-1673254944987)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20201117161706375.png)]

五、git指令

1.手多多创建左分支点算啊?

①先git branch -a 查看所有分支

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GAOVMhfC-1673254944987)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20201103155250244.png)]

②再删除分支啦 git push origin --delete 分支名 记得唔要remotes同orign波,唔系会报错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mtmUDZie-1673254944988)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20201103155324068.png)]

2.克隆左项目之后点样切换分支啊?

git checkout -b dev-01-20210611 origin/dev-01-20210611

3、合并分支了咋?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tStq3QK4-1673254944988)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210225113229178.png)]

1、按 i
2、随便输入几个字
3、esc 
4、shift + :  
5、输入 wq  回车
小乌龟合并分支代码 https://blog.csdn.net/huangerbian/article/details/126038305?ops_request_misc=&request_id=&biz_id=102&utm_term=svn%E5%90%88%E5%B9%B6%E4%BB%A3%E7%A0%81&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-126038305.142^v63^control,201^v3^control_1,213^v2^t3_control2&spm=1018.2226.3001.4187

六、不要不要用jquery!!

1、监听input change事件并且获取value

	$("#searchInput").bind("input propertychange", function() {
				var inputValue = document.getElementById('searchInput').value
				console.log("改变了",inputValue)
	});

2、时间戳转换

https://blog.csdn.net/qq_26605049/article/details/88800376?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160878580416780310176491%252522%25252C%252522scm%252522%25253A%25252220140713.130102334…%252522%25257D&request_id=160878580416780310176491&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-88800376.first_rank_v2_pc_rank_v29&utm_term=js%E6%97%A5%E6%9C%9F%E8%BD%AC%E6%8D%A2%E6%97%B6%E9%97%B4%E6%88%B3

`

function timestampToTime(timestamp) {
	    var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
	    var Y = date.getFullYear() + '-';
	    var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
	    var D = date.getDate() + ' ';
	    var h = date.getHours() + ':';
	    var m = date.getMinutes() + ':';
	    var s = date.getSeconds();
	    return Y + M + D + h + m + s;
	}
   	// 注:时间戳转时间(ios手机NaN)
    function getTime(nS) {
        var date=new Date(parseInt(nS)* 1000);
        var year=date.getFullYear();
        var mon = date.getMonth()+1;
        var day = date.getDate();
        var hours = date.getHours();
        var minu = date.getMinutes();
        var sec = date.getSeconds();

        return year+'/'+mon+'/'+day+' '+hours+':'+minu+':'+sec;
    }
var date = new Date('2014-04-23 18:55:49:123');
	// 有三种方式获取
	var time1 = date.getTime();
	var time2 = date.valueOf();
	var time3 = Date.parse(date);
	console.log(time1);//1398250549123
	console.log(time2);//1398250549123
	console.log(time3);//1398250549000

七、vue

1、vuex噶使用(pc篇)

1、先系index.js

 state: {
        // 状态
        isdepartmentChoose:false,
        username:''|| localStorage.getItem('username'),
        departmentId:''|| localStorage.getItem('departmentId'),
        isTop:''|| localStorage.getItem('isTop'),
        oldDepartmentId:'',
        homeDepartmentId:'',
    },
    mutations: {
        // 改变方法
        handleUsername: (state, username) => {
            state.username = username
            localStorage.setItem('username', username)
        },
        handleDepartmentId: (state, departmentId) => {
            state.departmentId = departmentId
            localStorage.setItem('departmentId', departmentId)
        },
        handleIsTop: (state, isTop) => {
            state.isTop = isTop
            localStorage.setItem('isTop', isTop)
        }
    },
    getters : {
        username: (state) => state.username,
        departmentId: (state) => state.departmentId,
        isTop: (state) => state.isTop
    },

2.要用噶页面

 赋值
 this.$store.commit("handleUsername",this.select);
取值
this.isTop = this.$store.state.isTop

2、watch噶使用 --vue 强制组件重新渲染

https://blog.csdn.net/zyx1303031629/article/details/86656785

方法一、

<template>
   <third-comp v-if="reFresh"/>
</template>
 
<script>
   export default{
       data(){
          return {
                reFresh:true,
                menuTree:[]
            }
       },
       watch:{
             menuTree(){
 
                  this.reFresh= false
                  this.$nextTick(()=>{
                    
                    this.reFresh = true
                })
            }
       }
}
</script>

方法二、 好用过vif

<template>
   <third-comp :key="menuKey"/>
</template>
 
<script>
   export default{
       data(){
          return {
                menuKey:1
            }
       },
       watch:{
             menuTree(){
 
                ++this.menuKey
            }
       }
}
</script>

2.1watch监听对象里的值变化

‘对象.对象’

2.2 watch的val是浅拷贝!!

修改监听的值要深拷贝一下!不然会死循环

You may have an infinite update loop in watcher with expression "equipList"

3、计算属性computed

点解要用computed唔用方法?

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

watch与computed对比?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V1uNV7eU-1673254944989)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210223110143087.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P4WIFnuA-1673254944990)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210223110152513.png)]

4、Vue引入外部js变量和方法

.sync的用法

https://blog.csdn.net/liushijun_/article/details/92426854

//父组件将name传给子组件并使用.sync修饰符。
<Footers :name.sync="name">
</Footers>
//子组件触发事件
 mounted () {
    console.log(this.$emit('update:name',1234567));
 }
 

5、Vue父子组件子组件直接改变父组件props属性值

img

https://blog.csdn.net/yangwqi/article/details/112238528?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161467163816780271559082%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161467163816780271559082&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-2-112238528.first_rank_v2_pc_rank_v29&utm_term=Avoid+mutating+a+prop+directly+since+the+value+will+be+overwritten+whenever+the+parent+component+re-renders.+Instead%2C+use+a+data+or+computed+property+based+on+the+prop%27s+value.+Prop+being+mutated%3A+%22sa

// 避免直接更改props属性值  子组件中找一个中间变量传值
	// 避免直接修改props
      activeTopTemp: this.topActive,

6、只更新一次数据 v-once && 只触发一次点击事件

<span v-once>这个将不会改变: {{ msg }}</span>

<a v-on:click.once="doThis"></a>

7、filter的使用

  {{ addFileForm.visiRange | filterPerson }}
  
  
  filters: {
    filterPerson(value) {
      if (value == 1) {
        return "全部可见";
      } else if (value == 2) {
        return "按人员可见";
      } else if (value == 3) {
        return "按线路可见";
      } else if (value == 4) {
        return "按铁路单位可见";
      }
    },
  },

8、webpackChunkName注释

webpackChunkName 是为预加载的文件取别名,作用就是webpack在打包的时候,对异步引入的库代码(lodash)进行代码分割时(需要配置webpack的SplitChunkPlugin插件),为分割后的代码块取得名字

import异步加载的写法实现页面模块lazy loading懒加载(Vue中的路由异步加载):
Vue中运用import的懒加载语句以及webpack的魔法注释,在项目进行webpack打包的时候,对不同模块进行代码分割,在首屏加载时,用到哪个模块再加载哪个模块,实现懒加载进行页面的优化

9、命令

1、vue不是XX命令:npm i -g @vue/cli
2、卸载node:where node 找到node位置直接删掉
3、安装node:node官网找到历史版本,msi的直接安装

10、关于移动端适配使用rem问题

1、vue不是XX命令:npm i -g @vue/cli
2、卸载node:where node 找到node位置直接删掉
3、安装node:node官网找到历史版本,msi的直接安装

11、class的使用

class linkObj{
        constructor(name,text,type){
            if(text=='解职' || text== '岸基人员' || type == 3){
                this.source = name;
                this.target = center.name;
            }else {
                this.source = center.name;
                this.target = name;
            }
            
            this.label = {show:true}
        }
        getObj(){
            return this;
        }
      }
let obj = new linkObj(name,text,type);

12、动态使用assesst图片

require(`@/assets/fullview/ship/chuanjianlei.svg`),

13、自定义表头

// 获取头部
      selectHeader(e) {
        // 弄两个数组
        let keyArr = []
        let NameKeyArr = []

        // 循环表头
        this.checkList.forEach((item) => {
          let key = item.split('-')[0]
          let name = item.split('-')[1]
          keyArr.push(key)
          if(name == '船舶类型') {
            NameKeyArr.unshift({
              minWidth: '200',
              prop: key,
              label: name
            })
          }else {
            NameKeyArr.push({
              minWidth: '200',
              prop: key,
              label: name
            })
          }
        })

        // 给最后一列表头加东西
        NameKeyArr.push({
          button: true,
          label: '操作',
          group: [{
            name: '管理',
            type: 'primary',
            plain: true,
            onClick: (row, index) => { // 箭头函数写法的 this 代表 Vue 实例
              console.log("管理阿")
              console.log(row)
              this.goToShipDetail(row.tgcShipInfoId)
              // this.$router.push({path:'/manage9/page/index',query: {shipIds:row.TGC_SHIP_INFO_ID}})
            }
          }]
        })

        // 设置表头
        if(NameKeyArr.length) {
          this.tableHeader = NameKeyArr
        }else {
          //船舶名称(中文)
          this.tableHeader = [
            {
              prop: 'shipName',
              label: '船名',
              width: 200,
            },
            {
              prop: 'shipId',
              label: '船舶识别号',
              width: 200,
            },
            {
              prop: 'shipType',
              label: '船舶类型',
              width: 200,
            },
            {
              prop: 'lastReportTm',
              label: '最近进出港报告时间',
              width: 200,
            },
            {
              prop: 'lastSupervisionTm',
              label: '最近现场监督检查时间',
              width: 200,
            },
            {
              prop: 'lastControlTm',
              label: '最近船舶安全检查记录时间',
              width: 200,
            },
            {
              prop: 'riskAttribute',
              label: '船舶风险属性',
              width: 200,
              render: (row, index) => {
                return row.riskAttribute
              }
            },
            {
              prop: 'flagState',
              label: '标记状态',
              width: 200,
              render: (row, index) => {
                return row.flagState
              }
            },
            {
              button: true,
              label: '操作',
              fixed: 'right',
              group: [{
                name: '管理',
                type: 'primary',
                plain: true,
                onClick: (row, index) => { // 箭头函数写法的 this 代表 Vue 实例
                  console.log("管理阿")
                  console.log(row)
                  this.goToShipDetail(row.tgcShipInfoId)
                  // this.$router.push({path:'/manage9/page/index',query: {shipIds:row.TGC_SHIP_INFO_ID}})
                }
              }]
            }]
        }

        let checkedCount = this.checkList.length;
        this.checkAll = checkedCount == this.allHeaderArr.length;
        this.isIndeterminate = checkedCount > 0 && checkedCount < this.allHeaderArr.length;

        this.showTableSet = false
        this.listData()
      },

14、this.$confirm取消异步 async await

if(this.pagination.total > 500 && await this.$confirm('当前导出数据过多有可能造成导出失败,是否继续?', '提示', {
          distinguishCancelAndClose: true,
          type: 'warning',
          confirmButtonText: '保存',
          cancelButtonText: '取消'
        }).catch(() => {}) !== 'confirm') {
          return
        }
15、同一个页面使用相同的组件,组件里面使用节流Throttle,导致两个组件的值相同了,改了其中一个值,另一个组件的值也修改了。
const throttle = (fn, delay) => {
 var delay = delay || 200;
 var timer;
 return function () {
     var th = this;
     var args = arguments;
     if (timer) {
         clearTimeout(timer);
     }
     timer = setTimeout(function () {
         timer = null;
         fn.apply(th, args);
     }, delay);
 };
}

methods:{
	changeContentInput:throttle((e) => {
      console.log(e);
        _this.getAnalyticFormula(e);
      },500),
}

八、小程序 的崩溃历程

1、父子组件传值 && 子组件调用父组件方法

  • 父组件

    <common-dialog show="{{show}}" confirm="{{confirm}}" cancel="{{cancel}}" bind:confirm="confirm" bind:cancel="cancel">
    </common-dialog>
    
  • 子组件

      html
      
      <van-button type="info"  custom-class="confirm"  bind:tap="confirm">{{confirm}}</van-button>
       <van-button type="info"  custom-class="cancel"  bind:tap="cancel">{{cancel}}</van-button>
       
      css
      	
       confirm(){
          let _confirm = {confirm:true}
          this.setData({show:false})
          this.triggerEvent('confirm',_confirm)
        },
    

2、父组件调用子组件方法

  • 父组件

    1、引用
    <infoBox orderId="{{id}}" id="infoBox" bind:getTransOrderInfo="getTransOrderInfo"></infoBox>
    2、方法
      // 调用子组件方法
      getTransOrderInfo() {
        var infoBox = this.selectComponent("#infoBox")
        console.log(infoBox.data) //子组件的数据
        infoBox.getTransOrderInfo() //子组件的方法
      },
    
  • 子组件

      getTransOrderInfo() {
      }
    

3、微信小程序:使用普通链接二维码跳转到小程序,解析二维码携带参数(微信扫普通普通链接二维码和小程序里扫二维码解析参数方法)

https://blog.csdn.net/yuyu0yuyu/article/details/109310948

4、微信小程序打开PDF

后端要转成https – 要配置ngnix

若要在小程序内置环境打开,加上type:pdf 🌾

[‘upReportArr[’ + index + ‘].protectRegion’]:e.detail

5、微信小程序filters

https://blog.csdn.net/laishaojiang/article/details/82870470

6、wx.navigatorBack返回上一页携带参数


var pages = getCurrentPages();
var currPage = pages[pages.length - 1];   //当前页面
var prevPage = pages[pages.length - 2];  //上一个页面
 
//直接调用上一个页面对象的setData()方法,把数据存到上一个页面中去
prevPage.setData({
  data:data
});
wx.navigateBack({
    delta: 1
})

7、微信小程序跳转页面携带对象

页面一:
const details = encodeURIComponent(JSON.stringify(this.data.ArticleList[index]));
  wx.navigateTo({
    url: `../article-detail/article-detail?details=${details}`
  });
页面二:
const details = JSON.parse(decodeURIComponent(options.details));

8、组件样式隔离,无法使用公用样式问题

json文件添加公用样式
"styleIsolation": "shared"

8、onshow获取options

	// 获取当前小程序的页面栈
    let pages = getCurrentPages();
    // 数组中索引最大的页面--当前页面
    let currentPage = pages[pages.length-1];
    // 打印出当前页面中的 options
    console.log(currentPage.options)	

9、vant-dialog before-close用法 (深坑)

XHTML
<van-dialog
    use-slot
    class="dialog-box"
    show="{{ showDialog }}"
    show-cancel-button
    confirmButtonText="确定"
    before-close="{{ beforeClose }}"
 >
 JS(写在data里面)
 beforeClose(action) {
      console.log(action,222);
      return new Promise((resolve) => {
         setTimeout(() => {
           if (action === 'confirm') {
             resolve(true);
           } else {
             // 拦截取消操作
             resolve(false);
           }
         }, 1000);
      })
    }

10、微信小程序echarts层级覆盖其他组件

force-use-old-canvas=false”(这个更坑)
无办法的,只能控制显示隐藏然后重新刷新
以下介绍一下echarts的使用方法:

index.wxml
<view class="canvas-box" hidden="{{showSelect}}">
        <ec-canvas id="clock-dom-chart" canvas-id="clock-chart" ec="{{ clockChart }}"></ec-canvas> </view>
            
 index.js
 clockChart:{
    lazyLoad: true
 }

let ecComponent = this.selectComponent('#clock-dom-chart');
ecComponent.init((canvas, width, height, dpr) => {
        // 获取组件的 canvas、width、height 后的回调函数
        // 在这里初始化图表
        const chart = echarts.init(canvas, null, {
          width: width,
          height: height,
          devicePixelRatio: dpr // new
        });
        //调用设定EChart报表状态的函数,并且把从后端拿到的数据传过去
        chart.setOption(option);
        // 注意这里一定要返回 chart 实例,否则会影响事件处理等
        return chart;
});

11、微信小程序动态修改style

style="height:{{100 / typeList.length}}%"

12、微信小程序下载文件预览啥的

// 预览文件  url 文件路径
function previewFile(url,type) {
  console.log(url,type);
  
  let tempArr = type.split('.')
  let fileType = tempArr[tempArr.length - 1]
  let fileTypeArr = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf']
  let imgTypeArr = ['jpg', 'png', 'jpeg', 'gif']

  wx.downloadFile({
    url: url,
    success: function (res) {
      wx.hideLoading()
      const filePath = res.tempFilePath
      if (fileTypeArr.indexOf(fileType) !== -1) {
        wx.openDocument({
          filePath: filePath,
          fileType: type,
          success: function (res) {
            console.log('打开成功',res);
          },
          fail: (err) => {
            console.log('打开失败',err);
          }
        })
      } else if (imgTypeArr.indexOf(fileType) !== -1){  
        wx.previewMedia({
          sources: [{url:res.tempFilePath || url}],
          url: res.tempFilePath || url, // 当前预览资源的url链接
          success: function (res) {
            console.log('打开成功',res);
          },
          fail: (err) => {
            console.log('打开失败',err);
          }
        })
      }
    }
  })
}

13、微信小程序调用没有ssl证书的https(如 https:// 192.19.21.xx)

1、让后端配置http,体验版发布后打开开发调试模式即刻使用
2、由于PC版微信没有开发者模式无法使用http,可以选择下载一个手机模拟器安装微信使用

九、ES6&ES8

1、promise.all与promise.race

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

​ promise.all 并行执行多个异步操作,并且在一个回调中处理所有的返回数据

​ promise.race 排序进行,谁先执行的快,以谁为基准执行then

​ promise.allsettled:不管resolve还是reject,不用catch统一返回


Promise.all([runAsync1(), runAsync2(), runAsync3()]).then((results)=>{
    console.log(results);
});

Promise.allSettled(promises).
  then((results) => results.forEach((result) => console.log(result.status)));
2、async&await

异步函数同步执行

3、always

promise请求结束

4、处理async/await
function AsyncTo(promise) {
    return promise.then(data => [null, data]).catch(err => [err]);
}
const [err, res] = await AsyncTo(Func());

十、typora

1、文档之间跳转

https://blog.csdn.net/qq_41259552/article/details/107892376?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161473597516780269872146%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161473597516780269872146&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-107892376.first_rank_v2_pc_rank_v29&utm_term=typora%E6%96%87%E4%BB%B6%E9%97%B4%E8%B7%B3%E8%BD%AC

十一、JSSDK的坑

jweixin-1.2.0.js里面的执行方式不适合直接webpack。我看到的报错是cannot read title of undefined,不知道你们是不是这个问题。

这个问题的原因是,里面在执行this.document.title的时候出的问题,这个js期望实在浏览器全局作用域下执行(this指向window),但是webpack之后,是在一个function作用域下执行,因此this.document为undefined。

因此有几种方式修改:

改源码,将jweixin-1.2.0.js中第一个this改为window

在html中使用script引入

webpack有个script-loader可以让模块文件在global环境下执行,可以试试看

十二、node报错大全

image-20210630113159605

十三、webpack

vue.config.js配置https://webpack.docschina.org/configuration/

1、关于环境变量

https://www.jianshu.com/p/f4638f5df1c7

2、缩小打包体积

① 🚚 vue.config.js productionSourceMap设置为false

productionSourceMap:true 每个打包后的js文件都会有一个对应的map文件 不加密源码

map文件的作用:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。 有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。

3、图片打包优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DWyQS10r-1673254944990)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210723173912903.png)]

4、打包Html资源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-54HuszQm-1673254944991)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210723174628560.png)]

5、压缩css大小

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ELCa99Ut-1673254944992)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210725212146761.png)]

6、

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prQusaQh-1673254944992)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210727125622764.png)]

6、压缩html、js代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2OeA6QqH-1673254944992)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210727125749621.png)]

7、webpack打包性能优化 - HMR

开启热模块替换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4CGY0Y6G-1673254944993)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210727140653725.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P9f2okbF-1673254944993)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\image-20210727140719098.png)]

十四、dom-to-image兼容ios

问题:多个div转换成图片,拼接在一起生成一张截图

原方案:将每个div都生成图片,但ios大部分机型会出现背景图黑屏,最后一张无法渲染出来的情况。目前没研究出来什么问题,猜测是渲染机制问题?

​ 尝试解决一:网上说利用toSvg能解决问题,但测试过多张图片生成的时候,网页能出现生成的图片,但页面无法展示(有可能是图片层级太低,被覆盖了),且svg图片无法实现长按保存。

​ 尝试解决二:重复渲染多张图片,每张图片此时可以出来,但是最后生成的时候,偶尔会导致黑屏的情况,有可能是代码里面没有处理好渲染的顺序。

​ 尝试解决三:新写一个div,先将当前的四个div拼接在一起,直接生成拼接好的div。(这样有点蠢,但是他work了)。注意:此处不能用svg(会黑屏)。但是还有部分顽强的部分机型,第一次背景图会黑屏,第二次才正常!那就模拟用户多触发一下生成图片,终于work了!但是这样会慢一点且猥琐,但是目前没测试出更好的方法了QAQ。。。

十五、H5背景音乐兼容ios(微信浏览器) 自动播放

步骤一

npm jweixin

步骤二

var innerAudioContext = uni.createInnerAudioContext(); // 获取audio对象
jweixin.config({});// 不做任何签名验证都可以
jweixin.ready(function(){
	WeixinJSBridge.invoke('getNetworkType', {}, function(e){  
		innerAudioContext.play();
	})
})

十五、H5背景音乐兼容ios(微信浏览器) 自动播放

后端返回xls文件流怎么处理

		// 获取后端返回文件名
		response.headers.get('content-disposition')
		
		const content = res;
        const blob = new Blob([content]);
        const fileName = "疫苗接种情况明细.xls";
        if ("download" in document.createElement("a")) {
          // 非IE下载
          const elink = document.createElement("a");
          elink.download = fileName;
          elink.style.display = "none";
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href); // 释放URL 对象
          document.body.removeChild(elink);
        } else {
          // IE10+下载
          navigator.msSaveBlob(blob, fileName);
        }

十六、element-ui上传组件坑

1、accept属性无效问题

传闻中input的这个accept属性是可以的,但是不知道为什么不生效

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr

2、上传组件修改了file-list的数据然后报错cannot rear ‘status’ if undefined

在每次对file-List做删除操作后都刷新下页面this.$forceUpdate()

十七、element-ui输入框限制只输入数字

https://blog.csdn.net/ymumi/article/details/103275131?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_default&utm_relevant_index=4

十八、element-ui表单输入不更新问题

监听表单变化,然后validate一下

问题收录

一、vue的keep-alive对iframe页面不能缓存?
	思路:创建一个组件,并且不销毁
	只能缓存当前vnode节点上的内容 iframe不属于当前vnode节点
二、vue keep-alive缓存 缓存相同的路由,但传参不一样?
https://blog.csdn.net/lllomh/article/details/121017789
三、element-ui的form组件
	1、关于部分输入框 无法输入或选中  原因:没给初始值
	2、校验不生效 可能是没给prop

十八、vue组件清除缓存

https://www.jianshu.com/p/8cedd68d30ad

十九、app切换至后台提示

利用h5plus的前台切换至后台事件https://www.html5plus.org/doc/zh_cn/events.html#plus.Events.%22pause%22

// #ifdef APP-PLUS
// 监听设备网络状态变化事件
plus.globalEvent.addEventListener('pause', function(){
	showAlert()
});
// #endif

function showAlert(){
	plus.nativeUI.toast("温馨提示:海事一网通管已切换至后台");
}

二十、app端使用SQLITE实现离线缓存

参考https://blog.csdn.net/weixin_43512812/article/details/106050709?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165044203316780274186339%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165044203316780274186339&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-106050709.142

uni-app App 端内置 HTML5+ (opens new window)引擎,让 js 可以直接调用丰富的原生能力。

https://uniapp.dcloud.io/tutorial/use-html5plus.html

而H5+是支持SQLITE的,用法见https://www.html5plus.org/doc/zh_cn/sqlite.html

二十一、APP人脸识别 nvue

二十二、小程序适配刘海屏

二十三、导入文件流格式 -format

利用upLoad组件 action方法调用接口  需要白名单

二十四、eventBus的使用

//1、先在main.js上挂载
Vue.prototype.$bus = new Vue()//事件总线,主要用于非父子组件间的通信
//2、emit
this.$bus.$emit('getAccdList',{records:result.records,total:result.total})
//3、on
this.$bus.$on('getGovLoading',(res) => {
            this.loading = res
})
//4、销毁
this.$bus.$off()

二十五、vue-redirect指令的使用

//1、先在main.js上挂载
Vue.prototype.$bus = new Vue()//事件总线,主要用于非父子组件间的通信
//2、emit
this.$bus.$emit('getAccdList',{records:result.records,total:result.total})
//3、on
this.$bus.$on('getGovLoading',(res) => {
            this.loading = res
})
//4、销毁
this.$bus.$off()

二十六、nvm的使用

在git上下载nvm.setup 然后傻瓜操作

nvm use

切换node版本 乱码问题:切换至C:\Windows\system32  找到cmd.exe 用管理员身份打开。

二十六、低代码生成curd

1、增删改查配置页面
2、所需要的接口、所需要的的路由 有接口返回,在对应的文件中调用接口获取并返回
3、接口将所有配置页面的显示的字段全部返回为一个json,前端解析生成js文件
4、前端由路由去区分显示哪些内容

二十七、nginx配置

花生壳配置步骤:https://service.oray.com/question/15507.html

配合花生壳使用步骤:
	1、端口配置,首先需要查看本地端口是否被占用:
		1)查看被占用端口对应的PID,输入命令:netstat -ano | findstr 端口,回车,记录最后一位数字,即 pid
		2)继续输入tasklist | findstr PID,回车,查看是哪个进程或者程序占用了端口
	2、配置nginx.conf文件
	3、先将nginx的相关进程kill掉,然后再双击执行nginx.exe
	4、成功执行后,配置的端口server_name拼接能正确访问

nginx配置失效解决步骤:

1、先看本地127.0.0.1:端口,能否访问成功
2、看任务管理器中是否有nginx进程,双击打开之后还没有的话执行命令nginx.exe -t看什么问题
3、修改了nginx.conf重启nginx不生效的话,将nginx进程删掉然后多打开几次确保彻底清掉
nginx.conf修改

server{
	listen 8090;
	server_name xxx.com(localhost啥的也可以);
	// 访问配置
	location /admin {
	 	root /user/admin.com
	 	index index.html
	 	try_files $url(找文件) $url/(找地址) /admin/index.html   -- history配置 不然返回直接会跳转404
	}

	location /3683/ {
		  proxy_redirect off;
		  proxy_set_header Host $http_host;
		  proxy_set_header X-Real-Ip $remote_addr;
		  proxy_set_header X-Forwarded-For $remote_addr;
		  proxy_pass https://192.168.16.212:3683/;
		}

		location /3688/ {
		  proxy_redirect off;
		  proxy_set_header Host $http_host;
		  proxy_set_header X-Real-Ip $remote_addr;
		  proxy_set_header X-Forwarded-For $remote_addr;
		  proxy_pass https://192.168.16.212:3688/;
		}
}

二十八、阻止用户退出浏览器全屏bug

全屏状态下,浏览器禁止监听F11和ESC事件

解决思路:

1、引入screenfull插件 import screenfull from ‘screenfull’

2、监听fullscreenchange事件

3、禁用F11、ESC事件

4、写一个全屏按钮让用户点击

document.addEventListener("fullscreenchange", function (e) {
        data.isFullscreen = !data.isFullscreen
        if (document.fullscreenElement) {
          data.isFullscreen = true
        } else {
          if( data.isPassScreen == false ) {
            data.fullScreenDialog.show = true
            screenfull.toggle()
          }else {
            data.isFullscreen = false
            data.isPassScreen = false
            document.exitFullscreen()
          }
        }
      })

      methods.screenFull()

	window.onkeydown = function (event) {
          if (event.keyCode === 122 || event.keyCode === 27) {
            event.preventDefault()
          }
        }

二十九、搭建vue3项目

1、vue create 项目名

2、手动添加vue.config.js文件,配置如下

​ https://cli.vuejs.org/zh/guide/webpack.html#%E5%AE%A1%E6%9F%A5%E9%A1%B9%E7%9B%AE%E7%9A%84-webpack-%E9%85%8D%E7%BD%AE

3、配置package.json

4、配置路由

5、配置pinia npm install pinia@next

性能优化

1、数据过多的长列表可以用这两个优化性能(不在可视区域的不渲染)

https://juejin.cn/post/7168629736838463525

y_files $url(找文件) $url/(找地址) /admin/index.html – history配置 不然返回直接会跳转404
}

location /3683/ {
	  proxy_redirect off;
	  proxy_set_header Host $http_host;
	  proxy_set_header X-Real-Ip $remote_addr;
	  proxy_set_header X-Forwarded-For $remote_addr;
	  proxy_pass https://192.168.16.212:3683/;
	}

	location /3688/ {
	  proxy_redirect off;
	  proxy_set_header Host $http_host;
	  proxy_set_header X-Real-Ip $remote_addr;
	  proxy_set_header X-Forwarded-For $remote_addr;
	  proxy_pass https://192.168.16.212:3688/;
	}

}


# 二十八、阻止用户退出浏览器全屏bug

全屏状态下,浏览器禁止监听F11和ESC事件

解决思路:

1、引入screenfull插件 import screenfull from 'screenfull'

2、监听fullscreenchange事件

3、禁用F11、ESC事件

4、写一个全屏按钮让用户点击

```js
document.addEventListener("fullscreenchange", function (e) {
        data.isFullscreen = !data.isFullscreen
        if (document.fullscreenElement) {
          data.isFullscreen = true
        } else {
          if( data.isPassScreen == false ) {
            data.fullScreenDialog.show = true
            screenfull.toggle()
          }else {
            data.isFullscreen = false
            data.isPassScreen = false
            document.exitFullscreen()
          }
        }
      })

      methods.screenFull()

	window.onkeydown = function (event) {
          if (event.keyCode === 122 || event.keyCode === 27) {
            event.preventDefault()
          }
        }

二十九、搭建vue3项目

1、vue create 项目名

2、手动添加vue.config.js文件,配置如下

​ https://cli.vuejs.org/zh/guide/webpack.html#%E5%AE%A1%E6%9F%A5%E9%A1%B9%E7%9B%AE%E7%9A%84-webpack-%E9%85%8D%E7%BD%AE

3、配置package.json

4、配置路由

5、配置pinia npm install pinia@next

性能优化

1、数据过多的长列表可以用这两个优化性能(不在可视区域的不渲染)

https://juejin.cn/post/7168629736838463525

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-woRv5xr2-1673254944993)(C:\Users\DuckZ\AppData\Roaming\Typora\typora-user-images\1669946323520.png)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值