【vue3】项目搭建

目录

    • 简介
    • 脚手架
    • 引入axios
    • 引入sass
    • 引入element-plus
    • vite.config.js
    • 路由配置
    • 全局状态管理
    • 完整main.js
    • 组合式API之Setup

简介

vue3:双向绑定改为ES6的Proxy;新的API风格,代码逻辑性更强、更易维护;性能提升,渲染更快、内存更少。
vite:新型前端构建工具,基于原生ES模块,极速启动、快速热更新,更优的开发体验。

以npm install和build过程为例, 之前vue2+webpack的项目在devops的编译环节非常耗时,在2-15min之间均有,vue3+vite的项目基本在1min以内。

脚手架

事先准备
nodejs需要大于16.0版本。
建议先卸载旧有nodejs,再安装nvm,通过nvm安装分别用于vue3项目和vue2项目的nodejs高低版本。

  1. 创建指令:npm create vue@latest
  2. 选项:TypeScript、Vue Router、ESLint 、Prettier (按需即可)
  3. 运行指令:
      npm install
      npm run dev
    

引入axios

  1. npm install axios --save
  2. 配置文件axios-config.js,统一封装请求
    /request/axios-config.js
    import axios from "axios";
    import router from "@/router";
    import qs from "qs";
    
    /* http request
     **请求拦截器
     **在发送请求之前进行的一系列处理,根据项目要求自行配置
     **例如:loading
     */
    axios.interceptors.request.use(
      (config) => {
        // 请求响应时间
        config.timeout = 60 * 60 * 1000;
        config.headers = {
          token: sessionStorage.getItem("accessToken"),
          // "Content-Type": "application/json"
          "Content-Type": "application/x-www-form-urlencoded",
        };
        return config;
      },
      (error) => {
        // 对请求错误做处理
        console.log(error); // for debug
        return Promise.reject(error);
      }
    );
    
    /* response
     **响应拦截器
     **允许在数据返回客户端前,修改响应的数据
     **返回体中数据:response.data,如果需要全部,则 return response 即可
     */
    axios.interceptors.response.use(
      (response) => response,
      (error) => {
        let message = "";
        // 处理响应错误
        if (error && error.response) {
          const errorResponse = error.response.data;
          if (errorResponse.msg || errorResponse.message) {
            message = errorResponse.msg || errorResponse.message;
            if (message.indexOf("无效token") > -1) {
              sessionStorage.removeItem("accessToken");
              sessionStorage.removeItem("userinfo");
              router.push({ path: "/login" });
            }
          }
        }
        return Promise.reject(error);
      }
    );
    
    const fetchPost = (url, params) => {
      return new Promise((resolve, reject) => {
        axios
          .post(url, qs.stringify(params))
          .then(
            (res) => {
              resolve(res.data.data);
            },
            (err) => {
              reject(err.data);
            }
          )
          .catch((err) => {
            reject(err.data);
          });
      });
    };
    
    const fetchPut = (url, params) => {
      return new Promise((resolve, reject) => {
        axios
          .put(url, qs.stringify(params))
          .then((res) => {
            resolve(res.data.data);
          })
          .catch((err) => {
            reject(err.data);
          });
      });
    };
    
    const fetchDel = (url, params) => {
      return new Promise((resolve, reject) => {
        axios
          .delete(url, {
            params: qs.stringify(params),
          })
          .then((res) => {
            resolve(res.data.data);
          })
          .catch((err) => {
            reject(err.data);
          });
      });
    };
    const fetchGet = (url, params) => {
      return new Promise((resolve, reject) => {
        axios
          .get(url, {
            params: qs.stringify(params),
          })
          .then((res) => {
            resolve(res.data.data);
          })
          .catch((err) => {
            reject(err.data);
          });
      });
    };
    
    /**
     * 不带参数的get请求
     * @param {*} url
     */
    const fetchGetNoParam = (url) => {
      return new Promise((resolve, reject) => {
        axios
          .get(url)
          .then((res) => {
            resolve(res.data.data);
          })
          .catch((err) => {
            reject(err.data);
          });
      });
    };
    
    export default {
      install: (app) => {
        app.config.globalProperties["$get"] = fetchGet;
        app.config.globalProperties["$post"] = fetchPost;
        app.config.globalProperties["$put"] = fetchPut;
        app.config.globalProperties["$del"] = fetchDel;
        app.config.globalProperties["$axios"] = axios;
      },
    };
    
  3. main.js引入
    import Axios from "@/request/axios-config.js";
    const app = createApp(App)
      .use(Axios);
    
  4. .vue使用
    import { getCurrentInstance } from "vue";
    const { proxy } = getCurrentInstance();
    
    let data=await proxy.$post("url",{});
    

引入sass

  1. npm install sass --save -dev
  2. npm install sass-loader --save -dev
  3. .vue使用:

引入element-plus

  1. npm install element-plus --save
  2. main.js引入
    import "element-plus/dist/index.css";
    import ElementPlus from "element-plus";
    import zhCn from "element-plus/dist/locale/zh-cn.mjs";
    
    const app = createApp(App)
      .use(ElementPlus, {
        locale: zhCn,
      });
    
  3. 使用见官网

vite.config.js

"@"路径配置及代理配置

import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
  server: {
    port: 8081,
    https: false,
    proxy: {
      "/check": {
        // 后台地址
        target: "http://127.0.0.1:18892",
        changeOrigin: true,
        // pathRewrite: {
        //   "^/check": "",
        // },
      },
    },
  },
});

路由配置

/router/index.js

import { createRouter, createWebHistory } from "vue-router";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/login",
      name: "login",
      component: () => import("../views/LoginView.vue"),
    },
    {
      path: "/",
      name: "home",
      component: () => import("../views/HomeView.vue"),
      children: [
        {
          path: "/index",
          name: "index",
          component: () => import("../views/Index.vue"),
        },
        
      ],
    },
  ],
});

router.beforeEach((to, from) => {
  if (!sessionStorage.getItem("accessToken") && to.name !== "login") {
    return { path: "/login" };
  }
  return true;
});

export default router;

main.js引入

import router from "./router";
const app = createApp(App)
  .use(router);

全局状态管理

/store/store.js

import { reactive } from "vue";

export const store = reactive({
  count: 0func: () => {
    ...
  },
});

.vue使用

<template> {{ store.count }}</template>

<script setup>
import { store } from './store.js'

store.func();
</script>

完整main.js

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";

import "./assets/main.css";

import "element-plus/dist/index.css";
import ElementPlus from "element-plus";
import zhCn from "element-plus/dist/locale/zh-cn.mjs";

import Axios from "@/request/axios-config.js";

const app = createApp(App)
  .use(router)
  .use(ElementPlus, {
    locale: zhCn,
  })
  .use(Axios);

app.mount("#app");

组合式API之Setup

一些常用功能示例

<script lang="ts" setup>
import { reactive, ref, getCurrentInstance, computed, onMounted } from "vue";
import { useRouter, useRoute, RouterView } from "vue-router";
const router = useRouter();
const route = useRoute();
const { proxy } = getCurrentInstance();
import { store } from "@/store/store.js";

// 计算属性,获取当前路由名称
const current= computed(() => {
  return route.name;
});

// 钩子函数
// 在组件完成初始渲染并创建 DOM 节点后运行
onMounted(() => {
  init();
});

// 响应式变量声明
const showTable = ref(false);
let tableData = reactive([]); 

// axios请求及store状态管理
const init= () => {
  tableData = await proxy.$post("/getResultList", {
    quarter: store.getQuarter(),
    year: store.getYear(),
  });
  showTable.value = true
};

// 路由跳转
const goLogin= () => {
  router.push({ path: "/login" });
};
  • ref:可以是 string、number 或 boolean 这样的原始类型,也可以是对象类型;在js中需要通过 .value,在template不需要;适合于原始类型和浅层级的对象。
  • reactive:只能用于对象类型;不需要 .value;适合于层级比较深的可变复杂对象。

你可能感兴趣的:(前端,vue3,vite)