.env.development 开发环境,使用 development 模式。 .env.staging 测试环境,因为要部署到测试服务器,或本地使用 serve 命令预览,所以使用 production 模式。 .env.production 生产环境,因为要部署到测试服务器,或本地使用 serve 命令预览,所以使用 production 模式。 package.json 内 script 需要增加 staging 命令 “script”: { “build”: “vue-tsc --noEmit && vite build”, “staging”: “vue-tsc --noEmit && vite build --mode staging”, “serve”: “vite preview --host” } 复制代码 4.2 常用的环境变量 推荐使用以下常见的三个变量: VITE_APP_BASE_URL 接口请求地址。 通常后端会区分三种环境,部署在不同的地址下。 VITE_APP_STATIC_URL 静态资源地址。 静态资源我是不建议你直接放在项目中,这会导致项目仓库变得巨大。 本地开发和测试环境我会选在使用本地搭建的静态资源服务器,你可以找后端运维的同学帮你搭建,或者你使用 http-server 在本地启动一个服务器也可以。生产环境建议上传至 OSS。 VITE_PUBLIC_PATH 构建资源公共路径。 这个与 vue/cli 中的 publicPath 同理,有的时候你构建的项目并不是存放在跟路径下,例如 http://ip:port/{项目名}。 4.3 封装静态资源文件 如果你配置了 VITE_APP_STATIC_URL 静态资源环境变量,那么你需要封装以下两个东西: 根据环境返回实际的资源地址函数。 方便使用的静态资源组件。 baseStaticUrl.ts // 处理静态资源链接 export default function baseStaticUrl(src = ‘’) { const { VITE_APP_STATIC_URL } = import.meta.env; if (src) { return ${VITE_APP_STATIC_URL}${src}; } return VITE_APP_STATIC_URL as string; } 复制代码 静态资源组件 静态资源主要有图片、音频和视频三种常见的形式。 通过 src 写入相对的路径,使用上述的函数来补全完整的路径,即可在不同的环境下使用不同地址的静态资源。 通过 type 传入图片、音频和视频的类型。 autoplay 是解决以视频为背景的情况下,视频无法自动播放的问题。 复制代码 4.4 封装 SVG 的图标组件 svg 图标比较小,而且都是可读的 xml 文本,所以我们把它直接放在项目中即可,通过 vite-plugin-svg-icons 插件,实现自动引入 svg 图标。 配置 vite.config.ts: plugins: [ viteSvgIcons({ iconDirs: [resolve(process.cwd(), ‘src/assets/icons’)], symbolId: ‘icon-[dir]-[name]’, }), ] 复制代码 封装一个 vue 组件: 复制代码 首先将下载的 .svg 图标放入 @/assets/icons 文件夹下 复制代码 name 放置在 @/assets/icons 文件夹下的文件名。 color 颜色填充,使用此项会默认覆盖图标颜色。 5.按需自动引入组件 unplugin-vue-components[77] 是一款非常强大的插件(极力推荐),核心功能就是帮助你自动按需引入组件,Tree-shakable,只注册你使用的组件。这里说一下他的两个核心使用方式和配置方式。 此插件不仅支持 vue3,同时也支持 vue2,并且支持 Vite、Webpack、Vue CLI、Rollup。 5.1 安装与配置 安装: npm i unplugin-vue-components -D 复制代码 配置: // vite.config.ts import Components from ‘unplugin-vue-components/vite’ export default defineConfig({ plugins: [ Components({ /* options */ }), ], }) 复制代码 这里的 options 可以配置一些选项,后面提到的组件库注册会使用到。 5.2 改变全局组件注册方式 我们通常将全局的组件封装在 @/src/components 中,然后通过 app.component() 注册全局组件。使用此插件后,无需手写注册,直接在模板中使用组件即可: 这里引入官方的示例: 复制代码 自动编译为: 复制代码 5.3 自动引入组件库 在使用组件库时,常规组件我们也会注册到全局,如果使用局部注册由于页面中会使用到多个组件,会非常麻烦,所以这个功能绝佳,例如我们使用 ant-design-vue 组件库。 直接在模板中使用即可,无需手动注册或局部引用: 按钮 复制代码 当然,你还需要在 vite 中引入它的解析器: import Components from ‘unplugin-vue-components/vite’ import { AntDesignVueResolver } from ‘unplugin-vue-components/resolvers’ export default defineConfig({ plugins: [ Components({ resolvers: [ AntDesignVueResolver(), ] }) ], }) 复制代码 目前支持的解析器,根据你的喜好去选择: Ant Design Vue[78] Element Plus[79] Element UI[80] Headless UI[81] IDux[82] Naive UI[83] Prime Vue[84] Vant[85] VEUI[86] Varlet UI[87] View UI[88] Vuetify[89] VueUse Components[90] Quasar[91] 6.样式 项目中最好使用通用样式,可以创建 src/styles 目录存放,这里推荐一些分类: styles ├── antd # 组件库样式覆盖,命名自取,这里以 ant design 为例 ├── color.less # 颜色 ├── index.less # 入口 ├── global.less # 公共类 ├── transition.less # 动画相关 └── variable.less # 变量 复制代码 6.1 预设基础样式 相信用过 normalize[92] 的同学不在少数,它可以重置 css 样式,使各浏览器效果保持一致。后面的章节会提到 tailwind.css,它内置了预设样式重置的功能,与 normalize 还是有一定的区别,有兴趣的同学可以了解一下[93]。 6.2 CSS 预处理器 虽然 vite 原生支持 less/sass/scss/stylus,但是你必须手动安装他们的预处理器依赖,例如: npm install -D less 复制代码 如何选择预处理器? 推荐使用你是所使用的组件库的样式语言,因为 css 预处理器学会一种后,入手其他几乎没有学习成本。 6.3 开启 scoped 没有加 scoped 属性,会编译成全局样式,造成全局污染。 复制代码 6.4 深度选择器 有时我们可能想明确地制定一个针对子组件的规则。 如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符。有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。 7.布局 页面整体布局是一个产品最外层的框架结构,往往会包含导航、页脚、侧边栏等。在页面之中,也有很多区块的布局结构。在真实项目中,页面布局通常统领整个应用的界面,有非常重要的作用,所以单独拆分出来也是非常有必要的。 在脚手架中,所有的通用布局组件都应该放在 src/layouts 中,这种封装比较简单,这里就不贴代码了,大家按照自己实际情况自行发挥,在此仅提供一下封装思路。 7.1 常规的布局 BasicLayout 基础页面布局,包含了头部导航,侧边栏等。 BlankLayout 空白的布局。 7.2 特殊的布局 RouteLayout 如果你的项目在路由切换中需要对某些二级页面进行缓存,那么推荐你创建一个 RouteLayout,通过路由 meta 中的配置,返回 router-view 或者使用 keep-alive 包裹的 router-view。 UserLayout 用于用户登录注册等页面抽离出来。 PageLayout 基础布局,包含了面包屑等信息,内含 slot。 8.集成 Tailwind.css Tailwind.css[94] 在我第一次看到它的时候,内心是比较反感的,但实际上手之后又觉得真香。从 vue2 项目中,我已经引入了 tailwind,整体的开发结果就是,基本很少再使用 <style> 标签去转本定义一些 class 和样式,毕竟起名字这种事,一个是涉及到规范,一个是涉及到英语。如果你选择 tailwind,CSS 预处理器的作用就会显得微乎其微,因为你无需再自定定义各种变量和 mixins。 总体来说,学习成本并不高,花上两个小时足够上手,记住不用死记硬背那些类名。 8.1 效率提升 很多人总是说样式要与 HTML 分离,现在为什么又要提倡 tailwind 这种与 HTML 紧密结合的工具?这是因为现在使用 vue 这类框架已经高度组件化,样式分离是为了方便复用和维护,但在组件化面前样式分离只能是降低开发效率。 下面介绍一下 tailwind 提供了哪些提升效率的功能: 提供了大量的功能类,极大的提高了可维护性。 响应式设计,各种设备一把梭。 悬停、焦点和其它状态。 深色模式。 支持配置,例如颜色方面很难做到跟你的设计师统一。 不用为起名字而纠结??? 8.2 JIT 模式 如果你的环境支持 postcss8( vue/cli 构建的 vue2 项目是 postcss7 ),那么 JIT 模式直接带你起飞。 超快的构建速度。 支持变体,你甚至可以这么写 sm:hover:active:disabled:opacity-75。 支持任意样式,例如 md:top-[-113px]。 开发和生产环境结果是一致的,(我在 vue2 项目中就遇到过组件库构建结果不一致的问题)。 如果你使用 vscode 那你一定要安装 Tailwind CSS IntelliSense[95] 插件,它可以自动补全类名,显著降低学习成本。 8.3 关于打包体积 使用默认配置,未压缩是 3739.4kB ,Gzip压缩 是 293.9kB,Brotli压缩 是 73.2kB。这似乎看起来很大,这是因为 tailwind 提供了成千上万的功能类,其中绝大部分你不会使用到。 当构建生产时,你应该使用 purge 选项来 tree-shake 优化未使用的样式,并优化您的最终构建大小当使用 Tailwind 删除未使用的样式时,很难最终得到超过 10kb 的压缩 CSS。 还有一点,Atom CSS 极大的提升了样式的复用程度,从而直接降低了构建体积。 9.vuex 替代方案 pinia 由于 vuex 4 对 typescript 的支持让人感到难过,所以状态管理弃用了 vuex 而采取了 pinia[96]。 忘记在哪看到,尤大好像说 pinia[97] 可能会代替 vuex,所以请放心使用。 9.1 为什么采用 Pinia ? Pinia 的 API 设计非常接近 Vuex 5 的提案[98]。(作者是 Vue 核心团队成员) 无需像 Vuex 4 自定义复杂的类型来支持 typescript,天生具备完美的类型推断。 模块化设计,你引入的每一个 store 在打包时都可以自动拆分他们。 无嵌套结构,但你可以在任意的 store 之间交叉组合使用。 Pinia 与 Vue devtools 挂钩,不会影响 Vue 3 开发体验。 下面简单的介绍一下如何使用 Pinia,并对比 vuex 有哪些区别与注意事项,具体请参考官方文档[99]。 9.2 创建 Store Pinia 已经内置在脚手架中,并且与 vue 已经做好了关联,你可以在任何位置创建一个 store: import { defineStore } from ‘pinia’ export const useUserStore = defineStore({ id: ‘user’, state: () =>({}), getters: {}, actions: {} }) 复制代码 这与 Vuex 有很大不同,它是标准的 Javascript 模块导出,这种方式也让开发人员和你的 IDE 更加清楚 store 来自哪里。 Pinia 与 Vuex 的区别: id 是必要的,它将所使用 store 连接到 devtools。 创建方式:new Vuex.Store(...)(vuex3),createStore(...)(vuex4)。 对比于 vuex3 ,state 现在是一个函数返回对象。 没有 mutations,不用担心,state 的变化依然记录在 devtools 中。 9.3 State 创建好 store 之后,可以在 state 中创建一些属性了: state: () => ({ name: ‘codexu’, age: 18 }) 复制代码 将 store 中的 state 属性设置为一个函数,该函数返回一个包含不同状态值的对象,这与我们在组件中定义数据的方式非常相似。 在模板中使用 store: 现在我们想从 store 中获取到 name 的状态,我们只需要使用以下的方式即可: {{userStore.name}} const userStore = useUserStore() return { userStore } 复制代码 注意这里并不需要 userStore.state.name。 虽然上面的写法很舒适,但是你一定不要用解构的方式去提取它内部的值,这样做的话,会失去它的响应式: const { name, email } = useUserStore() 复制代码 9.4 Getters Pinia 中的 getter 与 Vuex 中的 getter 、组件中的计算属性具有相同的功能,传统的函数声明使用 this 代替了 state 的传参方法,但箭头函数还是要使用函数的第一个参数来获取 state ,因为箭头函数处理 this 的作用范围: getters: { nameLength() { return this.name.length }, nameLength: state => state.name.length, nameLength: ()=> this.name.length ❌ } 复制代码 9.5 Actions 这里与 Vuex 有极大的不同,Pinia 仅提供了一种方法来定义如何更改状态的规则,放弃 mutations 只依靠 Actions,这是一项重大的改变。 Pinia 让 Actions 更加的灵活: 可以通过组件或其他 action 调用 可以从其他 store 的 action 中调用 直接在商店实例上调用 支持同步或异步 有任意数量的参数 可以包含有关如何更改状态的逻辑(也就是 vuex 的 mutations 的作用) 可以 $patch 方法直接更改状态属性 actions: { async insertPost(data){ await doAjaxRequest(data); this.name = ‘…’; } } 复制代码 9.6 Devtools 脚手架已内置下面的代码,这将添加 devtools 支持: import { createPinia, PiniaPlugin } from ‘pinia’ Vue.use(PiniaPlugin) const pinia = createPinia() 复制代码 时间旅行功能貌似已经可以使用了,这块后续会关注。 10.基于 mitt 处理组件间事件联动 如果你曾经是 Vue2.x 的开发者,那么请阅读下面引用官方文档[100]的一段话: 我们从实例中完全移除了 $on、$off 和 $once 方法。$emit 仍然包含于现有的 API 中,因为它用于触发由父组件声明式添加的事件处理函数。 在 Vue 3 中,已经不可能使用这些 API 从组件内部监听组件自己发出的事件了,该用例暂没有迁移的方法。但是该 eventHub 模式可以被替换为实现了事件触发器接口的外部库,例如 mitt 或 tiny-emitter。 10.1 为什么选择 mitt ? 足够小,仅有 200bytes。 支持全部事件的监听和批量移除。 无依赖,不论是什么框架都可以直接使用。 10.2 严重警告 我们已经无法在项目中使用 eventBus,仅推荐你在特殊场合下使用 mitt,它并不是开发的常态,你一定要确保知道自己在做什么?否则你的项目将难以维护!!! 10.3 如何使用 mitt ? 在使用 mitt 前建议请阅读官方文档[101]: 脚手架默认提供一个可以直接使用的对象: import emitter from ‘@/libs/emitter’; 复制代码 当然你也可以引入已经安装好的 mitt: import mitt from ‘mitt’ const emitter = mitt() 复制代码 mitt 提供了非常简单的 API,下面代码是官方演示: // listen to an event emitter.on(‘foo’, e => console.log(‘foo’, e) ) // listen to all events 自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。 深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。 既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化! 由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新 如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端) 最后 由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容! 一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长! import emitter from ‘@/libs/emitter’; 复制代码 当然你也可以引入已经安装好的 mitt: import mitt from ‘mitt’ const emitter = mitt() 复制代码 mitt 提供了非常简单的 API,下面代码是官方演示: // listen to an event emitter.on(‘foo’, e => console.log(‘foo’, e) ) // listen to all events 自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。 深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。 [外链图片转存中…(img-cMjNOb6l-1712810421828)] [外链图片转存中…(img-sEWFfMdT-1712810421829)] [外链图片转存中…(img-Ygn1vrlB-1712810421829)] [外链图片转存中…(img-uR2Jn8GN-1712810421830)] [外链图片转存中…(img-4SfJ1UWA-1712810421830)] [外链图片转存中…(img-UhoOxcgD-1712810421830)] 既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化! 由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新 如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端) [外链图片转存中…(img-a8XYxSa1-1712810421830)] 最后 由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容! [外链图片转存中…(img-83an1ufv-1712810421831)] [外链图片转存中…(img-rx4AJFHY-1712810421831)] 一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长! [外链图片转存中…(img-M9wnRhG5-1712810421831)]