vue3 framework construction+vite+ts+elementplus+axios+vuex

1. window + R to open the command line and enter

npm create vite@latest

Follow the steps below to create
Insert image description here

2. Enter the project to download dependencies

3. Run the project after the dependencies are installed

4.Introduction of element-plus

npm install element-plus --save

Introduced in main.js
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App).use(ElementPlus)
app.mount('#app')

To use el-icon, you need to download and import it separately.
npm install @element-plus/icons-vue

Introduced in main.js
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

5. Configure routing

npm install vue-router

Introduce routing in main.js

import router from './router'
const app = createApp(App).use(ElementPlus).use(router)

Create a new router file
![Insert image description here](https://img-blog.csdnimg. cn/ecd8b53e8d2d47768a7ef702476d39bd.png

import { createRouter, createWebHashHistory } from "vue-router"
const routes = [

    {

        path: '/',

        name: 'index',

        component: () => import('../views/index.vue')

    },

    {

        path: '/login',

        name: 'login',
        component: () => import('../views/login.vue')

    }

]

export const router = createRouter({

    history: createWebHashHistory(),

    routes: routes

})

export default router

Note: Be sure to add router-view in app.vue! ! !

6.axios encapsulation interfacer request

npm i axios
npm i qs

Create a new request>axios.js file

/**axios package
 * Request interception, corresponding interception, and unified error handling
 */
import axios from 'axios';
import QS from 'qs';
import router from '../router/index'
//qs.stringify() serializes the object into the form of a URL and splices it with & amp;
// let protocol = window.location.protocol; //Protocol
// let host = window.location.host; //Host
// axios.defaults.baseURL = protocol + "//" + host;
axios.defaults.baseURL = 'http://localhost:8888'
 
axios.interceptors.request.use( //Response interception
        async config => {
            // Determine whether there is a token in vuex before sending each request
            // If it exists, add the token to the header of the http request, so that the background determines your login status based on the token.
            // Even if the token exists locally, it is possible that the token has expired, so the return status must be judged in the response interceptor.
            config.headers.token = sessionStorage.getItem('token')
            return config;
        },
        error => {
            return Promise.error(error);
        })
    //Response interceptor
axios.interceptors.response.use(
    response => {
        if (response.status === 200) {
            return Promise.resolve(response); //In progress
        } else {
            return Promise.reject(response); //Failed
        }
    },
    // When the server status code is not 200
    error => {
        if (error.response.status) {
            switch (error.response.status) {
                // 401: Not logged in
                // If not logged in, jump to the login page and carry the path of the current page.
                // Return to the current page after successful login. This step needs to be done on the login page.
                case 401:
                    break
                    // 403 token expired
                    // Prompt user when login expires
                    // Clear the local token and empty the token object in vuex
                    // Jump to the login page
                case 403:
                    sessionStorage.clear()
                    router.push('/login')
                    break
                    //404 request does not exist
                case 404:
                    break;
                    // For other errors, throw an error message directly
                default:
            }
            return Promise.reject(error.response);
        }
    }
);
/**
 * get method, corresponding to get request
 * @param {String} url [requested url address]
 * @param {Object} params [parameters carried during request]
 */
const $get = (url, params) => {
        return new Promise((resolve, reject) => {
            axios.get(url, {
                    params: params,
                })
                .then(res => {
                    resolve(res.data);
                })
                .catch(err => {
                    reject(err.data)
                })
        });
    }
    /**
     * post method, corresponding to post request
     * @param {String} url [requested url address]
     * @param {Object} params [parameters carried during request]
     */
const $post = (url, params) => {
        return new Promise((resolve, reject) => {
            axios.post(url, QS.stringify(params)) //Serialize the object into the form of URL and splice it with & amp;
                .then(res => {
                    resolve(res.data);
                })
                .catch(err => {
                    reject(err.data)
                })
        });
    }
    //The following is required for vue3. It is not required for vue2. You only need to expose the get and post methods.
export default {
    install: (app) => {
        app.config.globalProperties['$get'] = $get;
        app.config.globalProperties['$post'] = $post;
        app.config.globalProperties['$axios'] = axios;
    }
}

Introduced in main.js

import Axios from './request/axios';
app.use(ElementPlus).use(Axios)

Enter the page where you need to send a request

import { getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
function logout() {
  proxy
    .$post("/api/qrycontent/", {
      page: 1,
      perpage: 4,
      section: "LearningGarden",
    })
    .then((response) => {
      console.log(response);
      if (response.code == 200) {
        sessionStorage.clear();
        router.push("/");
        ElMessage({
          message: "Exit successfully",
          type: "success",
        });
      }
    });
}

7. At this step, the interface will be blocked because cross-domain has not been configured yet. Next, configure cross-domain

 server: {
    proxy: {
      '/api': {
        target: 'http://----------------/', // actual request address
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, "/api"),
      },
    },
  },

8. Use vuex

npm i vuex

main.js introduction

import store from './store'
const app = createApp(App).use(router).use(ElementPlus).use(Axios).use(store)

New store>index.js

/*
 * @Author: wangdandan [email protected]
 * @Date: 2023-10-17 11:16:03
 * @LastEditors: wangdandan [email protected]
 * @LastEditTime: 2023-10-17 14:08:00
 * @FilePath: \vue3-practice\src\store\index.js
 * @Description: This is the default setting, please set `customMade`, open koroFileHeader to view the configuration and set it: https://github.com/OBKoro1/koro1FileHeader/wiki/Configuration
 */
import { createStore } from 'vuex'
//Similar to building a state tree in Redux

export default createStore({
  
  // 1. Store all global data
  state: {
    person:{
        name:'jack',
        age:20
    }
  },
 
  // 2. It is necessary to obtain the data obtained from the content in the state through calculation.
  // Can only be read and cannot be modified
  getters: {
    getPerson(state){
        return state.person
    }
  },
 
  // 3. Define various operations on state
  // Why not implement it directly in mutation but need to write it in action?
  // Mutations cannot perform asynchronous operations. aq: Get information from the cloud --> (waiting for feedback from the cloud) update to state asynchronous operation
  // Therefore: asynchronous operations need to be placed in actions, and simple direct assignment operations can be placed directly in mutations.
  mutations: {
   ageGrow(state,value){
    state.person.age + = value
   }
  },

  // 3. Define various operations on state
  //Actions cannot modify state directly and need to be updated in mutations.
  //Mutation does not support asynchronous, so you need to write the api to the url in the action
  actions: {
      // For example, action defines the operation of updating state
      // But it cannot be modified directly
      // All modification operations must be placed in mutations
      ageGrow(store,value){
        store.commit('ageGrow',value)
       }
  },

  //When the information in state is too long
  // Used to divide state
  // As follows, split the state tree into a user state.
  modules: {
// user: ModuleUser,
  }
})


Use on page

import { useStore } from "vuex";

 <h2>----------vuex use-------------</h2>
  <h3>Name: {<!-- -->{store.state.person.name}} ------------ Age: {<!-- -->{store.state. person.age}}</h3>
  <el-button @click="changeAge">Change age simultaneously</el-button>
  <el-button @click="asycChangeAge">Asynchronously change age</el-button>


//vuex
const store = useStore();
// Synchronously change vuex data
const changeAge = () =>{
  store.commit('ageGrow',1)
}
//Asynchronously change vuex data
const asycChangeAge = () =>{
  setTimeout(() => {
    store.dispatch('ageGrow',2)
  }, 100);
}

9. Configure environment variables



# just a flag
ENV = 'development'

# base api
VITE_APP_BASE_API = 'http://----------------/'

# title
VITE_APP_TITLE = 'Development environment'

Modify url in axios

 axios.defaults.baseURL = '/api';

Modify within vite.config.js

import path from "path";
import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';

// https://vitejs.dev/config/
export default ({ mode }) => {
  //The parameter mode is open mode or production mode
  //console.log(mode); // development or product
  const env=loadEnv(mode, process.cwd()); // Get the environment variables defined in the .env file
  console.log(env); //Variables are printed on the command line
  
  return defineConfig({
    plugins: [vue()],

    //The project is deployed in a sub-file of the main domain name, such as http://localhost:3000/myvite/. If not filled in, the default is /
    base: env.VITE_APP_BASE_URL,
    build: {
      cssCodeSplit: false, //default true, split the css and extract it into a css file, false extract all css into one file
    },

    resolve: {
      alias: {
        //Alias configuration
        "@": path.resolve(__dirname, "src"), //Configure the alias of src
        "@comp": path.resolve(__dirname, "src/components"),
      },
    },
    server: {
      proxy: {
        // proxy configuration
        "/api": {
          // target: "http://127.0.0.1/1000", //Local server environment backend directory D:\phpstudy_pro\WWW\1000
          target: env.VITE_APP_BASE_API,
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, "/api"),
        },
      },
    },
  })
}