【学习周报 01】-2022/09/11
本周报预计每周日更新,用于总结个人本周的一些公开项目进展和遇到的问题,还会对接触的各种零散的新知识进行简短的概括总结。
项目总结
桌游小工具
完成并上传初版,上传初版后几天进行各种 bug 的修修补补。
桌游辅助工具的小程序开发算是我这段时间的主要内容,从九月一日正式开工,本来预计是一个星期完工,但没想到各种小坑不断,自己对功能的考虑也不完备,最后是 7 天完成 90%,又花了 4 天进行各种小修小补。
Vue2 电商网站
除了这个小程序项目,也在学习另一个电商项目,计划后续借用该项目 API 从头制作一个自己的电商项目。
前端知识总结
Vue 中的组件间通信的方法有哪些?
props
自定义事件
子组件给父组件通信
全局事件总线$bus
pubsub-js
vue 中几乎不用
插槽
vuex
使用Object.assign()
方法合并对象
Object.assign() - JavaScript | MDN
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target);
// expected output: true
主要是用来合并两个对象,如果 source 中有和 target 相同的 key,则会覆盖 target 中的值。但是要注意,这个方法不是深拷贝,即如果有某个值是对象,则只会复制对该对象的引用,当该对象改变时,新复制出来的对象也会改变。
如果需要进行深拷贝,考虑使用JSON.stringify
配合JSON.parse
进行转换,前提是数据可以进行字符串化。
合并多个对象
这个方法的source 可以是多个,即传入的第二个和之后的参数都是 source:
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };
const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed.
异常会打断拷贝
这个方法会按照顺序进行值的拷贝,但是如果中间出现错误导致拷贝过程中断,之前的值也会正常拷贝。以下例子中定义了一个foo
的只读属性,所以拷贝到 foo 时就会报错,后续的拷贝无法继续进行,但是之前的拷贝还是完成了:
const target = Object.defineProperty({}, 'foo', {
value: 1,
writable: false,
}); // target.foo is a read-only property
Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 });
// TypeError: "foo" is read-only
// The Exception is thrown when assigning target.foo
console.log(target.bar); // 2, the first source was copied successfully.
console.log(target.foo2); // 3, the first property of the second source was copied successfully.
console.log(target.foo); // 1, exception is thrown here.
console.log(target.foo3); // undefined, assign method has finished, foo3 will not be copied.
console.log(target.baz); // undefined, the third source will not be copied either.
拷贝会触发 get
如果 source 中的某个属性配置了 get,则在复制后该属性的值是 get 的返回值,而不是将该属性完整拷贝(参考网页中也给出了完整拷贝的方法):
const obj = {
foo: 1,
get bar() {
return 2;
},
};
let copy = Object.assign({}, obj);
console.log(copy); // { foo: 1, bar: 2 }
Vue 中 Typescript 的使用
项目配置
如果要在 Vue 中使用 Typescript,建议是在创建项目时使用「搭建基于 Vite 且 TypeScript 就绪的 Vue 项目」,如果是 Vue CLI 这样的基于 webpack 搭建的项目,则会在编译时顺道执行类型检查,但是这存在检查不全面的问题,所以成功编译后仍然可能发生类型报错,所以建议如果要使用 TypeScript 则直接迁移到 Vite。
用法
- 使用
defineComponent
这个全局 API 来定义组件; - script 标签写法:
<script lang="ts">
;
其他经验
修改选项为 active
单选修改属性时,先使用arr.forEach()
遍历数组全部修改为未激活状态,然后再单独修改点击的那个为 active;
changeActive(selected, list){
list.forEach(item=>item.active = 0
}
selected.active = 1
需要发出请求后获取的数据使用注意事项
当使用这类数据时,刚开始的时候还没有请求回来数据,所以使用返回的数据||{}
返回一个空对象或数组,以防产生 TypeError 错误。
usedData(){
return data||{}
}
使用 nextTick()防止调用方法时 DOM 不完整
netxTick()方法会在下一次 DOM 渲染后才执行,可以用来生成 swiper,这时生成的 swiper 可以保证是使用了完整的 DOM 的
Vue2 样式 scoped 失效 bug
当子组件最外层标签的上有和父组件一样的class
时,会导致父组件的样式应用到子组件中。
// 父组件
<template>
<div class="home">
父组件
<child></child>
</div>
</template>
// 子组件
<template>
<div class="home"> // 这里父组件会覆盖子组件的style
子组件
</div>
</template>
解决方法就是在子组件最外层再包一个标签,或者把子组件中的选择器从.home
改为.home.home
以增加权重。
其他
开启特定用户的 chrome 的 cmd 命令
先将 chrome 切换至需要快速启动的用户,然后在地址栏输入chrome://version/
,页面中的Executable Path
部分为 chrome 地址,Profile Path
部分为当前用户配置文件所在路径。
然后新建一个 txt 文本文档,修改其后缀为cmd
,然后使用文本编辑器打开,粘贴以下内容,将其中的「chrome 所在地址」和「用户配置文件夹名称」替换为你的:
"chrome所在地址" --profile-directory="用户配置文件夹名称"
// 填写截图中信息后↓
"C:\Program Files\Google\Chrome\Application\chrome.exe" --profile-directory="Default"
保存后双击运行cmd
文件,即可发现会打开配置用户的 chrome 窗口。