创建vue3项目

安装 pnpm 包管理器(有的话就跳过此步骤)

npm i -g pnpm

创建一个新项目

pnpm create vue
  • 然后需要你配置vue项目,具体更具个人喜好来
    在这里插入图片描述

创建完后,在你的根文件夹中就会出现你创建的项目文件夹

进入到项目文件夹并安装依赖

pnpm install

在这里插入图片描述

依赖安装完后,你的项目文件夹中会多出 node_modules 1 pnpm-lock.yaml 2

运行项目

pnpm dev

在这里插入图片描述

在这里插入图片描述

当你看到有这个页面的时候,就代表你的基础项目创建完成

配置 Eslint 效验 和 prettier 格式化

环境(设置)同步:

  1. 安装了插件 ESlint,开启保存自动修复
  2. 禁用了插件 Prettier,并关闭保存自动格式化
// vsc设置中的 setting.json 文件中修改
// ESlint插件 + Vscode配置 实现自动格式化修复
"editor.codeActionsOnSave": {
    "source.fixAll": true
},
"editor.formatOnSave": false,

配置文件 .eslintrc.cjs

  1. prettier 风格配置 https://prettier.io

    1. 单引号

    2. 不使用分号

    3. 每行宽度至多150字符

    4. 不加对象|数组最后逗号

    5. 换行符号不限制(win mac 不一致)

  2. vue组件名称多单词组成(忽略index.vue)

  3. props解构(关闭)

  rules: {
    'prettier/prettier': [
      'warn',
      {
        singleQuote: true, // 单引号
        semi: false, // 无分号
        printWidth: 150, // 每行宽度至多150字符
        trailingComma: 'none', // 不加对象|数组最后逗号
        endOfLine: 'auto' // 换行符号不限制(win mac 不一致)
      }
    ],
    // ESLint关注于规范,如果不符合规范,报错
    'vue/multi-word-component-names': [
      'warn',
      {
        ignores: ['index'] // vue组件名称多单词组成(忽略index.vue)
      }
    ],
    'vue/no-setup-props-destructure': ['off'], // 关闭 props 解构的校验(props 解构丢失响应式) -- 可以处理,所以就关闭校验
    // 💡 添加未定义变量错误提示 (未定义的变量直接使用,会提示错误)
    'no-undef': 'error'
  }

基于 husky 的代码检查工作流(提交代码到仓库前先效验自己的代码是否有问题)

husky 是一个 git hooks 工具 ( git的钩子工具,可以在特定时机执行特定的命令 )

husky 配置

  1. git初始化(需要打开git的命令行终端)
git init
  1. 初始化 husky 工具配置 https://typicode.github.io/husky/
pnpm dlx husky-init && pnpm install
  1. 修改 .husky/pre-commit 文件
修改 npm test 为 pnpm lint

**问题:**默认进行的是全量检查,耗时问题,历史问题。(就是默认是检查全部代码,但是有些代码并不是我们自己编写的,我们不需要负责,只需要检查自己的即可)

lint-staged 配置

  1. 安装
pnpm i lint-staged -D
  1. 配置 package.json
{
  // ... 省略 ...
  "lint-staged": {
    "*.{js,ts,vue}": [
      "eslint --fix"
    ]
  }
}

{
  "scripts": {
    // ... 省略 ...
    "lint-staged": "lint-staged"
  }
}
  1. 修改 .husky/pre-commit 文件
修改 pnpm lint 为 pnpm lint-staged

调整项目目录

默认生成的目录结构不满足我们的开发需求,所以这里需要做一些自定义改动。主要是两个工作:

  • 删除初始化的默认文件
  • 修改剩余代码内容
  • 新增调整我们需要的目录结构
  • 安装预处理器插件(如果用到sass之类的才需要进行这一步)
  1. 删除多余文件

  2. 修改内容

src/router/index.js

import { createRouter, createWebHashHistory } from 'vue-router'

// history 模式: createWebHistory     地址栏不带 # 号
// hash 模式: createWebHashHistory    地址栏带 # 号
// vite 中的环境变量 import.meta.env.BASE_URL  就是 vite.config.js 中的 base 配置项

const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),
  routes: []
})

export default router

import.meta.env.BASE_URL 是Vite 环境变量:https://cn.vitejs.dev/guide/env-and-mode.html

src/App.vue

<script setup></script>

<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<style scoped></style>

src/main.js

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.mount('#app')
  1. 新增需要目录 api utils (src目录下)
├── api (存放与后端API交互的代码)
|
├── assets (存放静态资源,如图片、字体、图标等)
|
├── components (存放可复用的Vue组件)
|
├── router (存放Vue-Router相关代码)
|    └── index.js
|
├── store (仓库: pinia - 状态管理工具)
|    └── modules
|           └── 分仓库
|    └── index.js (配置仓库统一管理)
|
├── utils (存放工具函数,如:request.js[axios请求/响应拦截器])
|    └── request.js (封装axios模块)
|
├── views (存放页面组件)
|
App.vue (Vue应用的根组件)
main.js (应用的入口文件)

引入 element-ui 组件库

官方文档: https://element-plus.org/zh-CN/

  • 安装
pnpm add element-plus

自动按需:

  1. 安装插件
pnpm add -D unplugin-vue-components unplugin-auto-import
  1. 然后把下列代码插入到你的 ViteWebpack 的配置文件中
...
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    ...
    AutoImport({
      resolvers: [ElementPlusResolver()]
    }),
    Components({
      resolvers: [ElementPlusResolver()]
    })
  ]
})

  1. 在 .eslintrc.cjs 中声明全局变量名,解决使用 element方法 时报未导入的错误(实际上已经通过自动按需导入了)
module.exports = {
  ...
  globals: {
    ElMessage: 'readonly',
    ElMessageBox: 'readonly',
    ElLoading: 'readonly'
    // 如果使用其他插件,再进行配置即可
    // ...
  }
}
  1. 直接使用(测试是否可以自动按需导入)
<script setup>
    ElMessage.success('Hello Vue 3 + Vite')
</script>
<template>
  <div>
    <el-button type="primary">Primary</el-button>
    <el-button type="success">Success</el-button>
    <el-button type="info">Info</el-button>
    <el-button type="warning">Warning</el-button>
    <el-button type="danger">Danger</el-button>
    ...
  </div>
</template>

**彩蛋:**默认 components 下的文件也会被自动注册~

Pinia - 构建用户仓库 和 持久化

官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

  1. 安装插件 pinia-plugin-persistedstate
pnpm add pinia-plugin-persistedstate -D
  1. 配置 main.js
import persist from 'pinia-plugin-persistedstate'
...
app.use(createPinia().use(persist))
  1. 配置 stores/user.js(测试用的,实际可以自己配置仓库)
import { defineStore } from 'pinia'
import { ref } from 'vue'

// 用户模块
export const useUserStore = defineStore(
  'big-user',
  () => {
    const token = ref('') // 定义 token
    const setToken = (t) => (token.value = t) // 设置 token

    return { token, setToken }
  },
  {
    persist: true // 持久化
  }
)

Pinia - 配置仓库统一管理

pinia 独立维护

- 现在:初始化代码在 main.js 中,仓库代码在 stores 中,代码分散职能不单一

- 优化:由 stores 统一维护,在 stores/index.js 中完成 pinia 初始化,交付 main.js 使用

仓库 统一导出

- 现在:使用一个仓库 import { useUserStore } from ./stores/user.js 不同仓库路径不一致

- 优化:由 stores/index.js 统一导出,导入路径统一 ./stores,而且仓库维护在 stores/modules 中


  1. 将 main.js 中与 pinia 相关的代码 移动到 stores/index.js 中
  • stores/index.js 需要从 main.js 中抽取的代码
// 就是这些代码
import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate'

// app.use(createPinia().use(persist)) 这是从main.js 中抽取出来的
// 需要进行改写成
const pinia = createPinia()
pinia.use(persist)

export default pinia // 导出 pinia 到 main.js 中进行全局注册

// 将仓库中的 数据和方法 导入到 index.js 并进行统一 导出
// 这样 后续 我们只需要引入 '@/stores' 即可 不用 '@/stores/modules/仓库文件名'
// 例如
export * from './modules/user' // 导出 user 模块
  1. mina.js 导入 pinia 并全局注册
import pinia from '@/stores/index.js'
app.use(pinia)

数据交互 - 请求工具设计

1. 创建 axios 实例 并 完善

们会使用 axios 来请求后端接口, 一般都会对 axios 进行一些配置 (比如: 配置基础地址等)

一般项目开发中, 都会对 axios 进行基本的二次封装, 单独封装到一个模块中, 便于使用

  1. 安装 axios
pnpm add axios
  1. 新建 utils/request.js 封装 axios 模块

    利用 axios.create 创建一个自定义的 axios实例 来使用

  • 官方文档: https://www.axios-http.cn/docs/instance
import axios from 'axios'
import { useUserStore } from '@/stores'
import router from '@/router'

const instance = axios.create({
  // TODO 1. 基础地址,超时时间
  baseURL: '接口地址',
  timeout: 10000
})

// 请求拦截器
instance.interceptors.request.use(
  function (config) {
    // TODO 2. 携带token
    const userStore = useUserStore()
    if (userStore.token) {
      config.headers.Authorization = userStore.token
    }
    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

// 响应拦截器
// 第一个函数处理的是业务逻辑上成功的响应,而第二个函数处理的是HTTP请求层面上的错误响应。
instance.interceptors.response.use(
  function (response) {
    // TODO 3. 处理业务失败
    if (response.data.code !== 0) {
      ElMessage.error(response.data.message || '服务器异常')
      return Promise.reject(response.data)
    }
    // TODO 4. 摘取核心响应数据
    return response
  },
  function (error) {
    // TODO 5. 处理401错误
    // 特殊的错误情况 => 401 权限不足 或 token 过期 => 拦截到登录
    if (error.response?.status === 401) {
      router.push('/login')
    }

    // 错误的默认情况 => 主要给提示
    ElMessage.error(error.response.data.message || '服务器异常')
    return Promise.reject(error)
  }
)

export default instance

配置路由 router/index.js 中

  • 这里只是示例,具体配置需要根据项目需求来配置
  routes: [
    // 一级路由
    { path: '/login', component: () => import('@/views/login/LoginPage.vue') },
    {
      path: '/',
      component: () => import('@/views/layout/LayoutContainer.vue'),
      // 强制跳转
      redirect: '/article/manage',
      // 二级路由
      children: [
        { path: '/user/profile', component: () => import('@/views/user/UserProfile.vue') },
        { path: '/user/avatar', component: () => import('@/views/user/UserAvatar.vue') },
        { path: '/user/password', component: () => import('@/views/user/UserPassword.vue') }
      ]
    }
  ]

全局前置守卫

  • 官方文档: https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

配置在 router/index.js 中

// 登录访问拦截
router.beforeEach((to) => {
  // 如果什么都没有,undefined 或返回 true 默认直接放行
  // 返回 false 以取消导航, 拦回 from 地址页面

  // 这里的代码可以更具具体情况去进行更改
  // 具体路径 或者 路径对象 拦截到对应地址
  const userStore = useUserStore() // 获取 user 库要放在 beforeEach() 不然创建太早了,找不到 user库
  return !userStore.token && to.path !== '/login' ? '/login' : true
})

  1. node_modules 文件夹是文件夹在 Node.js 项目中扮演着核心角色,它主要用于管理项目的依赖 ↩︎

  2. pnpm-lock.yaml 是 pnpm(性能化 Node.js 包管理器)使用的锁文件 ↩︎

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值