# 中前台通用项目
# 一、工具和包
# vite
一、介绍
webpack 进行构建时,默认只会抓取并构建整个应用,然后才能提供服务,项目构建时慢、且项目中任何错误都会影响到整个项目的构建,此外 webpack 是基于 node.js 的打包工具 (vue-cli 基于 webpack),其中可以使用 CommonJS 的语法。而 Vite 是一个基于 ES 模块的构建工具,它不再依赖于 CommonJS 规范。
**vite**
不会在一开始就构建你的整个项目,而是会将应用中的模块区分为 依赖 和 源码(项目代码) 两部分,对于 源码 部分,它会根据 路由来拆分 代码模块,只会去构建一开始就必须要构建的内容。
vite
以 原生 ESM 的方式为浏览器提供源码,让浏览器接管了 打包 的部分工作。
** 问题:** 早期版本不支持 CommonJS 的语法,导致依赖都无法使用
解决: vite
在后期提供了 依赖预构建 的功能,其中一个非常重要的目的就是为了解决 CommonJS 和 UMD 兼容性 问题。目前 vite
会先将 CommonJS 或 UMD 发布的依赖项转换为 ESM
之后,再重新进行编译。这也可以理解为 速度对业务的一个妥协。
二、使用
1、vite 中需要在 vite.config.js 中配置 @符号表示根路径
// 在 defineConfig 中进行配置: | |
// 软链接 | |
resolve: { | |
alias: { | |
'@': join(__dirname, '/src') | |
} | |
}, |
2、vite 中通过 import.meta 获取到元信息,如环境变量的获取: import.meta.env.VITE_BASE_API
,批量导入函数:
import.meta.globEager('./modules/*.js')
3、vite-plugin-svg-icons 插件中使用 createSvgIconsPlugin 进行批量注册文件夹中的 svg 图标 (在 vite.config.js 中配置 plugins)
plugins: [ | |
vue(), | |
createSvgIconsPlugin({ | |
// 指定需要缓存的图标文件夹 | |
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], | |
// 指定 symbolId 格式 | |
symbolId: 'icon-[name]' | |
}) | |
], |
4. 代理服务器 (在 vite.config.js 中的 defineConfig 中配置:)
server: { | |
proxy: { | |
// 代理所有 /api 的请求,该求情将被代理到 target 中 | |
'/api': { | |
// 代理请求之后的请求地址 | |
target: 'https://api.imooc-front.lgdsunday.club/', | |
// target: 'http://127.0.0.1:3005/', | |
// 跨域 | |
changeOrigin: true | |
} | |
} | |
} |
5、环境配置文件 .env.development
开发环境文件和 .env.production
生产环境文件 等
作用:区分不同环境下的变量,比如开发环境下需要使用任意修改的假数据,但是生产环境下需要使用真实数据
使用:只有以 VITE_
为前缀的变量,才会暴露给 vite 进行处理,使用时使用 import.meta.env.变量名
# tailwindcss
一、优势:
如果期望在整个项目中进行统一的划分,这样的一套变量通过 css 来实现,就不得不维护一个庞大的变量组,除此之外还有很多其他的问题,此时 tailwindcss 的优势就体现出来了
二、简介:
tailwindcss 提供了很多类名,每一个类名对应一个具体的 css 内容,设计理念为:原子化 css,css 设计粒度上有 4 中形式,颗粒度自上而下逐渐增大,颗粒度越大则约束行越高,可定制性越弱
css 设计粒度的四种形式:
①行内样式:样式全部写入行内,自由度最高,可定制化最强,但是不方便复用。
②原子化 css:每一个类名代表一个 css 属性,自由度很强,可定义化很高,也方便复用,但是大量样式会导致大量的类名
③传统形式:通过一些 class 来描述一段 css 属性,封装性强,语义化强,自由度和可定制化性一般
④组件形式:封装性强,语义化强,但是自由度和可定制化性较差
注意点:tailwindcss 的构建顺序为移动优先,项目中构建尽量和 tailwind 设计保持一致。
三、使用:
①直接使用类名,注意可以指定不同屏幕尺寸和不同主题下对应的样式。
②还可以自己配置特殊的样式(在 tailwind.config.js 中进行配置)
③tailwindcss 生态下有很多可以使用的插件。例如如下配置:
module.exports = { | |
// 手动切换暗模式 | |
darkMode: 'class', | |
// Tailwind 应用范围 | |
content: ['./index.html', './src/**/*.{vue,js}'], | |
theme: { | |
extend: { | |
height: { | |
header: '72px', | |
main: 'calc(100vh - 72px)' | |
}, | |
fontSize: { | |
xs: ['0.25rem', '0.35rem'], | |
sm: ['0.35rem', '0.45rem'], | |
base: ['0.42rem', '0.52rem'], | |
lg: ['0.55rem', '0.65rem'], | |
xl: ['0.65rem', '0.75rem'] | |
}, | |
boxShadow: { | |
'l-white': '-10px 0 10px white', | |
'l-zinc': '-10px 0 10px #18181b' | |
}, | |
colors: { | |
main: '#f44c58', | |
'success-100': '#F2F9EC', | |
'warn-100': '#FCF6ED', | |
}, | |
backdropBlur: { | |
'4xl': '240px' | |
}, | |
variants: { | |
scrollbar: ['dark'] | |
} | |
} | |
}, | |
// 注册下载的 tailwind-scroll-bar 工具包,使用全新的 scroll-bar | |
plugins: [require('tailwind-scrollbar')] | |
} |
④ tailwind 进行主题替换
tailwind 中有一个 dark mode 的概念,在使用 css 时,加上 dark 前缀的表示暗黑模式下的样式。需要在 tailwind.config.js 中进行配置:darkMode : ' class ',
然后监听主题的切换行为,保存到 vuex 中并进行持久化处理,然后根据 vuex 中保存的当前主题修改 html 元素中的 class 属性 。 (dark 或者 light)
⑤tailwind-scrollbar tailwind 中 scrollbar 组件
# Prettier
Prettier 是一个代码格式插件,下载插件之后,在项目根目录中配置 .prettierrc 文件即可使用。例如:
{ | |
// 代码结尾不加分号 | |
"semi": false, | |
// 优先单引号 | |
"singleQuote": true, | |
// 不添加尾随逗号 | |
"trailingComma": "none" | |
} |
# vueuse
一、 useScroll()
方法,获得 dom 元素的 响应式
位置数据
二、 useScrollLock()
方法,将 dom 元素的滚动 上锁
(无法滚动)
三 、useVModel()
方法,更方便的使用 v-model,获得的是响应式数据
四、 useElementBounding()
方法,获得响应式的元素的宽高属性
五、 useFullscreen()
方法,将 dom 元素全屏显示
六、 useIntersectionObserver()
方法,监视 dom 元素是否在视窗显示
七、 watchDebounced 防抖功能的监视属性,在监视属性的基础之上,第三个参数中配置 debounce 属性设置防抖的时长
八、useFullScreen,全屏方法
# GSAP
js 动效库,官网地址:https://gsap.framer.wiki/
# vuex-persisterdstate
自动进行 vuex 配置模块的持久化存储处理
# file-saver
小文件下载
# streamsaver
大文件下载
# driver.js
功能引导
# vee-validata
表单校验
# md5
用于密码加密
# cropperjs
图片裁剪
# dayjs
日期工具
# 二、组件
1、vite 通用组件自动化注册
① 使用 vite 中的 import.meta.glob()
方法,得到文件路径名称和导入函数的对象
import { defineAsyncComponent } from 'vue' | |
export default { | |
install(app) { | |
// 获取当前路径任意文件夹下的 index.vue 文件 | |
const components = import.meta.glob('./*/index.vue') | |
// 遍历获取到的组件模块 | |
for (const [key, value] of Object.entries(components)) { | |
// 拼接组件注册的 name | |
const componentName = 'm-' + key.replace('./', '').split('/')[0] | |
// 通过 defineAsyncComponent 异步导入指定路径下的组件 | |
app.component(componentName, defineAsyncComponent(value)) | |
} | |
} | |
} |
② 然后在 main.js 中引入实例,使用 app.use()
一下即可。
③ 此外,指令也可以进行自动化全局注册,但是由于 import.meta.glob()
方法是异步的(适合于组件注册),指令在进行导入时需要使用 import.meta.globEager()
同步导入方法。
/** | |
* 全局指令注册 | |
*/ | |
export default { | |
async install(app) { | |
// https://cn.vitejs.dev/guide/features.html#glob-import | |
//import.meta.globEager 为同步导入 | |
const directives = import.meta.globEager('./modules/*.js') | |
for (const [key, value] of Object.entries(directives)) { | |
// 拼接组件注册的 name | |
const arr = key.split('/') | |
const directiveName = arr[arr.length - 1].replace('.js', '') | |
// 完成注册 | |
app.directive(directiveName, value.default) | |
} | |
} | |
} |
2、svg-icon 组件:
动态绑定 svg 中 use 标签的 xlink:href 属性,svg 中使用图标的方式:
①直接写路径加名称:
<svg> | |
<use xlink:href="./access/image.svg"></use> | |
</svg> |
②使用 symbol 标签,配合 id 属性
<symbol id='name'></symbol> | |
<svg> | |
<use xlink:href="#name"></use> | |
</svg> |
项目中使用了工具包 vite-plugin-svg-icons
,配置后直接生成了全部的 symbol 标签,id 熟悉绑定了 name , 直接使用即可,此外需要在 main.js 中导入
import 'virtual:svg-icons-register' // 导入 svg-icons-register |
3、popup 弹层组件
4、button 按钮通用组件
在 button 组件中绑定自己定义的 icon 组件,组件中绑定传过来的 icon-name ,class 和 iconColor 等。组件需要使用时传入 type 标识按钮风格,size 标识按钮大小,icon 标识图标名称,iconColor 标识图标颜色,iconClass 表示图标的类名,isActiveAnim 表示是否需要动画,loading 标识加载状态。给按钮添加点击事件 emits 出去,如果 loading 为 false 就不触发事件
5、popover 气泡卡片
设置两个插槽:具名插槽用于表示出发弹出层的视图,匿名插槽用于表示弹出层视图中展示的内容。同时希望可以控制弹层的位置
6、瀑布流组件
7、长列表组件
8、confirm 确认组件
虚拟 dom 的概念就是通过 js 来描述 dom 元素,vnode 虚拟节点就是告诉 vue 页面上需要渲染什么样式的节点。h 函数就是用来创建 vnode 函数,h 函数接收三个参数:要渲染的 dom 元素,attrs 对象和子元素,render 函数:可以根据 vnode 虚拟节点来渲染
9、trigger-menu 移动端 tab-bar
10、倒计时 count-down 组件
# 三、API
一、 window.navigator.userAgent
属性,拿到用户的设备信息
二、 Element.getBoundingClientRect()
方法,获得 dom 元素的位置信息
三、 window.matchMedia()
方法,接受一个媒体查询解析的字符串,返回一个 MediaQueryLise 对象,对象有 change
事件和 matches
属性(是否匹配成功),例如:
matchMedia = window.matchMedia('(prefers-color-scheme: dark)') | |
themeClassName = matchMedia.matches ? 'dark' : 'light' |
匹配系统窗口的 scheme 主题是否是 dark 模式。
四、 window.getComputedStyle()
方法返回 DOM 元素的 css 样式属性,包含位置等信息,第二个参数可以指定对应要获得的属性
五、window.IntersectionObserver 观察目标元素与祖先元素或顶级文档视口交叉状态
六、 Element.requestFullscreen()
让指定元素全屏显示。 Document.exitFullscreen()
退出全屏。
七、History.pushState() 方法,改变 url 但是不会跳转页面
八、 URL.createObjectURL()
方法,获得到对应的 blob 对象 ,可以将文件对象变成一个可以访问的文件对象链接
九、 BroadcastChannel
广播通道,进行同源页面之间的通信(但是存在兼容性问题)
#
# 四、vue3 技巧
一、transition 动画标签钩子函数
使用 js 进行自定义动画样式和触发时机.(before-enter、enter、leave 等事件),只使用 js 设置动画时,可以给 transition 组件的 css 属性绑定为 false
二、自定义指令实现图片懒加载
方案:监听所有图片是否可见(交互 api),如果图片不可见,就不加载图片(设置 src 属性),如果图片可见就加载图片。
注意细节是:①对于每一个 img,当监视到在视口中出现过,就可以赋值属性 src,然后就可以使用 stop()
方法停止监视 dom 元素是否在视口显示 ②使用 import.meta.globEager()
方法,可以同步导入所有的指令,然后一同注册
三、多组件共享数据的方式
①父传子(绑定数据,使用 props 接收)②子传父(自定义事件)③依赖注入 Provide /inject( 适用于嵌套层级较深 )④全局状态管理 vuex 或者 pina
四、搜索框匹配内容高亮显示
使用字符串的 replace()方法,传入正则,将匹配的内容替换为高亮显示的内容(使用 v-html 进行渲染)
五、h 函数和 render 函数
①模板 VS 渲染函数:Vue 模板会被预编译成虚拟 DOM 渲染函数,Vue 也提供了 API 使我们可以不使用模板进行编译:直接手写渲染函数,渲染函数相比于模板更加灵活,而模板更加直观和方便。
②h 函数用于创建 vnodes 虚拟节点,第一个参数是 dom 类型(可以使用 'div' 等,也可以使用组件),第二个参数是 props (包括组件中的属性和方法 ,或者 dom 的属性如 style),第三个参数是子元素。
③render 函数,第一个参数是要渲染的虚拟节点,第二个参数是要渲染的位置(传入 dom 元素)
六、状态驱动 css
将响应式数据绑定到 css 之中: v-bind(变量名称)
七、从部分组件到路由的跳转动画
①History.pushState() 方法改变 url 地址栏(注意要绑定对应的动态路由,不然一刷新就会空白)②设置过渡动画(可以使用 GSAP)
八、router-view 作用域插槽
使用 router-view 作用域插槽,配合 transition 中的自定义事件,加上 keep-alive 的 include 属性缓存动态数组中的组件,利用 component 组件的 is 属性动态绑定上 router-virew 的作用域插槽,实现移动端下路由切换时的动态效果
#
# 五、其他业务
一、人类行为验证
目前人类行为验证的实现方案,主要分为两种:
收费平台,年费在几万到几十万不等,有专门的技术人员帮助对接:
极验
网易易盾
...
免费开源,验证的精准度,需要看服务端的能力:
gitee
开源的: SliderCaptcha
二、头像裁剪与上传
三、对象存储服务
四、移动端页面过渡
维护一个虚拟任务栈的数组,当 push 操作时,将 vuex 中的 routerType 改为 push ,back 操作时,将 routerType 改为 back。
五、虚拟任务栈缓存
使用 keep-alive 组件中的 include 属性进行设置,属性值中包含的组件会进行缓存,在使用路由进行跳转的时候,改变 vuex 中的 routerType 属性(PC 端下永远为 none),根据 routerType 的属性进行路由跳转时动画的设置。
六、第三方登录
QQ 互联平台
微信开放平台
微信登录对接官方文档
七、用户反馈
腾讯兔小巢 (url 地址中改为 product)
八、第三方分享
当前微信不支持不同网站的分享
新浪微博开发平台
九、第三方支付
微信支付不支持 PC 网站应用(迂回)
支付宝开放平台
十、项目上线与发布