背景
使用 vue3 + 若依框架,点击切换左侧菜单,页面偶尔白屏,并且不报错。刷新页面后可以正常显示。继续点击,还是偶尔会出现相同的问题。
网上查找资料,发现出现这种问题,有可能是页面组件嵌套,重复使用 transition 引起的。在 components 文件夹下的 layout 文件夹中,AppMain 中使用了 transition,而 keep-alive 包裹的组件中又使用了 transition,导致页面出现白屏。
...大约 1 分钟
背景
使用 vue3 + 若依框架,点击切换左侧菜单,页面偶尔白屏,并且不报错。刷新页面后可以正常显示。继续点击,还是偶尔会出现相同的问题。
网上查找资料,发现出现这种问题,有可能是页面组件嵌套,重复使用 transition 引起的。在 components 文件夹下的 layout 文件夹中,AppMain 中使用了 transition,而 keep-alive 包裹的组件中又使用了 transition,导致页面出现白屏。
背景
使用 vue3 + Echarts,在进行页面监听,重新渲染 Echarts 的时候,出现 Cannot read properties of undefined (reading 'type') 错误。
由于之前 vue2 中会在 data 中定义 Echarts 实例,并且通过 this.echarts.xxx() 来调用 API 并未出现异常,所以在 Vue3 惯性使用 ref 定义实例。但是 Vue3 使用了 proxy,Echarts 无法从中获取内部变量
背景
项目中要搞一个季度选择器,但是 element-plus 没有,所以网上搜索了一个大神写的,记录一下,方便以后使用。
<template>
<div class="el-quarter-wrap">
<el-popover title="" content="" width="320" v-model="visible">
<template #reference>
<el-input
v-model="quarterDate"
placeholder="请选择季度"
clearable
:prefix-icon="Calendar"
readonly
@click.stop.native="visible = true"
@change="quarterDateChange">
<template #suffix>
<el-icon
v-if="quarterDate"
class="el-quarter-clear"
@click="clearData">
<Close />
</el-icon>
</template>
</el-input>
</template>
<div class="el-quarter__header">
<span
class="el-quarter-btn el-quarter-btn__pre"
@click="changeShowYear(-1)">
<el-icon>
<DArrowLeft />
</el-icon>
</span>
<div class="el-quarter__header-text" @click="showYearList">
{{ quarterTitle }}
</div>
<span
class="el-quarter-btn el-quarter-btn__next"
@click="changeShowYear(1)">
<el-icon>
<DArrowRight />
</el-icon>
</span>
</div>
<div class="el-quarter__content" v-if="!isEditYear">
<div class="el-quarter__row">
<span
class="quarter-index"
:class="{
'is-active': showYear === pickerYear && quarterIndex === 1,
}"
@click="pickerQuarte(1)"
>第一季度</span
>
<span
class="quarter-index"
:class="{
'is-active': showYear === pickerYear && quarterIndex === 2,
}"
@click="pickerQuarte(2)"
>第二季度</span
>
</div>
<div class="el-quarter__row">
<span
class="quarter-index"
:class="{
'is-active': showYear === pickerYear && quarterIndex === 3,
}"
@click="pickerQuarte(3)"
>第三季度</span
>
<span
class="quarter-index"
:class="{
'is-active': showYear === pickerYear && quarterIndex === 4,
}"
@click="pickerQuarte(4)"
>第四季度</span
>
</div>
</div>
<div class="el-year__content" v-else>
<div class="el-year-item" v-for="item in yearList">
<div
class="cell"
:class="{ 'is-active': showYear == item }"
@click="selectYear(item)">
{{ item }}
</div>
</div>
</div>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import {
DArrowLeft,
DArrowRight,
Close,
Calendar,
} from '@element-plus/icons-vue';
import { computed, onMounted, reactive, ref } from 'vue';
let visible = ref(false);
const props = defineProps({
modelValue: {
type: String,
default: '',
},
});
const emits = defineEmits(['update:modelValue', 'change']);
// 绑定日期
let quarterDate = ref('');
// 选择的年
let pickerYear = ref('') as any;
// 展示的年
let showYear = ref('') as any;
// 选择的季度
let quarterIndex = ref(0);
// 是否展示年份列表
let isEditYear = ref(false);
// 年份列表开始年份
let startYear = ref('') as any;
// 年份列表
let yearList = reactive([] as any);
const quarterTitle = computed(() => {
if (isEditYear.value) {
return startYear.value + '年 - ' + (startYear.value + 9) + '年';
} else {
return showYear.value + '年';
}
});
// 选择某季度
function pickerQuarte(index: number) {
quarterIndex.value = index;
pickerYear.value = showYear.value;
let oldValue = quarterDate.value; // 记录上一次数据
quarterDate.value = pickerYear.value + '-Q' + index;
emits('update:modelValue', quarterDate.value);
// 新老数据不一致,触发change时间
if (oldValue !== quarterDate.value) {
emits('change', quarterDate.value);
}
}
// 更改展示的年
function changeShowYear(num: number) {
if (isEditYear.value) {
startYear.value = startYear.value + num * 10;
// console.log('startYear.value', startYear.value)
changeYearList();
} else {
showYear.value = showYear.value + num;
}
}
// 清空选择的数据
function clearData() {
quarterDate.value = '';
pickerYear.value = '';
showYear.value = new Date().getFullYear();
quarterIndex.value = 0;
}
// 选择的数据
function quarterDateChange(value: any) {
const splitArray = value.split('-Q');
if (splitArray.length < 2) {
pickerYear.value = '';
showYear.value = new Date().getFullYear();
quarterIndex.value = 0;
} else {
pickerYear.value = splitArray[0];
showYear.value = splitArray[0];
quarterIndex.value = splitArray[1];
}
}
// 更改年份列表函数
function changeYearList() {
yearList = [];
let year = startYear.value;
for (let i = 0; i < 10; i++) {
yearList.push(year++);
}
}
// 切换展示年份列表 和 季度
function showYearList() {
if (!isEditYear.value) {
startYear.value = Number(Math.floor(showYear.value / 10) + '0');
changeYearList();
isEditYear.value = true;
} else {
isEditYear.value = false;
}
}
// 选中某个年份列表
function selectYear(item: any) {
showYear.value = item;
isEditYear.value = false;
}
onMounted(() => {
// 初始化展示的年为当前年份
showYear.value = new Date().getFullYear();
startYear.value = Number(Math.floor(showYear.value / 10) + '0');
changeYearList();
});
</script>
<style lang="scss">
.el-quarter__header {
padding-bottom: 12px;
border-bottom: 1px solid #ebeef5;
display: flex;
align-items: center;
justify-content: space-between;
.el-quarter-btn {
font-size: 12px;
}
.el-quarter__header-text {
font-size: 16px;
font-weight: 500;
text-align: center;
cursor: pointer;
}
}
.el-quarter__content {
min-height: 100px;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-around;
.el-quarter__row {
display: flex;
justify-content: space-around;
.quarter-index {
display: flex;
padding: 4px 10px;
width: fit-content;
cursor: pointer;
&:hover {
color: #337ecc;
}
}
.is-active {
color: #409eff;
}
}
}
.el-quarter-clear {
position: relative;
color: #909399;
display: none;
height: 12px;
width: 12px;
cursor: pointer;
&::after {
content: '';
position: absolute;
height: 14px;
width: 14px;
margin: auto;
border-radius: 50%;
border: 1px solid #909399;
}
}
.el-input {
&:hover {
.el-quarter-clear {
display: flex;
}
}
}
.el-year__content {
min-height: 100px;
display: flex;
padding: 10px 0;
flex-wrap: wrap;
.el-year-item {
width: calc(100% / 4);
display: flex;
align-items: center;
justify-content: center;
.cell {
padding: 4px 10px;
width: fit-content;
cursor: pointer;
cursor: pointer;
white-space: nowrap;
&:hover {
color: #337ecc;
}
}
.is-active {
color: #409eff;
}
}
}
</style>
背景
启动一个 Vue3 项目,报了上边的错误。网上查找后,发现有可能是端口没权限,手动在 package.json 中修改了端口,但是还是报错。最终使用下边方法解决:
netstat -ano| findstr 9527