1.js数组解构赋值并直接赋值给 vue 中data 中的变量
const myArray = ['Hello', 'World'];
new Vue({
el: '#app',
data: {
foo: '',
bar: ''
},
created() {
[this.foo, this.bar] = myArray; //可以这样直接赋值,因为本来就相当于新建了变量!
}
});
但是如果值中有一部分想要赋值给 data的变量,有一部分想新建变量呢?
const myArray = ['Hello', 'World'];
[this.foo, bar] = myArray; //这样是不行的
const [this.foo, bar] = myArray; //这样也是不行的
只能这样:因为新建的变量是必须有类型标识符的
const myArray = ['Hello', 'World'];
const [foo, bar] = myArray;
this.foo = foo
注意:我们也可以解构赋值取数组中的一部分,会按照顺序取值!
const myArray = ['Hello', 'World'];
const [foo] = myArray;
// foo 为 'Hello'
注意:对象的解构赋值和上面的规则基本一样!
2.flex-direction: row-reverse/column-reverse
/*从右到左排列:指定Flex容器中主轴方向的反向排列*/
.container {
display: flex;
flex-direction: row-reverse;
}
/*从下到上排列:在主轴的垂直方向上从底部到顶部进行排列*/
.container {
display: flex;
flex-direction: column-reverse;
}
3.换行的两个属性
1.让文字自动换行的方法:
word-wrap: break-word; /* 或者使用 overflow-wrap: break-word; */
2.让文字无法换行的方法:
white-space:nowarp;(有时候不一定要用这个,用 min-width让宽度可变,也可以实现比较好的效果)
4.react项目热更新自动插入了iframe的解决方案
比如我根目录的文件是 index.scss, 就在文件中添加
iframe {
pointer-events: none;
}
或者是因为使用旧版本react-scripts,升级至5也可以解决这个问题
npm install --save react-scripts@5
5.大坑:父组件给子组件传递的 props 是通过 ajax获取的如何处理
父组件给子组件传递的 props 是通过 ajax获取的,并且子组件要依赖这个 props 进行页面逻辑的构建。
一般的思路肯定是在子组件的 mounted 中进行操作,但是一开始父组件的 ajax 还没有获取到值,所以传的不是我们真正想要的值,但是这个时候子组件已经 mounted 挂载完毕了,当父组件得到了 ajax的值并传递给子组件时,子组件虽然可以接收到最新的props的,但是页面逻辑的构建是在 mounted 中进行的,所以已经无法构建逻辑了!
以下是一个错误的示例:
父组件:
otherSeasonData: [],
mounted(){
if (this.currentUserId) {
await this.queryHistoryCup(); //这个方法里面用 ajax 获取了我们想传给子组件的otherSeasonData
if (this.isTrainingGrounds) {
this.getTrainingData();
} else {
this.queryMembers();
}
}
}
<slideDownSelect
@change="seasonChange"
:isSeason="true"
:title="currentSeasonLabel"
:slideData="otherSeasonData" //我们想传递的是otherSeasonData
/>
子组件:
props: {
slideData: {
type: Array,
default: [],
},
},
mounted() {
let teamInfo = JSON.parse(localStorage.getItem("teamInfo"));
let name = teamInfo.cupName.replace("松鼠杯", "");
if (this.isSeason) {
this.slideData.forEach((e, index) => { //这里用的是 props 的slideData
if (e.name == name) {
this.currentIndex = index;
}
});
}
},
这样slideData在 mounted 里面执行的时候只能接收到一个空的[]!
判断数组是不是空的的技巧:
不要相信打印值!
有时候我们打印this.slideData会给我们显示一个非空的有对象的数组(但是实际上是空的,并不会走循环),这时的数组没打开的时候看起来是空的,打开了是有对象的,但是对象上面都没有 observe 这个属性(说明不是真的有这个对象)——> 这样的数组很有迷惑性,实际上是空的,它应当代表的是一个将会通过 ajax返回的数组,而不是一个实际的有对象的数组!
最好的判断方法是判断是否进了循环,在循环里面 console.log()打印!从而判断这个数组有没有数据!
所以正确的解决方法是什么?
在子组件中,可以使用watch
选项来观察父组件传递的props数据的变化,并在变化时执行相应的操作。
在 watch 中监听slideData这个 props,这样父组件在传过来最新的值的时候,我们就可以实现我们想要构建的页面逻辑了!
props: {
slideData: {
type: Array,
default: [],
},
},
watch: {
slideData(newVal, oldVal) {
if (this.isSeason) {
newVal.forEach((e, index) => { //在 watch 这里获取的 slideData 这个 props 一定是最新的
if (e.name == this.title) { //在 watch 这里获取的 title这个 props 也一定是最新的,所以不用再使用本地存储里面的 name 了
this.currentIndex = index;
}
});
}
},
},
6.当复用一个组件要做不同的逻辑的时候
如下所示,我们在父组件里面使用了两次 slideDownSelect 这个组件:


由于只有在显示赛季的时候currentIndex才是动态的(因为当前显示的赛季是根据一些状态决定的),而显示学科的时候是静态的,所以我们在js 写逻辑的时候要根据标志变量赋予不同情况下使用的组件不同的操作!
watch: {
slideData(newVal, oldVal) {
if (this.isSeason) { //根据标志变量判断是否是显示赛季,否则不做下面的操作!
newVal.forEach((e, index) => {
console.log(index);
console.log(e);
if (e.name == this.title) {
this.currentIndex = index;
}
});
console.log(this.currentIndex);
}
},
},
只要这样处理了,我们复用组件就不会遇到问题,因为每个组件都是一个单独的实例,里面的状态是不会相互影响的,不会因为多次使用,多次传递内容就造成覆盖什么的(因为每个组件是单独的实例,有单独的 data 和 props 变量)!
7.vue构建原生单选框的策略(点击项被隐藏)
<h3>
<!--根据 isSeason 变量显示不同的标题内容-->
<template v-if="isSeason"> 其他赛季 </template>
<template v-else>
{{ title }}
</template>
</h3>
<div @click="handleClick"><arrow/></div>
<ul v-if="isShow">
<template v-for="(item, index) in slideData">
<!--当isSeason为 true 的时候就隐藏当前点击项,而 isSeason 为 false 的时候不需要隐藏!动态的组件!-->
<li
v-if="(index !== currentIndex && isSeason) || !isSeason"
@click="change(index)"
>
{{ item.name }}
</li>
</template>
</ul>
methods: {
handleClick() {
this.isShow = !this.isShow
},
change(index) {
this.currentIndex = index; //将当前点击的项的索引进行保存,从而实现当前点击项的隐藏
let item = this.slideData[index]; //获取对应的数据
this.$emit("change", { index, item }); //将当前选择的数据传递给父组件,进行相关逻辑构建
this.isShow = false;
},
},
arrow.vue
<template>
<div class="arrow" @click="handleClick">
<img v-if="isSlide" src="../../../assets/images/winterGame/arrDown.png"/>
<img v-else src="../../../assets/images/winterGame/arrUp.png"/>
</div>
</template>
<script>
export default {
name:'arrow',
data(){
return {
isSlide:true
}
},
methods:{
handleClick(){
this.isSlide = !this.isSlide
}
}
}
</script>
<style lang="less" scoped>
.arrow {
img{
width:48px;
}
}
</style>
8.js 中 switch 使用方法
JavaScript中的
switch
语句是一种用于根据不同的条件执行不同代码块的控制流语句。它可以替代多个if-else
语句,使代码更简洁易读。
根据一个变量的值做不同的操作:
这种情况下case
部分不能直接使用正则表达式
switch (expression) {
case value1:
// 当 expression 的值等于 value1 时执行的代码块
break;
case value2:
// 当 expression 的值等于 value2 时执行的代码块
break;
// 可以有更多的 case
default:
// 当 expression 的值与之前的所有 case 都不匹配时执行的代码块
break;
}
判断一个变量是否符合某个条件:
这种情况case
部分可以使用正则表达式
let str = 'Hello World';
let result;
switch (true) { //下面为 true 的就会被输出
case /^Hello/.test(str):
result = '以 Hello 开头';
break;
case /World$/.test(str):
result = '以 World 结尾';
break;
default:
result = '未匹配到条件';
break;
}
console.log(result); // 输出 "以 Hello 开头"
整合模版:
let str = 'Hello World';
let result;
//这种匹配模版是最好用的,可以使用正则表达式进行匹配,也可以直接判断等于
switch (true) { //下面为 true 的就会被输出
case str === "value1":
result = '等于 value1';
break;
case /World$/.test(str):
result = '以 World 结尾';
break;
default:
result = '未匹配到条件';
break;
}
9.整和统一的本地存储方法到 util.js 中
//获取真正准确赛季
export function judgeSeason() {
let gameTime = JSON.parse(localStorage.getItem("teamInfo")).title;
localStorage.setItem("tempFlag", gameTime); //根据 gameTime(准确的) 设置 tempFlag(临时的,用于历史赛季)
const year = gameTime.split("_")[0];
const season = gameTime.split("_")[1];
let isSpring = true;
if (gameTime != "2023_spring") {
isSpring = false;
}
return [isSpring, year, season]; //返回标志量,年份,季节
}
这种很多组件中需要用到的方法,一定要提取出来,放到公共的 util 文件中!