Vue项目搭建

162 阅读4分钟

项目基础搭建流程

〇、接口文档

管理后台: http://121.89.205.189:3001/admindoc/#api-Banner-GetBannerList

一、项目创建

1. vite创建项目

# npm 6.x
npm init vite@latest xxx --template vue
​
# npm 7+, 需要额外的双横线:
npm init vite@latest xxx -- --template vue

2. 安装依赖


cd xxx
npm install

3. 运行项目查看

npm run dev

二、创建api层

1. 接口文档地址

2. 安装axios


npm install axios -S

3. axios封装

3.1 service/axios.js
import axios from 'axios';
​
// 给axios设置一些默认行为
switch (process.env.NODE_ENV) {
  case 'production':
    axios.defaults.baseURL = 'http://121.89.205.189:3001/admin';
    break;
  case 'development':
    axios.defaults.baseURL = '/admin';
    break;
}
​
// 设置超时时间
axios.defaults.timeout = 5000;
// 设置跨域是否需要携带凭证
axios.defaults.withCredentials = false
// 设置判断是否响应成功的校验,3开头的代码一般都不在接口里面返回,一般都是资源类数据会返回
axios.defaults.validateStatus = status => {
  return /^2|3\d{2}$/.test(status)
}
​
// 设置请求拦截器,
axios.interceptors.request.use((config) => {
  // 进行token校验(JWT):接收服务器返回的token,存储到本地,每次发送请求,都需要带上token
  // token && (config.headers.Authorization = token)
  // config需要返回
  const token = localStorage.getItem('token')
  token && (config.headers.token = token)
​
  return config
}, error => {
  // 请求错误的操作,返回报错信息
  return Promise.reject(error)
})
​
// 设置响应拦截器
/**
 * response 包含内容:
 * response: {
 *  data: 响应主体内容,一般都是后端返回的数据
 *  status: 服务器相应的状态码
 *  statusText: 响应状态码的描述,
 *  headers:服务器响应头
 *  config: 之前发送请求是发送给服务器的配置对象
 *  request: 原生的ajax对象
 * }
 *  
 */
axios.interceptors.response.use(response => {
  if(response.data?.data?.token) {
    localStorage.setItem('token', response.data.data.token)
  }
  ElMessage({
    message: response?.data?.message,
    type: response.data.code === '200' ? 'success' : 'error',
  })
  return response.data
}, error => {
  const {response} = error
  // 如果返回了response,证明服务器返回了结果,可以通过返回的状态码判断
  if (response) {
    switch (response.status) {
      // 当前请求用户需要验证,一般为需要验证用户(未登录)
      case 401:
        break;
        // 服务器接收到请求,但拒绝处理,一般为登录状态过期(token失效)
      case 403:
        localStorage.removeItem('token')
        break;
        // 找不到资源,
      case 404:
        break;
    }
  } else {
    // 说明服务器连结果都没有返回,可能的原因有两种:
    /**
     * 1. 服务器崩掉了
     * 2. 前端客户端断网状态
     */
    if (!window.navigator.onLine) {
      // 判断为断网,可以跳转到断网页面
      return
    } else {
      return Promise.reject(error)
    }
  }
})
​
​
export default axios
3.2 service/index.js
// 使用封装好的 axios (已设置默认选项)
import axios from './axios'// 不缓存接口地址白名单
const whiteList = ['/banner/list', '/admin/list']
​
class Xhr {
  // 单例模式
  static getInstance() {
    if (!this.instance) {
      this.instance = new Xhr()
    }
    return this.instance
  }
​
  // 设置请求缓存
  constructor() {
    this.cache = new Map()
  }
​
  /**
   * 请求方法: 
   *  get类型options携带params参数作为数据对象, 
   *  post类型options携带data参数作为数据对象
   */
  request(options) {
    // 对get请求做一层缓存,允许post请求添加相同的数据
    const {
      method,
      url,
      params
    } = options
    let accessKey = url
    // 如果是get请求且有参数,要换缓存到参数,
    // 否则所有该url的请求都返回同一数据
    // post 请求是添加数据不需要缓存
    if (method === 'get' && params) {
      for (let key in params) {
        accessKey += key + params[key]
      }
    }
​
    // 这里借鉴了vue源码的watcher
    if (this.cache.has(accessKey)) {
      return Promise.resolve(this.cache.get(accessKey))
    }
​
    return axios(options).then((res) => {
      if (method === 'get' && whiteList.indexOf(url) === -1) {
        this.cache.set(accessKey, res)
      }
      return res
    })
  }
}
​
export default Xhr.getInstance()
3.3 api/demo.js

组件内引用请求接口函数,传入数据对象{},使用.then接收返回值


import fetch from '../service'// post请求
export function docheckphone(data) {
  return fetch.request({
    url: "/user/docheckphone",
    method: 'post',
    data
  })
}
​
// get请求
export function cartGetRecommendlist(data) {
  return fetch.request({
    url: "/pro/recommendlist",
    method: 'get',
    params: {
      ...data
    }
  })
}

三、引入vue-router@4

1. 依赖安装


npm install vue-router@4 -S

2. 创建文件目录 src/router/index.js(ts)


import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import HomeView from '@/views/HomeView.vue'const routes: Array<RouteRecordRaw> = [
  { path: '/', component: HomeView },
  { path: '/other', component: () => import('../views/OtherView.vue') },
]
​
const router = createRouter({
  // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  history: createWebHashHistory(),
  routes, // `routes: routes` 的缩写
})
​
export default router

3. 入口文件导入


// main.js
// ...
​
import router from "./router/index"createApp(App).use(router).use(...).mount('#app')

四、引入vuex

1. 依赖安装


npm install vuex@4 -S

2. 创建文件目录src/store/index.js(ts)

import { createStore } from 'vuex'interface State{
  count: number
}
​
// 创建一个新的 store 实例
const store = createStore<State>({
  state() {
    return {
      count: 0
    }
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
})
​
export default store
​

3. 入口文件导入


// main.js
import store from './store/index'createApp(App).use(router).use(store).mount('#app')

4. 实现vuex数据持久化

安装插件


npm i vuex-persistedstate -S

修改store/index.js


import { createStore } from 'vuex'
// ++++++++++++
import createPersistedState from "vuex-persistedstate";
​
// 创建一个新的 store 实例
const store = createStore({
  state () {
    return {
      userInfo: {},
      currentMenuIndex: ''
    }
  },
  mutations: {
    updateUserInfo (state, payload) {
      state.userInfo = payload
    },
    updateCurrentMenuIndex (state, payload) {
      console.log(state.currentMenuIndex)
      state.currentMenuIndex = payload
    }
  },
  // ++++++++++++++
  plugins: [
    createPersistedState({
      // 设置要持久化的数据
      reducer: state => {
        return {
          currentMenuIndex: state.currentMenuIndex
        }
      }
    })
  ]
})
​
export default store

五、 引入组件库element-plus

element-plugs 官网地址

1. 依赖安装


npm install element-plus --save

2. 自动按需导入

这种方式不需要导入任何组件,可以直接使用


npm install -D unplugin-vue-components unplugin-auto-import

3. 配置文件配置

// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

4. 引入样式文件


// main.js
import 'element-plus/dist/index.css'

六、项目样式重置

1. 依赖安装


npm install normalize.css -S

2. 入口文件引入


// main.js
import 'normalize.css'