# official-website-template **Repository Path**: crazy_about_programming/official-website-template ## Basic Information - **Project Name**: official-website-template - **Description**: 基于vue3,vite开发的通用型官方网站模板。 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: http://ainowr.com - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2025-05-03 - **Last Updated**: 2025-05-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 1. 相关链接 * 预览:[在线预览](http://ainowr.com) * 演示&教程:[视频演示&教程]() 待制作 * 获取源码方式 * [gitee地址](https://gitee.com/ainowr/official-website-template) ## 2. 项目概要 * **keywords(全):** `vue3,vite,vant,Element Plus,json-server,Axios,Pinia,Vuex,Vue Router,...` * 采用vue3,vite开发的通用型官方网站模板,而且还提供了许多小demo,帮助你快速上手vue3工程化开发! ## 3. 项目详情 ### 3.1. 前,后端简述 * **前端:** `vue3,vite,vant,Element Plus,json-server,Axios,Pinia,Vuex,Vue Router,......` * 采用vue3,vite工程化,语言基于html + js + css * **库和工具:** Vant,Element Plus,layui-vue,json-server,Axios,Pinia,Vuex,Vue Router...... * **知识点:** less,组件mixins,导航守卫,pinia持久化,请求/响应拦截器,api模块封装,第三方库的按需引入,模拟后端接口(json-sever,mock-sever),...... * **知识点-UI:** clip-path剪裁任意形状,带偏移且平滑滚动的hash定位, * **后端:** * 后端接口还未完工,可先参考 [Q免签支付](https://juejin.cn/post/7338214297572835380)。 * **库和工具:** Hutool-captcha,...... ### 3.2. 前端部分详述 #### Vant,Element Plus,layui-vue按需引入,及组件推荐 * [Vant4](),[Element Plus](https://element-plus.org/zh-CN/),[layui-vue]() * 弹出层:layui-vue弹层 * 图片,图片预览:el-image,el-image-viewer * 滚动条:默认 > el-scrollbar * main content的滚动条使用document的滚动条而非改到main div,否则可能会有一系列问题,如会影响整个document的高度,影响懒加载机制,document的scroll监听失效等问题, * 只有局部滚动的时候才开启局部div的滚动条 * 骨架:el-skeleton * 地图:百度地图 * index管理 * 999 弹出层,图片预览 #### 路由配置 ```js /* * 注意 * name重复的路由只会注册靠后的 * path重复的路由,匹配靠前的 * */ import HomeView from "@/a-main-app/home/HomeView.vue"; const routes = { path: '/home', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/a-layout/homeLayout/HomeLayout.vue'), redirect: '/', //如果父级路由设置component,访问子路由会先在app.vue的RouterView(路由出口)中显示该组件,然后再在该组件的RouterView显示子组件,若该组件没有RouterView,子组件应该显示的位置会空白 //若未设置component,访问子路由就直接在app.vue的RouterView中显示子组件 // component: () => import('@/components/views/DemoView.vue'), meta: { title: 'Q享-齐分享,同乐趣,共进步!', // 设置该路由在侧边栏和面包屑中展示的名字 // icon: 'el-icon-s-help' // 设置该路由的图标,对应路径src/assets/icons/svg // hidden: true, // 如果设置为true,则不会在侧边栏出现 // noCache: true // 如果设置为true,则不会被 缓存(默认 false) // breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 // affix: true // 如果设置为true,则标签将永远显示在左侧 // activeMenu: '/demo/note' // 如果设置路径,侧边栏将突出显示您设置的路径 // roles: ['admin','editor'] // 设置该路由进入的权限,支持多个权限叠加 }, children: [ { path: '/', name: 'home', component: HomeView, meta: { title: 'Q享-菜单', transition: 'fade', anchorTopOffset: 200 }, }, { path: '/demo', name: 'demo', children: [ // 动态路由传参,?为参数可选符,不加的话表示必须传参,否则匹配不到组件,如/demo/note,/demo/note/显示空白 { path: '/note/:words?', name: 'note', component: () => import('@/a-main-app/home/note/NoteCompositionApiSimple.vue') }, ] }, ] } ``` #### mock/json-sever 后端接口模拟 mock [参考](https://blog.csdn.net/m0_64378190/article/details/136504896) json-sever 参考官网 上述方案实现要么全部用模拟接口,要么全部用正式接口,适合团队开发 个人开发一般是采用后端完善的接口则直接使用,没完善的接口则使用模拟数据:即直接在封装请求的方法中返回模拟数据,这样开发环境,生产环境都能正常使用,工作量也会减少,这也是本项目最终采用的方法 #### Anxios请求/响应拦截器 在请求或响应被 then 或 catch 处理前拦截它们,实现统一处理请求和响应的逻辑,减少代码冗余,提高代码的可维护性和灵活性。 ```js // 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 2xx 范围内的状态码都会触发该函数。 // 对响应数据做点什么 return response; }, function (error) { // 超出 2xx 范围的状态码都会触发该函数。 // 对响应错误做点什么 return Promise.reject(error); }); ``` #### Less支持 * less是一种动态样式表语言,它扩展了 CSS 的功能,增加了变量、嵌套规则、运算等功能。 * vue工程化,可通过包管理器引入less,less-loader使得在组件样式支持less #### 组件 Mixins * 组件 Mixins 是 Vue.js 中用于复用组件逻辑的一种机制。通过将共享的代码块定义为 mixin,并在多个组件中引入该 mixin,可以避免重复编写相同的逻辑。这有助于减少代码冗余,提高代码的可维护性和复用性。Mixins 可以包含组件选项,如 data、methods、computed 等,使得这些选项能够在多个组件之间共享。 #### clip-path: polygon div形状剪裁,自定义 ```css //实现缺角矩形div clip-path: polygon( 0 0,100% 0,100% 100%,70% 100%,0 30%) ``` #### vuex,pinia状态管理库选择 * Vuex是Vue.js官方出品的状态管理库, * Pinia则是一个较新的状态管理库,相比Vuex, * 简化了核心概念 * setup store 与 Vue 组合式 API 的 [setup 函数](https://cn.vuejs.org/api/composition-api-setup.html) 有异曲同工之妙,而且也提供options store保留Vuex用法 * 插件支持,如持久化 * 极致轻量化,开发工具支持 * ...... #### VueRouter 导航守卫 * 导航守卫是 Vue Router 提供的一种机制,用于在路由发生变化时执行特定的逻辑。通过定义导航守卫,可以在路由进入、离开或更新前后执行一些操作,如权限验证、数据获取、页面跳转/取消跳转等。 ```js router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) else next() }) ``` ### 3.2. 前端踩坑 这些坑都会消耗或多或少时间,精力,【笑哭,泪目】 #### 父子组件生命周期执行流程 不要自以为父组件的生命周期先于子组件执行 [参考文章-子组件调用父组件的接口回调数据的坑](https://www.cnblogs.com/YiFeng-Liu/p/15125141.html) #### ...... ### 3.3. 后端详述 #### Hutool-captcha * [Hutool](https://doc.hutool.cn/pages/index/)是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅 * Hutool-captcha Hutool中加入验证码生成和校验功能 ```java //定义图形验证码的长、宽、验证码字符数、干扰线宽度 ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4); //ShearCaptcha captcha = new ShearCaptcha(200, 100, 4, 4); //图形验证码写出,可以写出到文件,也可以写出到流 captcha.write("d:/shear.png"); //验证图形验证码的有效性,返回boolean值 captcha.verify("1234"); ``` ## 4. 功能,特点,优化 ### 4.1. 功能,效果: * music player affix * 全响应式布局(各种分辨率的屏幕都能友好显示) * Header组件封装 * 可切换模式:自动隐藏,总是显示,标题模式 * 导航高亮,手机适配方案 * 平滑滚动的hash定位,backToTop ### 4.2. 后期完善功能 * 邮箱验证码登录 * 图形验证码 * 图片懒加载 ### 4.3. 交互效果 * 优化——响应速度,性能优化,用户体验, * loading 蒙层 * 静态资源压缩处理 * 待优化 * 图片懒加载 * audio未配置缓存,每次切换源,都会从网络加载 ### 4.4. 待探究 * 为了实现解耦/功能点组合,对统一属性开多个watch,性能消耗情况 * 建议使用function来组合功能点 ## 4. 简单使用 * install node https://nodejs.org (npm,yarn) * node -v; npm -v; yarn -v; * Project Setup * yarn install | npm install * Compile and Hot-Reload for Development * yarn dev | npm run dev * Compile and Minify for Production ```sh npm run build npm run preview ``` ## 常见问题 * build 打包失败 * 由于我没把一些demo dir/files 推送到git,所以导致 vite.config.js 中 build.rollupOptions.input配置会导致找不到文件 * 解决办法:注释掉,例如 // p1: resolve(__dirname, './pages-demo/sub/index.html'), **已经到文章末尾了,感谢您的阅读!**