BEM 命名法
# 摘要
当你在编写 css 代码的时候,是否遇到这样的困扰:不知道取什么 class 名?修改某个组件的样式,担心影响了其他组件?编写的组件样式如何复用?为了解决这些问题,聪明的程序猿发明了 BEM 命名法。
BEM 命名法,是对 css 命名的一种规范,将页面模块化,隔离样式,提高代码的复用性,减少后期的维护成本。BEM 的意思就是 Block (块)、Element (元素)、modifier (修饰符),通过双下划线
__
或者双中划–
链接。BEM 通常用于框架开发中,比如微信 WEUI、饿了么 element-ui、有赞 vant 等。笔者也是通过阅读这些优秀框架的源码,学习到了这一套 css 命名大法,从此走上人生巅峰,赢取白富美。
实现Vuex的min简单版本
# vuex 的基本使用
//index.js | |
import { createStore } from './gvuex.js' | |
const store = createStore({ | |
// 定义 store 的状态 | |
state() { | |
return { | |
count: 1 | |
} | |
}, | |
// 定义获取 state 状态数据的计算属性 getters,以下的值都被认为是 state 的派生值 | |
getters: { | |
double(state) { | |
return state.count * 2 | |
} | |
}, | |
// 定义修改 state 状态数据的方法 mutations | |
mutations: { | |
add(state) { | |
state.count++ | |
} | |
}, | |
// 定义异步操作的方法 actions | |
actions: { | |
asyncAdd({ commit }) { | |
setTimeout(() => { | |
commit('add') | |
}, 1000) | |
} | |
} | |
}) |
App.vue
<script setup> | |
import { useStore } from '../store/gvuex' | |
import { computed } from 'vue' | |
let store = useStore(); | |
let count = computed(()=>{ store.state.count }) | |
let double = computed(()=>{ store.getters.double }) | |
function add() { | |
store.commit('add') | |
} | |
function asyncAdd() { | |
store.dispatch('asyncAdd') | |
} | |
</script> | |
<template> | |
<div class=""> | |
* 2 = | |
<button @click="add">add</button> | |
<button @click="asyncAdd">async add</button> | |
</div> | |
</template> | |
<style scoped> | |
</style> |
知道了 vuex 的用法,你会不会发出以下疑问:
- 为什么要
store.commit('add')
才能触发事件执行呢?可不可以进行直接调用mutation
函数进行操作呢? - 为什么不可以直接对
state
存储的状态进行修改,只能通过调用mutation
函数的方式修改呢? - 为什么存在异步调用的函数需要
store.dispatch('asyncAdd')
函数才能完成呢?可以直接调用store.commit('asyncAdd')
嘛?如果不可以,为什么呢? createStore()
和useStore()
到底发生了什么?
那么下面就来一一解密吧。
前端10 个 Web API
JavaScript 中有些 API 可能使用率比较低,下面我们逐一介绍它们的用法和使用场景。
# Blob API
Blob API
用于处理二进制数据,可以方便地将数据转换为 Blob 对象或从 Blob 对象读取数据。
// 创建一个 Blob 对象 | |
const myBlob = new Blob(["Hello, world!"], { type: "text/plain" }); | |
// 读取 Blob 对象的数据 | |
const reader = new FileReader(); | |
reader.addEventListener("loadend", () => { | |
console.log(reader.result); | |
}); | |
reader.readAsText(myBlob); |
使用场景:在 Web 应用中,可能需要上传或下载二进制文件,使用 Blob API
可以方便地处理这些数据。
前端需要掌握的设计模式
提到设计模式,相信知道的同学都会脱口而出,五大基本原则(SOLID)和 23 种设计模式。SOLID 所指的五大基本原则分别是:单一功能原则、开放封闭原则、里式替换原则、接口隔离原则和依赖反转原则。逐字逐句诠释这五大基本原则违背了写这篇文章的初衷,引用社区大佬的理解,SOLID 可以简单概括为六个字,即 “高内聚,低耦合”:
- 高层模块不依赖底层模块,即为依赖反转原则。
- 内部修改关闭,外部扩展开放,即为开放封闭原则。
- 聚合单一功能,即为单一功能原则。
- 低知识要求,对外接口简单,即为迪米特法则。
- 耦合多个接口,不如独立拆分,即为接口隔离原则。
- 合成复用,子类继承可替换父类,即为里式替换原则。
常见的Vue2项目性能优化
# 前言
众所周知,Vue 项目采用了数据双向绑定和虚拟 DOM 基础,在数据驱动代替 DOM 频繁渲染已经算是非常高效了,对开发者而言已经非常优化了,那为什么还会有 Vue 性能优化这一说呢?
因为目前 Vue 2.x 使用了 webpack 等第三方打包构建工具,并且支持其他第三方的插件,我们在项目中使用这些工具时可能不同的操作在运行或打包效率上会有不同的效果,下面就来详细说明优化的方向。
如何优雅地使用Vue 弹窗
# Dialog 地狱
为啥是地狱?
因为凡是有 Dialog
出现的页面,其代码绝对优雅不起来!因为一旦你在也个组件中引入 Dialog
,就最少需要额外维护一个 visible
变量。如果只是额外维护一个变量这也不是不能接受,可是当同样的 Dialog
组件,即需要在父组件控制它的展示与隐藏,又需要在子组件中控制。
再谈前端状态管理
5 分钟搞懂 Monorepo
由于谷歌在 Monorepo 上的实践,Monorepo 受到了越来越多的关注。Monorepo 意味着把所有项目的所有代码统一维护在一个单一的代码版本库中,和多代码库方案相比,两者各有优劣,需要根据公司文化和产品特性进行取舍。原文:What is monorepo? (and should you use it?)[1]
Monorepos(单一代码库)有助于加快开发工作流程,在本文中,我们将帮助你认识这一代码组织模型是否适合你的团队和公司。