June
6月12日
获取屏幕宽度
data() {
return {
ScreenWidth: '', // 当前屏幕宽度
ScreenHeight: '', // 当前屏幕高度
}
},
let that = this;
that.ScreenHeight = window.innerHeight; // 屏幕高度
that.ScreenWidth = window.innerWidth; // 屏幕宽度
🏷️ document (网页)
含义 | 属性值 |
---|---|
可见区域 - 宽 | document.body.clientWidth |
可见区域 - 高 | document.body.clientHeight |
可见区域 (包括边线的宽) | document.body.offsetWidth |
可见区域 (包括边线的高) | document.body.offsetHeight |
正文全文 - 宽 | document.body.scrollWidth |
正文全文 - 高 | document.body.scrollHeight |
被卷去的 - 高 | document.body.scrollTop |
被卷去的 - 左 | document.body.scrollLeft |
🏷️ window (屏幕)
含义 | 属性值 |
---|---|
正文部分 - 上 | window.screenTop |
正文部分 - 左 | window.screenLeft |
屏幕分辨率 - 高 | window.screen.height |
屏幕分辨率 - 宽 | window.screen.width |
可用工作区 - 高 | window.screen.availHeight |
可用工作区 - 宽 | window.screen.availWidth |
窗口 - 高 | window.innerHeight |
窗口 - 宽 | window.innerWidth |
6月13日
父子组件数据双向绑定
- 问题描述
在写前端代码时,遇到一个逻辑错误。
首先,我编写了一个子组件(四个tab按钮,点击切换对应内容),并在父组件里引用。当我点击其中一个tab时,获取到这个tab的下标,子组件通过 emit
传给父组件,判断显示对应的内容。这时,数据是单向流动的
但是,在父组件这边,我还有一个需求,如果路由有携带参数,我需要获取这个参数,并传给子组件,改变了原有的值,让其对应的tab处于激活状态,。这时,数据就是双向的
但控制栏中就会报出以下错误:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
- 原因
props
中的数据只能单向流动,即只能从父组件通过组件的DOM
属性attribute
传递props
给子组件子组件只能被动接收父组件传递过来的数据,并且在子组件中,不能修改由父组件传来的 props 数据。
- 解决
父组件
<ChildLayout
v-model="currentIndex" // 父子组件双向绑定的值
:banImg="banImg"
:navList="navList"
@getCurrentIndex="getCurrentIndex" // 获取子组件传递过来的值
></ChildLayout>
父组件的业务逻辑
created() {
// 业务需求,根据路由获取的参数进行判断,并传给子组件
if(this.$route.query?.tabId) {
this.currentIndex = Number(this.$route.query.tabId)
}
},
methods: {
// 获取子组件传递过来的值
getCurrentIndex(e) {
this.currentIndex = e;
}
}
子组件
<view class="tab_box">
<ul class="tab_ul">
<li
class="tab_item"
:class="navIndex == currentIndex ? 'tab_item_active':''"
v-for="(nav,navIndex) in navList"
:key="navIndex"
@click="handleClick(nav,navIndex)"
>{{nav.name}}</li>
</ul>
</view>
子组件的逻辑处理
export default {
model: {
prop: 'currentIndex',
event: 'getCurrentIndex'
},
props: {
...
// 获取当前父组件路由所接收到的tab下标
currentIndex: {
type: Number,
dafault: 0
}
},
methods: {
// tab点击事件
handleClick(item,index) {
this.$emit('getCurrentIndex',index)
//以下是原先的写法,相当于直接改变 props 的值,会报错。
//this.currentIndex = index;
},
}
}
我们在子组件内 自定义model
,其有 prop
与 event
属性,而我们在子组件内触发在model定义好的event,通过this修改prop后,父子组件的count值都发生了改变,说明实现了双向绑定。
这里其实还有一种方法,就是对父组件传递过来的props值,进行监听,然后再用 emit
传回给父组件
- 📖 参考文档
输入框点击回车触发事件
- 原生的input,使用
@keyup.enter
<input v-model="" placeholder="" @keyup.enter="事件"/>
- 如果是element-ui,则要加上native限制符 [
@keyup.enter.native
]
<el-input v-model="" placeholder="" @keyup.enter.native="事件"></el-input>
6月14日
前端处理数据,根据月份做数据分组
- 问题描述
当后端传回来的数据是以下这种格式:
{
dateList: [
{
date: '2023-06-01',
content: 'xxx'
},
{
date: '2023-06-02',
content: 'xxx'
},
{
date: '2023-07-02',
content: 'xxx'
},
],
}
需要对上述的数据做成,6月份的日期为一组,7月份的日期为一组,样式如下
左侧的数字,是天数(day)
- 解决
首先,先对日期格式做处理
// 日期格式处理
dealData(arr) {
// 遍历后端传过来的数组,拿到每一条数据的日期
for (let i = 0; i < arr.length; i++) {
let num = new Date(arr[i].date);
let str = '';
// 对日(天数)进行截取 例:2023-06-14 截取最后两位
let day = arr[i].date.substring(8,10);
// 如果天数是 0-9 则去掉 0
if(Number(day) <= 9) {
day = arr[i].date.substring(9,10);
}
// 对处理好的数据进行拼接(分组单位,年,月,日等)
str += num.getFullYear() + ' / ';
str += num.getMonth() + 1;
arr[i].date = str;
//console.log(str)
// 往每一条数据里添加新的属性,天数
Object.assign(arr[i],{day: day})
}
// 处理好日期之后,开始对数据进行按月份分组,并返回
this.formatList = this.dataResort(arr); // 方法一
this.formatList = this.arrGroup(arr, (item) => item.date) // 方法二
},
按月份分组
方法一
dataResort(data) {
// 定义空数组,用于存储新组装的数据
let newArr = [];
// 遍历数组
data.forEach((item, i) => {
// 默认当前操作的数据下标 -1
let index = -1;
// 判断数组中是否已经存在当前遍历数据的时间
let isExists = newArr.some((newItem, j) => {
if (item.date == newItem.date) {
// 存在就保存当前数据下标 用于插入数据
index = j;
return true;
}
})
// 如果没有就存储一条新对象数据
if (!isExists) {
newArr.push({
date: item.date,
subList: [item]
})
} else {
// 如果有就插入到已存在的对象中
newArr[index].subList.push(item);
}
})
// 返回新数组
return newArr
},
方法二
arrGroup (arr, fn) {
const keyArr = [...new Set(arr.map(item => fn(item)))];
// filter里过滤的内容 就是分组属性判断
return keyArr.map(key => arr.filter(i => i.date === key));
}
6月15日
async / await 接口报错
- 问题描述
Unexpected reserved word 'await'
- 原因
在用 async/await
调用接口时,忘记加
async 或者 async 加错位置
。
- 解决
TIP
async
应该放在 与await最近的函数
,注意不能
放错放到handleSubmit前面
。这里的async后面是一个箭头函数。
修改host文件,github 仍然无法访问
- 解决
在修改完 host
文件后,需要执行以下命令,刷新本地dns数据,即可访问
$ ipconfig /flushdns
- 补充(2023/06/21)
还可以使用 FastGithub 进行加速
6月29日
nextTick 错误
- 问题描述
Error in nextTick: "RangeError: Maximum call stack size exceeded"
- 原因
当出现这个报错时,说明你有两个components的名称是一样的,所以在调用时两个循环调用不能结束就溢出栈了。
- 解决
组件中的 name
不能与 组件名
相同
- 📖 参考文档
vue 给每一页添加title
- 添加meta属性
meta: {
title: 'xxxx'
}
- router.beforeEach
// 这个方法是为了每个页面添加属于自己的title
router.beforeEach((to, from, next) => {
if (to.meta.title) {
document.title = to.meta.title
}
next()
})
- 📖 参考文档