Skip to content

Commit

Permalink
Update: vue.md
Browse files Browse the repository at this point in the history
  • Loading branch information
qiilee committed Aug 6, 2024
1 parent ac403c0 commit da2ee2e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-->

🚀 欢迎`Star`与分享,后续会不断更新。[gitee版本阅读更流畅,点击阅读](https://gitee.com/qiilee/web-interview)
🇨🇳 最后更新日期:2️⃣0️⃣2️⃣4️⃣`/`0️⃣1️⃣`/`0️⃣9️⃣
🇨🇳 最后更新日期:2️⃣0️⃣2️⃣4️⃣`/`0️⃣8️⃣`/`0️⃣6️⃣


## 目录
Expand Down
33 changes: 32 additions & 1 deletion content/Git.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,37 @@ wip 开发中

</details>

<b><details><summary>34. </summary></b>
<b><details><summary>34. npm和pnpm有什么区别</summary></b>

```
npm和pnpm都是JavaScript的包管理工具,用于自动化安装、配置、更新和卸载npm包依赖。然而,它们在设计和功能上有一些关键的区别:
存储方式:
npm为每个项目安装独立的包版本,即使多个项目使用相同的包版本,也会在每个项目的node_modules目录下存储一个副本。
pnpm使用一个内容寻址的文件存储方式,如果多个项目使用相同的包版本,pnpm会存储单个副本,并在每个项目中创建硬链接。这节省了大量的磁盘空间并提高了安装速度。
性能:
pnpm在性能方面通常优于npm,因为它使用硬链接和符号链接来避免重复包的冗余副本,从而加快了安装速度。
安全性:
pnpm在安装包时采用了严格的依赖解析策略。默认情况下,它不会扁平化依赖,这意味着子依赖不会被提升到项目的顶层node_modules目录,这减少了意外覆盖依赖的风险。
依赖关系:
npm的依赖扁平化可以导致许多顶层node_modules目录中的包,这在一些情况下可能会导致版本冲突或意外的行为。
pnpm通过创建非扁平化的node_modules结构,避免了由于包之间的版本冲突所导致的问题。
命令行界面:
npm和pnpm的命令行界面(CLI)非常相似,大多数命令都是一致的,如install, run, test等,但可能在某些高级功能和命令上有所不同。
兼容性:
npm作为最早和最广泛使用的包管理器,几乎被所有的Node.js项目支持。
pnpm虽然在许多项目中能够无缝工作,但在某些依赖于特定node_modules结构的工具或项目中可能会遇到兼容性问题。
总体来说,pnpm在空间和性能方面提供了显著的优势,但在某些项目中可能需要额外的配置来保证与传统npm相同的行为。选择哪一个主要取决于个人或团队的需求和项目的特定要求。
```

</details>

<b><details><summary>35. </summary></b>

</details>
94 changes: 90 additions & 4 deletions content/vue/vue.md
Original file line number Diff line number Diff line change
Expand Up @@ -2286,10 +2286,9 @@ devDependencies:开发环境依赖包的名称和版本号,即这些 依赖

参考答案:

1) 父组件向子组件通信
2) 子组件向父组件通信
3) 隔代组件间通信
4) 兄弟组件间通信
1) 父子组件通信 props / $emit / $parent / ref / $attrs
2) 隔代组件间通信 eventbus / vuex / provide + inject
3) 兄弟组件间通信 $parent / $root / eventbus / vuex

</details>

Expand Down Expand Up @@ -4341,4 +4340,91 @@ Vuex使用vue中的reactive方法将state设置为响应式,这样组件就可
视图。


</details>

<b><details><summary>212. Vue 中如何扩展⼀个组件 </summary></b>

答题思路:

1. 按照逻辑扩展和内容扩展来列举, 逻辑扩展有: mixins 、 extends 、 composition api ; 内容扩展有 slots ;
2. 分别说出他们使⽤⽅法、场景差异和问题。
3. 作为扩展, 还可以说说 vue3 中新引⼊的 composition api 带来的变化

回答范例:

1. 常⻅的组件扩展⽅法有: mixins , slots , extends 等
2. 混⼊ mixins 是分发 Vue 组件中可复⽤功能的⾮常灵活的⽅式。混⼊对象可以包含任意组件选项。 当组件使⽤ 混⼊对象时, 所有混⼊对象的选项将被混⼊该组件本身的选项。
```js
// 复⽤代码: 它是⼀个配置对象, 选项和组件⾥⾯⼀样
const mymixin = { methods: { dosomething( ) { } } }
// 全局混⼊: 将混⼊对象传⼊
Vue.mixin(mymixin)
// 局部混⼊: 做数组项设置到 mixins 选项, 仅作⽤于当前组件
const Comp = { mixins: [mymixin] }
```
3. 插槽主要⽤于 vue 组件中的内容分发, 也可以⽤于组件扩展。
4. 组件选项中还有⼀个不太常⽤的选项 extends , 也可以起到扩展组件的⽬的
```js
// 扩展对象
const myextends = { methods: { dosomething( ) { } } }
// 组件扩展: 做数组项设置到 extends 选项, 仅作⽤于当前组件
// 跟混⼊的不同是它只能扩展单个对象
// 另外如果和混⼊发⽣冲突, 该选项优先级较⾼, 优先起作⽤
const Comp = { extends: myextends }
```

5. 混⼊的数据和⽅法 不能明确判断来源 且可能和当前组件内变量 产⽣命名冲突 , vue3 中引⼊的 composition api , 可以很好解决这些问题, 利⽤独⽴出来的响应式模块可以很⽅便的编写独⽴逻辑并提供响应式的数据, 然后在 setup 选项中组合使⽤, 增强代码的可读性和维护性。 例如:
```js
// 复⽤逻辑 1
function useXX( ) {}
// 复⽤逻辑 2
function useYY( ) {}
// 逻辑组合
const Comp = { setup( ) { const {xx} = useXX( ) const {yy} = useYY( ) return {xx, yy} } }
```
</details>

<b><details><summary>213. ⼦组件可以直接改变⽗组件的数据么, 说明原因 </summary></b>

思路 1 . 讲讲单项数据流原则, 表明为何不能这么做 2. 举⼏个常⻅场景的例⼦说说解决⽅案 3. 结合实践讲讲如果需要修改⽗组件状态应该如何做

回答范例 1. 所有的 prop 都使得其⽗⼦之间形成了⼀个 单向下⾏绑定 : ⽗级 prop 的更新会向下流动到⼦组件中, 但是反 过来则不⾏。 这样会防⽌从⼦组件意外变更⽗级组件的状态, 从⽽导致你的应⽤的数据流向难以理解。另外, 每次⽗级组件发⽣变更时, ⼦组件中所有的 prop 都将会刷新为最新的值。这意味着你 不 应该在⼀个⼦组件内 部改变 prop 。 如果你这样做了, Vue 会在浏览器控制台中发出警告。

2.实践中如果确实想要改变⽗组件属性应该 emit ⼀个事件让⽗组件去做这个变更。注意虽然我们不能直接修改 ⼀个传⼊的对象或者数组类型的 prop , 但是我们还是能够直接改内嵌的对象或属性。

</details>

<b><details><summary>214. Vue 要做权限管理该怎么做?控制到按钮级别的权限怎么做? </summary></b>

思路 1 . 权限管理需求分析: ⻚⾯和按钮权限 2. 权限管理的实现⽅案: 分后端⽅案和前端⽅案阐述 3. 说说各⾃的优缺点

回答范例

1. 权限管理⼀般需求是 ⻚⾯权限 和 按钮权限 的管理
2. 具体实现的时候分后端和前端两种⽅案:

前端⽅案会把所有路由信息在前端配置,通过路由守卫要求⽤户登录, ⽤户登录后根据⻆⾊过滤出路由表。⽐ 如我会配置⼀个 asyncRoutes 数组, 需要认证的⻚⾯在其路由的 meta 中添加⼀个 roles 字段, 等获取⽤户⻆⾊之后取两者的交集, 若结果不为空则说明可以访问。此过滤过程结束, 剩下的路由就是该⽤户能访问的⻚⾯, 最后通过 router.addRoutes(accessRoutes) ⽅式动态添加路由 即可。

后端⽅案会 把所有⻚⾯路由信息存在数据库 中, ⽤户登录的时候根据其⻆⾊ 查询得到其能访问的所有⻚⾯路由 信息 返回给前端, 前端 再通过 addRoutes 动态添加路由 信息 按钮权限的控制通常会 实现⼀个指令 , 例如 v-permission , 将按钮要求⻆⾊通过值传给 v-permission 指 令 , 在指令的 moutned 钩⼦中可以 判断当前⽤户⻆⾊和按钮是否存在交集 , 有则保留按钮, ⽆则移除按钮。

3. 纯前端⽅案的优点是实现简单, 不需要额外权限管理⻚⾯, 但是维护起来问题⽐较⼤, 有新的⻚⾯和⻆⾊需求 就要修改前端代码重新打包部署; 服务端⽅案就不存在这个问题, 通过专⻔的⻆⾊和权限管理⻚⾯, 配置⻚⾯ 和按钮权限信息到数据库, 应⽤每次登陆时获取的都是最新的路由信息, 可谓⼀劳永逸!

</details>

<b><details><summary>215. 如果让你从零开始写⼀个 vue 路由, 说说你的思路 </summary></b>

回答范例: ⼀个 SPA 应⽤的路由需要解决的问题是 ⻚⾯跳转内容改变同时不刷新 , 同时路由还需要以插件形式存在, 所以:
1. ⾸先我会定义⼀个 createRouter 函数, 返回路由器实例, 实例内部做⼏件事: 保存⽤户传⼊的配置项 监听 hash 或者 popstate 事件 回调⾥根据 path 匹配对应路由
2. 将 router 定义成⼀个 Vue 插件, 即实现 install ⽅法, 内部做两件事: 实现两个全局组件: router-link 和 router-view , 分别实现⻚⾯跳转和内容显示 定义两个全局变量: $route 和 $router , 组件内可以访问当前路由和路由器实例

</details>

<b><details><summary>215. 说说从 template 到 render 处理过程 </summary></b>

回答范例

1. Vue 中有个独特的编译器模块, 称为 “compiler” , 它的主要作⽤是将⽤户编写的 template 编译为 js 中可执⾏的 render 函数。
2. 之所以需要这个编译过程是为了便于前端程序员能⾼效的编写视图模板。相⽐⽽⾔, 我们还是更愿意⽤ HTML 来编写视图, 直观且⾼效。 ⼿写 render 函数不仅效率底下, ⽽且失去了编译期的优化能⼒。
3. 在 Vue 中编译器会先对 template 进⾏解析, 这⼀步称为 parse ,结束之后会得到⼀个 JS 对象, 我们成为抽象语 法树 AST , 然后是对 AST 进⾏深加⼯的转换过程, 这⼀步成为 transform , 最后将前⾯得到的 AST ⽣成为 JS 代 码, 也就是 render 函数

</details>

0 comments on commit da2ee2e

Please sign in to comment.