Vue3 project actual combat

Table of contents

1. Project preparation

2. Basic grammar application

2.1. Mixin application

2.2. Network request

2.3. Show and hide

2.4. Programmatic routing jump

2.5. Download information

2.6. Calling method

2.7. Monitor routing changes

2.8, pinia application

(1)Storage token(user.js)

(2) Select all and none case (car.js)

1. Project preparation

download:

cnpm i unplugin-auto-import -D //setup syntactic sugar plug-in

npm i -D @types/node //Solve the problem that vite cannot @

npm install element-plus --save //Component library

npm install -D unplugin-vue-components //Introduce component library on demand

npm install less
npm install less-loader
npm install @originjs/vite-plugin-global-style

In vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import globalStyle from '@originjs/vite-plugin-global-style'
// cnpm i unplugin-auto-import -D setup 语法糖插件
import AutoImport from 'unplugin-auto-import/vite'
import path from 'path'
export default defineConfig({
  plugins: [vue(),
  AutoImport({
    imports: ['vue', 'vue-router']
  }),
  globalStyle({
    sourcePath:'./src/assets/css',
    lessEnabled:true
  }),
],
  resolve: {
    // 配置路径别名(解决vite不能@问题)  npm i -D @types/node
    alias: {
      "@": path.join(__dirname, 'src'),
      "#": path.join(__dirname, 'types')
    }
  }
})

Component library address:  Design | Element Plus

2. Basic grammar application

2.1. Mixin application

During the v-for loop, the status returned by the backend is a number, and the frontend needs to echo it into the corresponding Chinese character. You can use mixin to encapsulate this.

import courseType from "../../mixins/courseType.js";
let { courseTypeFn } = courseType();

js code in the mixin folder:

export default function () {
    let courseTypeFn = (type) => {
        let val = ''
        switch (type) {
            case 1:
                val = '初级';
                break;
            case 2:
                val = '中级';
                break;
            case 3:
                val = '高级';
                break;
            default:
                val = ''
        }
        return val;
    }
    return { courseTypeFn, }
}

View application: { { courseTypeFn(item.courseLevel) }}

The status can also be determined in methods:

2.2. Network request

After getting the request, first define the data type and get the data in the onBeforeMount life cycle.

// api
import {
  getSliders,
  getFirstCategorys,
} from "@/api/api.js";
import { onBeforeMount } from "vue";
// 轮播图数据
let sliderList = ref([]);
// 一级分类数据
let firstList = ref([]);
// 生命周期
onBeforeMount(() => {
  getSliders().then((res) => {
    sliderList.value = res.data.list;
  });
  getFirstCategorys().then((res) => {
    firstList.value = res.data.list;
  });
});

2.3. Show and hide

<div class="active-r" v-if="isShow"></div>
// 定义数据
let isShow = ref(false);
// 事件
const mouseHover = () => {
  isShow.value = true;
  );
};

2.4. Programmatic routing jump

import { useRouter } from "vue-router";
const router = useRouter();
//方法里跳转指定页面
const GoJump = (id) => {
  router.push({
    path: "/about/details",
    query: { id },
  });
};

Receive parameters

import { useRoute } from "vue-router";
let route = useRoute();
courseId: route.query.id,

2.5. Download information

Get the file stream returned by the backend, assemble a full file name yourself, create an a tag on the page, and implement the download function.

const download = (item) => {
  downloadAttachment({
    courseId: item.courseId,
    attachmentId: item.id,
  }).then((res) => {
    //后端返回的是文件流
    const blob = new Blob([res]);
    let fileName = item.attachmentName;
    let fileUrl = item.attachmentUrl;
    const extName = fileUrl.substring(fileUrl.lastIndexOf(".")); //.gif
    fileName = fileName + extName; //kkkk.gif
    // 前端创建a标签进行新窗口的打开
    const link = document.createElement("a");
    link.download = fileName;
    link.target = "_black";
    link.style.display = "none";
    link.href = URL.createObjectURL(blob);
    document.body.appendChild(link);
    link.click();
    URL.revokeObjectURL(link.href);
    document.body.removeChild(link);
  });
};

Or you can directly  window.open (info.url) ;

2.6. Calling method

const pageSize = ref(8);
const getlist = () => {
  mostNew({
    pageNum: pageNum.value,
    pageSize: pageSize.value,
  }).then((res) => {
    newList.value = res.data.pageInfo.list;
    total.value = res.data.pageInfo.total;
  });
};
const handleSizeChange = (val) => {
  pageSize.value = val;
  getlist();
};

2.7. Monitor routing changes

// 头部监听路由变化
watch(
  () => router.currentRoute.value.name,
  (toPath) => {
    if (toPath == "Home") {
      currentId.value = 1;
    } else if (toPath == "About") {
      currentId.value = 2;
    } else if (toPath == "Shop") {
      currentId.value = 3;
    }
  },
  { immediate: true }
);

2.8, pinia application

Download the persistence storage plug-in: cnpm i pinia-plugin-persist

index.js of the folder

import {createPinia} from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store=createPinia()
store.use(piniaPluginPersist)
export default store

(1)Storage token(user.js)

import { defineStore } from 'pinia'
export const useUserStore = defineStore({
    id: 'user',
    state: () => {
        return {
            token: ''
        }
    },
    actions: {
        setToken(token) {
            this.token = token
        }
    },
    // 开启数据缓存
    persist: {
        enabled: true,
        strategies: [{
            key: 'xiao_user',
            storage: localStorage
        }]
    }
})

Page usage:

// pinia
import { useUserStore } from "../stores/user.js";
const userStore = useUserStore();
 userStore.setToken(res.data.accessToken);

(2) Select all and none case (car.js)

deconstruct

import { defineStore } from 'pinia'
export const useCartStore = defineStore({
    id: 'cart',
    state: () => {
        return {
            cartList: [],//购物车数量
            select: [],//选中的商品id
        }
    },
    getters: {
        isChecked() {
            return this.select.length == this.cartList.length
        }
    },
    actions: {
        addCart(list) {
            list.forEach(v => {
                v['check'] = true
                this.select.push(v.id)
            })
            this.cartList = list
        },
        // 全选
        all() {
            this.select = this.cartList.map(v => {
                v['check'] = true
                return v.id
            })
        },
        // 全不选
        unAll() {
            this.cartList.forEach(v => {
                v['check'] = false
            })
            this.select = []
        },
        //单个选
        itemChecked(index) {
            let id = this.cartList[index].id;
            let idx = this.select.indexOf(id);//检查它里面有没有
            if (idx > -1) {
                this.cartList[index].check = false;
                this.select.splice(idx, 1);//有
            } else {
                this.cartList[index].check = true;
                this.select.push(id);//没有
            }
        }
    },
})

Page usage:

import { storeToRefs } from "pinia";
import { useCartStore } from "../stores/car.js";
let cartStore = useCartStore();
let { cartList, isChecked } = storeToRefs(cartStore);
onBeforeMount(() => {
  getShopCarList().then((res) => {
  firstList.value = res.data.list;
  });
  cartStore.addCart(firstList.value);
  console.log(cartStore.cartList);
});
const checkAll = () => {
  if (isChecked.value) {
    cartStore.unAll(); // 不选
  } else {
    cartStore.all(); // 全选
  }
};

Guess you like

Origin blog.csdn.net/qq_44930306/article/details/132408232