开发项目中遇到的问题
css
last-child
和first-child
失效问题:
如果父亲元素里的子元素有包含其他不一样的标签时,会出现获取不到的问题。
当使用first的话,第一个子元素一定要是一样的标签.中间和最后可以是不一样的标签.
last最后一个元素标签要一致,前面和中间可以是不一样标签。
除了这些伪类,同样,其他的伪类在这种情况无法获取到。
vue
- 在使用
this.$router.push
实现路径跳转时,会延迟好几秒;
是因为query属性的原因,当query对象属性以及属性值内容太多时,会增长路径拼接的速度。 - 在使用图片的时候,直接使用开发环境的路径在标签内使用图片或者在css中使用背景图片都会无法显示。
第一种情况可以提前加载图片require(url)
- css中给元素添加背景图,
background: url(~@/img/page.png)
~是相对于其他路径(文件)的,类似于相对路径
所以background正常使用相对路径也是ok的。
vue之computed
computed是计算出来的属性, 相当于计算结果, 所以我们不能直接对结果进行修改!
- getter函数
负责使用data中的数据, 但是注意 只能用, 不能改! 使用完后 记得将结果return- setter函数
有一个参数 newValue, 负责接收传进来的值, 可以使用这个newValue给data中的数据进行操作:- 给computed创建的属性赋值,其实是传参给setter函数,触发set事件
现在有个需求: 想给options里添加新的数据, 如何操作?
// 1. 需要用到set函数:
computed {
objArr: {
get() { return this.options;},
set(newValue) {
console.log('newValue', newValue)
this.options.push(newValue);
}
}
}
// 2. 触发set函数 即给objArr赋值:
// 这里我们封装个方法:
methods: {
setObjArr() {
this.objArr = {b: 2}
}
}
// 通过按钮点击触发
<button @click="setObjArr">set</button>
/**这里的this.objArr = { b: 2 }并不是把{b: 2} 赋值给objArr的意思, 而是传参给里面的set函数。
触发setObjArr事件, 会发现 计算属性 objArr 已经改变了, 其本质是因为data中的options发生了改变。**/
provide 和 inject 之响应式
provide和inject :provide并不是响应式的,当子组件inject的时候已经丢失了响应式功能
希望整个数据都是响应式的—provide提供一个函数
。
函数内部返回一个响应式的数据。此时整条数据的响应式的状态并不会丢失。
父组件:
provide() {
return {
getActiveSecurityType: () => ({
activeSecurityType: this.securityType
})
}
},
孙后代组件:
inject: ['getActiveSecurityType'],
computed: {
activeSecurityType() {
return this.getActiveSecurityType();
},
},
}
watch: {
activeSecurityType(newVal) {
}
}
form校验
- validate:
对整个表单进行校验的方法,参数为一个回调函数。
该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。
若不传入回调函数,则会返回一个 promise
Function(callback: Function(boolean, object))
- validateField:
对部分表单字段进行校验的方法
Function(props: array | string, callback: Function(errorMessage: string))
<template>
<el-form
ref="form"
:model="form"
:rules="rules"
label-width="80px"
size="mini"
>
<el-form-item
label="姓名"
prop="name"
>
<el-input v-model.trim="form.name"></el-input>
</el-form-item>
<el-form-item
label="年龄"
prop="age"
>
<el-input v-model.number="form.age"></el-input>
</el-form-item>
<el-form-item
label="学校"
prop="school"
>
<el-input v-model.trim="form.school"></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="validate"
>校验全部</el-button>
<el-button
type="primary"
@click="validateField"
>校验单个字段</el-button>
<el-button
type="primary"
@click="validateFields"
>校验多个字段</el-button>
</el-form-item>
</el-form>
</template>
<script>
// created at 2021-09-23
export default {
name: 'TestForm',
data() {
return {
form: {
name: '',
age: '',
school: '',
},
rules: {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
age: [
{
required: true,
message: '请输入年龄',
trigger: 'blur',
},
{ type: 'number', message: '年龄必须为数字值', trigger: 'blur' },
],
school: [{ required: true, message: '请输入学校', trigger: 'blur' }],
},
};
},
methods: {
/**
* 校验全部字段
*/
validate() {
this.$refs['form'].validate((valid) => {
console.log(valid); // true/false
});
},
/**
* 校验单个字段
*/
validateField() {
this.$refs['form'].validateField('name', (errorMessage) => {
console.log(errorMessage);
let valid = errorMessage == '' ? true : false;
console.log(valid); // true/false
});
},
/**
* 校验多个字段
*/
validateFields() {
// 需要校验的字段
let fieldsToValidate = ['name', 'age'];
// 将回调转换为Promise
Promise.all(
fieldsToValidate.map((field) => {
return new Promise((resolve, reject) => {
this.$refs['form'].validateField(field, (errorMessage) => {
resolve(errorMessage);
});
});
})
).then((errorMessages) => {
console.info(errorMessages);
// ['请输入姓名', '请输入年龄']
// errorMessages 里是各个字段的验证错误信息, 如果数组里全为空串则所有验证通过
// 判断errorMessages 里是否全是空串
let valid = errorMessages.every((errorMessage) => {
return errorMessage == '';
});
console.log(valid); // true/false
});
},
},
};
</script>
初始化出现表单校验结果
el-form有一些表单校验会在初始化是就校验,解决方案:在form上绑定:validate-on-rule-change="false"
自定义滚动条
/*滚动条样式*/
.innerbox::-webkit-scrollbar {/*滚动条整体样式*/
width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
height: 4px;
}
.innerbox::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.innerbox::-webkit-scrollbar-track {/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
element生成dom内文本前后自动追加空格
解决方案:
- 给对应的元素内添加一个标签
- 调整它的margin为负值
元素有滚动条出现时会占位,挤压元素
overflow属性设置值为
overflow: overlay
新特性记录
element table expand列合并
td.el-table__expand-column,
th.el-table__expand-column {
width: 0 !important;
border-right: none !important;
z-index: 1;
&.is-left,
&.is-right,
&.is-center {
.cell {
padding-right: 0 !important;
}
}
}
th.el-table__expand-column + th.is-left {
overflow: visible !important;
.cell {
padding-left: 0 !important;
transform: translate(-10px);
z-index: 2;
}
}
element 下拉选值不回显问题
比如有一个所在地需要选择省市区,当省市选完后,选择区的时候,会发现值已经改变,但是区的下拉框没回显选中的数据,在打印中查看是修改成功了,但在页面中没有及时刷新改变后的值,也就是下拉框值无法选中。
解决方法:
出现这个问题好像是因为下拉框数据是循环掉别的接口得来的,因为数据层次太多,render函数没有自动更新,需手动强制刷新所以我直接强制刷新了值,而forceUpdate就是重新render。
写一个方法,在select的change事件中调用此方法,运用 this.$forceUpdate()强制刷新,页面正常选值。
change(){
this.$forceUpdate()
}
函数导入错误导致的报错
通过弹窗取消按钮关闭弹窗可以清空表单,通过❎关闭表单不会清空
清空表单的时机放在关闭之前,非关闭之后
v-infinite-scroll 自动调用分页接口请求
问题出现在transition-group,将他替换成div
<el-scrollbar ref="scrollbar" class="h-full overflow-x-hidden">
<transition-group
v-if="allList && allList.length > 0"
v-infinite-scroll="getMessageList"
:infinite-scroll-immediate="false"
:infinite-scroll-disabled="loading || loadingMore"
:infinite-scroll-distance="50"
name="messagelist"
class="h-full"
tag="ul"
>
<li
v-for="(item, key) in allList"
:key="item.messageId"
:class="{ 'message-item': true, isRead: item.isRead, active: key === activeItem }"
@click="getDetail(key)"
>
<div class="message-item-inner">
<div class="message-close" @click.stop="deleteMsg(key)">
<i class="el-icon-close" />
</div>
<div class="flex">
<div>
<div class="message-title">{{ item.title }}</div>
<div class="leading-[12px]">
<span class="message-desc">{{ parseTime(item.sendTime) }}</span>
</div>
</div>
</div>
</div>
</li>
<li v-if="loadingMore" key="loading" class="message-item text-center">
<div class="message-item-inner">
<BosLoading></BosLoading>
</div>
</li>
<li
v-if="!loadingMore && totalCount !== -1 && allPage > Math.ceil(totalCount / allLimit)"
key="loading"
class="message-item text-center text-[#86909C] text-[12px]"
>
<div class="message-item-inner">{{ $t('COMMON_NO_MORE_DATA') }}</div>
</li>
</transition-group>
<div v-else class="no-message">
{{ $t('COMMON_NO_MESSAGE') }}
</div>
</el-scrollbar>