Skip to content

【学习周报 01】-2022/09/11

本周报预计每周日更新,用于总结个人本周的一些公开项目进展和遇到的问题,还会对接触的各种零散的新知识进行简短的概括总结。

项目总结

桌游小工具

完成并上传初版,上传初版后几天进行各种 bug 的修修补补。

桌游辅助工具的小程序开发算是我这段时间的主要内容,从九月一日正式开工,本来预计是一个星期完工,但没想到各种小坑不断,自己对功能的考虑也不完备,最后是 7 天完成 90%,又花了 4 天进行各种小修小补。

Vue2 电商网站

除了这个小程序项目,也在学习另一个电商项目,计划后续借用该项目 API 从头制作一个自己的电商项目。

前端知识总结

Vue 中的组件间通信的方法有哪些?

  • props

  • 自定义事件

    子组件给父组件通信

  • 全局事件总线$bus

  • pubsub-js

    vue 中几乎不用

  • 插槽

  • vuex

使用Object.assign()方法合并对象

Object.assign() - JavaScript | MDN

jsx
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:

jsx
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 时就会报错,后续的拷贝无法继续进行,但是之前的拷贝还是完成了:

jsx
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 的返回值,而不是将该属性完整拷贝(参考网页中也给出了完整拷贝的方法):

jsx
const obj = {
  foo: 1,
  get bar() {
    return 2;
  },
};

let copy = Object.assign({}, obj);
console.log(copy); // { foo: 1, bar: 2 }

Vue 中 Typescript 的使用

搭配 TypeScript 使用 Vue | Vue.js

项目配置

如果要在 Vue 中使用 Typescript,建议是在创建项目时使用「搭建基于  Vite   且 TypeScript 就绪的 Vue 项目」,如果是 Vue CLI 这样的基于 webpack 搭建的项目,则会在编译时顺道执行类型检查,但是这存在检查不全面的问题,所以成功编译后仍然可能发生类型报错,所以建议如果要使用 TypeScript 则直接迁移到 Vite。

用法

  • 使用defineComponent这个全局 API 来定义组件;
  • script 标签写法:<script lang="ts">

其他经验

修改选项为 active

单选修改属性时,先使用arr.forEach()遍历数组全部修改为未激活状态,然后再单独修改点击的那个为 active;

jsx
changeActive(selected, list){
	list.forEach(item=>item.active = 0
}
selected.active = 1

需要发出请求后获取的数据使用注意事项

当使用这类数据时,刚开始的时候还没有请求回来数据,所以使用返回的数据||{}返回一个空对象或数组,以防产生 TypeError 错误。

jsx
usedData(){
	 return data||{}
}

使用 nextTick()防止调用方法时 DOM 不完整

netxTick()方法会在下一次 DOM 渲染后才执行,可以用来生成 swiper,这时生成的 swiper 可以保证是使用了完整的 DOM 的

Vue2 样式 scoped 失效 bug

当子组件最外层标签的上有和父组件一样的class时,会导致父组件的样式应用到子组件中。

jsx
// 父组件
<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部分为当前用户配置文件所在路径。

Untitled

然后新建一个 txt 文本文档,修改其后缀为cmd,然后使用文本编辑器打开,粘贴以下内容,将其中的「chrome 所在地址」和「用户配置文件夹名称」替换为你的:

"chrome所在地址" --profile-directory="用户配置文件夹名称"
// 填写截图中信息后↓
"C:\Program Files\Google\Chrome\Application\chrome.exe" --profile-directory="Default"

保存后双击运行cmd文件,即可发现会打开配置用户的 chrome 窗口。