国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦

這篇具有很好參考價(jià)值的文章主要介紹了快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、Vue基本概念

1.1-Vue3的優(yōu)點(diǎn)

  • Vue3支持Vue2額大多數(shù)特性。
  • 更好的支持TypeScript。
  • 打包大小減少41%。
  • 初次渲染快55%,更新渲染快133%。
  • 內(nèi)存減少54%。
  • 使用proxy代替defineProperty實(shí)現(xiàn)數(shù)據(jù)響應(yīng)式。
  • 重寫虛擬DOM的實(shí)現(xiàn)和Tree-Shaking。

二、API

2.1-setup

我們可以跟以前定義data和methods,但是vue3中我們更推薦使用setup函數(shù)。

  • setup是一個(gè)函數(shù)。只在初始化時(shí)執(zhí)行一次。以后大部分代碼都是在setup中寫。
  • 返回一個(gè)對(duì)象,對(duì)象中的屬性或方法,模板中可以直接使用。
  • setup返回的數(shù)據(jù)會(huì)和data和methods進(jìn)行合并,setup優(yōu)先級(jí)更高。
  • setup函數(shù)中沒有this。 以后開發(fā)都不使用this了
  • setup不要寫async函數(shù)。

因?yàn)閍sync函數(shù)必須返回一個(gè)json對(duì)象供模板使用,如果setup是一個(gè)async函數(shù),返回的將是一個(gè)promise對(duì)象。
如果setup是一個(gè)async函數(shù),那該組件就成了一個(gè)異步函數(shù),需要配合Suspense組件才能使用。


2.2-ref

讓數(shù)據(jù)變成響應(yīng)式。

(1)先引用ref
import {ref} from 'vue';

(2)將數(shù)據(jù)變成響應(yīng)式的。
let data1=ref(12);

(3)操作數(shù)據(jù)
data1.value = 123;

2.3-reactive

作用:定義對(duì)象格式的響應(yīng)式數(shù)據(jù)
如果用ref定義對(duì)象/數(shù)組,內(nèi)部會(huì)自動(dòng)將對(duì)象/數(shù)組轉(zhuǎn)換為reactive代理器對(duì)象。

  • const proxy=reactive(obj):接收一個(gè)普通對(duì)象然后返回該普通對(duì)象的響應(yīng)式代理器對(duì)象。
  • js中修改告訴不需要.value。
  • 一般用來定義一個(gè)引用類型的響應(yīng)數(shù)據(jù)。

2.4-toRefs

將響應(yīng)式對(duì)象中所有屬性包裝為ref對(duì)象,并返回包含這些ref對(duì)象的普通對(duì)象。
應(yīng)用:對(duì)trsctive定義的對(duì)象進(jìn)行toRefs包裝,包裝之后的對(duì)象中每個(gè)屬性都是響應(yīng)式的。


2.5-響應(yīng)式原理

通過proxy(代理):攔截對(duì)對(duì)象本身的操作,包括屬性的讀寫、刪除等操作。
通過Reflect(反射):動(dòng)態(tài)對(duì)被代理對(duì)象的響應(yīng)式屬性進(jìn)行特定的操作。


2.6-watch和watchEffect

watch - 指定監(jiān)聽數(shù)據(jù):

  • 監(jiān)聽指定的一個(gè)或多個(gè)響應(yīng)式數(shù)據(jù),一旦發(fā)生變化,就會(huì)自動(dòng)執(zhí)行監(jiān)視回調(diào)。
    • 如果是監(jiān)聽reactive對(duì)象中的屬性,必須通過函數(shù)來指定。
    • 監(jiān)聽多個(gè)數(shù)據(jù),使用數(shù)組來指定。
  • 默認(rèn)初始時(shí)不指定回調(diào),但是通弄過配置immediate為true,來指定初始時(shí)立即執(zhí)行第一次。
  • 通過配置deep為true,來指定深度監(jiān)視。

watchEffect - 不指定監(jiān)聽數(shù)據(jù):

  • 不用直接指定啦監(jiān)視的數(shù)據(jù),回調(diào)函數(shù)中使用的哪些響應(yīng)式數(shù)據(jù)就監(jiān)聽哪些響應(yīng)式數(shù)據(jù)。
  • 默認(rèn)初始就會(huì)執(zhí)行一次。

2.7-生命周期

vue2中的生命周期鉤子函數(shù)依舊可以使用,不過建議使用vue3的鉤子函數(shù)

快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦


2.8-ref獲取元素

vue2中是用thisref.xxx來獲取元素或組件,但是vue3中沒有this的概念。
vue3通過ref創(chuàng)建響應(yīng)式數(shù)據(jù)的api來獲取元素。

1.使用ref創(chuàng)建響應(yīng)式數(shù)據(jù),假設(shè)叫x
2.模板中綁定ref屬性,值為上面的x
注意不能使用v-bind動(dòng)態(tài)綁定。
這是x就是一個(gè)dom元素或組件了。


2.9-自定義hook函數(shù)

hook函數(shù)翻譯成中文就是鉤子函數(shù)(注意并不是生命周期的鉤子函數(shù))
比如ref,reactive,computed,watch,onBeforeMount等都是hook函數(shù),只不過他們都是vue內(nèi)部hook函數(shù)。

1.創(chuàng)建一個(gè)函數(shù),函數(shù)名稱必須以"use"開頭
2.函數(shù)必須return一些數(shù)據(jù)。


2.10-shallowReactive與shallowRef

他們都表示淺響應(yīng)式。

  • shallowReactive:只處理了對(duì)象第一層屬性的響應(yīng)式(值響應(yīng)第一層)
  • shallowRef:只有重新復(fù)制時(shí)才是響應(yīng)式(不響應(yīng)內(nèi)部數(shù)據(jù),只響應(yīng)整體。)

2.11-readonly與shallowReadonly

  • 他們表示只讀代理對(duì)象
  • readonly
    • 深度只讀
    • 設(shè)置readonly后,修改響應(yīng)式數(shù)據(jù)會(huì)報(bào)錯(cuò)。
  • shalloReadonly
    • 淺只讀
    • 設(shè)置shalloReadonly后,修改響應(yīng)式數(shù)據(jù)的第一層數(shù)據(jù)會(huì)報(bào)錯(cuò)。
  • 應(yīng)用場(chǎng)景:
    • 在某些特定情況下,我們可能不希望對(duì)數(shù)據(jù)進(jìn)行更新的操作,那就可以包裝成一個(gè)只讀代理對(duì)象,而不能修改或刪除。

2.12-toRaw與markRaw

  • toRaw
    • 返回reactive或readonly對(duì)象的原始數(shù)據(jù)
    • 這是一個(gè)還原方法,可用于臨時(shí)讀取,得到的數(shù)據(jù)不具有響應(yīng)式。
  • markRow:
    • 標(biāo)記一個(gè)對(duì)象,使其不具有響應(yīng)式
    • 應(yīng)用場(chǎng)景:
      • 有些只不應(yīng)被設(shè)置為響應(yīng)式的,例如復(fù)雜的第三方實(shí)例或Vue組件對(duì)象。
      • 當(dāng)渲染具有不可變數(shù)據(jù)源的大列表時(shí),跳過代理轉(zhuǎn)換可以提高性能。

2.13-toRef

  • 為響應(yīng)式對(duì)象上的某個(gè)屬性創(chuàng)建一個(gè)ref引用,更新是應(yīng)用對(duì)象會(huì)同步更新。
  • 與ref的區(qū)別:ref是拷貝了一份新的數(shù)據(jù)指單獨(dú)操作,更新時(shí)相互不影響。

2.14-customRef

  • 用于自定義一個(gè)ref,可以顯示的控制依賴追蹤和觸發(fā)相應(yīng)。
  • 接受一個(gè)工廠函數(shù),兩個(gè)參數(shù)分別用于追蹤的track與用于觸發(fā)相應(yīng)的trigger,并方法一個(gè)帶有g(shù)et和set屬性的對(duì)象。
  • 需求:使用customRef實(shí)現(xiàn)防抖函數(shù)

2.15-provide與inject

  • provide和inject提供依賴注入,功能類似2.0的provide/inject
  • 實(shí)現(xiàn)跨層級(jí)組件(祖孫)間通信。

2.16-響應(yīng)式數(shù)據(jù)的判斷

  • isRef:檢查一個(gè)值是否為一個(gè)ref對(duì)象。
  • isReactive:檢查一個(gè)對(duì)象是否否是由reactive對(duì)象的響應(yīng)式代理。
  • isReadonly:檢查一個(gè)對(duì)象是否由readonly創(chuàng)建的只讀代理。
  • isProxy:檢查一個(gè)對(duì)象是否是由reactive或者readonly方法創(chuàng)建的代理。

2.17-Fragment(片段)

  • 在vue2中:組件中必須有一個(gè)跟標(biāo)簽
  • 在vue3中:組價(jià)可以沒有跟標(biāo)簽,內(nèi)部會(huì)將多個(gè)標(biāo)簽包含在一個(gè)Fragment虛擬標(biāo)簽中。
    • 好處:減少標(biāo)簽層級(jí),減小內(nèi)存占用

2.18-Teleport(瞬移)

  • Teleport提供了一種干凈的方法,讓組件的html在父組件界面外的特定標(biāo)簽(很可能是body)下插入顯示。

2.19-Suspense(不確定的)

Supense組件是配合一部組件使用的,它可以讓一部組件返回?cái)?shù)據(jù)前渲染一些后背內(nèi)容。
那我們首先要學(xué)會(huì)一個(gè)異步組件。

  • 在setup函數(shù)總返回一個(gè)promise,就是一個(gè)異步組件。
  • setup函數(shù)攜程async函數(shù),也是一個(gè)異步組件。

2.20-其他新的API

  • 全新的全局API:
    • createApp()
    • defineProperty()
    • defineComponent()
    • nextTick()
  • 將原來的全局API轉(zhuǎn)移到應(yīng)用對(duì)象:
    • app.component()
    • app.config()
    • app.directive()
    • app.mount()
    • app.umount()
    • app.use()

2.21-useSlots和useAttrs

useSlots 和 useAttrs 是真實(shí)的運(yùn)行時(shí)函數(shù),它會(huì)返回與 setupContext.slots 和 setupContext.attrs 等價(jià)的值,同樣也能在普通的組合式 API 中使用。
使用場(chǎng)景:父組件使用子組件的插槽

1.父組件

<template>
  <h1>這是父組件</h1>

  <p>插槽上面1</p>
  <slots-attrs msg="我是props的msg" heihei="我是attr">
    <template #header >
      <div style="width:100%;height:100px;border:1px solid green;">我是父組件插槽--插入的內(nèi)容。。。</div>
    </template>
  </slots-attrs>
  <p>插槽下面2</p>

</template>

<script lang="ts" setup>
import SlotsAttrs from '@/components/04/SlotsAttrs.vue'

</script>

2.子組件

<template>
  <Child ref="child"/>

  {{msg}}
</template>


<script lang="ts" setup>
import { ref,onMounted } from 'vue';
import Child from '@/components/03/Child.vue'


const child = ref(null);
const msg=ref('')




onMounted(()=>{
  console.log("進(jìn)來了")
  console.log(child.value.msg)
  msg.value = child.value.msg;
})

</script>

三、路由

(1)userRout:獲得當(dāng)前路由對(duì)象。
(2)useRouter:獲得路由實(shí)例,可以進(jìn)行路由跳轉(zhuǎn)。

import {useRoute,useRouter} from "vue-router"

四、Vue3+TS實(shí)戰(zhàn)知識(shí)點(diǎn)

1.1-引入ElementPlus

(1)輸入命令安裝(全局引入)。

npm install element-plus --save

(2)【main.ts】文件中配置

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(ElementPlus)

1.2-引入axios

(1)輸入命令安裝。

npm install axios

(2)新建一個(gè)【http.ts】文件,寫一個(gè)簡(jiǎn)單的請(qǐng)求封裝。
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦

//導(dǎo)入axios
import axios from "axios"

//axios.create創(chuàng)建一個(gè)axios實(shí)例
//我們給這個(gè)實(shí)例編寫配置,后端所有通過這個(gè)實(shí)例發(fā)送請(qǐng)求,都受這個(gè)配置約束。
const $http=axios.create({
    baseURL:"http://jsonplaceholder.typicode.com/",
    timeout:1000
});



// 添加請(qǐng)求攔截器
$http.interceptors.request.use(function (config) {
    // 在發(fā)送請(qǐng)求之前做些什么
    return config;
  }, function (error) {
    // 對(duì)請(qǐng)求錯(cuò)誤做些什么
    return Promise.reject(error);
  });



// 添加響應(yīng)攔截器
$http.interceptors.response.use(function (response) {
    // 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么
    return response.data;
  }, function (error) {
    // 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么
    return Promise.reject(error);
  });

export default $http;

(3)新建一個(gè)【test.ts】文件進(jìn)行二次封裝。

import $http from "./http"

export const getData=$http.get("/posts");

(3)使用。

<script lang="ts">
import { defineComponent } from 'vue';
import {getData} from "@/apis/test"

export default defineComponent({
  name: 'Home',
  setup(){
      //請(qǐng)求接口
      getData.then((data:any)=>{
        console.log(data);
      })

      return{

      }
    }
});
</script>

1.3-引入vuex

(1)輸入命令安裝vuex

npm install vuex

(2)在【main.ts】中引入。

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'

createApp(App).use(store).mount('#app')

(3)在src文件夾下新建一個(gè)【store/index.ts】文件

import { createStore } from 'vuex'
import app from "./modules/app"
import settings from "./modules/settings"
import user from "./modules/user"

export default createStore({
  // 導(dǎo)入模塊
  modules: {
    app,
    settings,
    user
  }
})

(4)【app.ts】格式如下。

//【應(yīng)用程序模塊】
const app={
  //單一狀態(tài)樹,UI可通過this.$store.state.app.*獲得數(shù)據(jù)
  state: {

  },
  //對(duì)state數(shù)據(jù)進(jìn)行過濾后返回(可以認(rèn)為是 store 的計(jì)算屬性)
  getters:{

  },
  // 唯一擁有更改內(nèi)存數(shù)據(jù)的接口,不可進(jìn)行異步操作
  mutations: {

  },
  // 與mutation通訊,UI層寫入內(nèi)存數(shù)據(jù)的接口,可異步操作
  actions: {

  }
}
export default app;

1.4-引入.env

(1)創(chuàng)建文件xxx.env文件。
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦

----------------【.env.development】---------------
#以下的值webpack會(huì)根據(jù)不同的環(huán)境取得不同的值,使用方法:process.env.*
#設(shè)定一個(gè)標(biāo)題,代表這個(gè)環(huán)境是development
NODE_ENV = 'development'

# Base URL
BASE_URL = 'http://xxx:7881' 

# Base API
VUE_APP_BASE_API = 'http://xxx:7881'



----------------【.env.production】---------------
#以下的值webpack會(huì)根據(jù)不同的環(huán)境取得不同的值,使用方法:process.env.*
#設(shè)定一個(gè)標(biāo)題,代表這個(gè)環(huán)境是production
NODE_ENV = 'production'

# Base URL
BASE_URL = 'http://xxx:7881'

# Base API
VUE_APP_BASE_API = 'http://xxx:7881'


----------------【.env.staging】---------------
#以下的值webpack會(huì)根據(jù)不同的環(huán)境取得不同的值,使用方法:process.env.*
#設(shè)定一個(gè)標(biāo)題,代表這個(gè)環(huán)境是development
NODE_ENV = 'development'

# Base URL
BASE_URL = 'http://xxx:7881'

# Base API
VUE_APP_BASE_API = 'http://xxx:7881'

(2)使用。

process.env.VUE_APP_BASE_API

快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦


1.5-引入cookie

(1)安裝。

npm install vue-cookies --save


1.6-引入nprogress

(1)安裝。

npm install nprogress -S
npm i @types/nprogress-D

(2) 現(xiàn)在我們對(duì)NProgress進(jìn)行一下簡(jiǎn)單的封裝,首先我們?cè)凇綾ommon/utils/nporgress.ts】目錄下創(chuàng)建文件,然后引入NProgress和CSS樣式文件 。
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦
(3)內(nèi)容如下。

import NProgress from 'nprogress' // 進(jìn)度條
import 'nprogress/nprogress.css' // 進(jìn)度條樣

//全局進(jìn)度條的配置
NProgress.configure({
  easing: 'ease', // 動(dòng)畫方式
  speed: 1000, // 遞增進(jìn)度條的速度
  showSpinner: false, // 是否顯示加載ico
  trickleSpeed: 200, // 自動(dòng)遞增間隔
  minimum: 0.3, // 更改啟動(dòng)時(shí)使用的最小百分比
  parent: 'body', //指定進(jìn)度條的父容器
})

//打開進(jìn)度條
export const start =()=>{
  NProgress.start();
}

//關(guān)閉進(jìn)度條
export const close =()=>{
  NProgress.done();
}

(4)在【router/index.ts】文件中使用

--引入文件
import { close, start } from '@/common/utils/nprogress'//進(jìn)度條

--使用
const router = createRouter({
  routes,
  history: createWebHistory(),
})
 
router.beforeEach((pre, next) => {
  start()
})
 
router.afterEach(() => {
  close()
})

1.7-引入Element Plus(按需自動(dòng)引入)

環(huán)境:
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦
參考文獻(xiàn):https://www.yisu.com/zixun/723540.html

(1)輸入命令安裝

npm?install?element-plus
npm?install?-D?unplugin-vue-components?unplugin-auto-import

(2)在【vue.config.ts】中配置。

const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')


// 【每次修改,都需要重新build】
// 插件(module.exports={configureWebpack:[]})
    plugins: [
      AutoImport({
        resolvers: [ElementPlusResolver()]
      }),
      Components({
        resolvers: [ElementPlusResolver()]
      })
    ],

(3)然后執(zhí)行【npm run dev】報(bào)錯(cuò)了(如果報(bào)node-sass將這個(gè)卸載,安裝sass即可)。
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦
解決: 卸載nodev12,更新到nodev16在重新構(gòu)建一下項(xiàng)目成功解決 了。
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦

命令:
npm uninstall node-sass --dev-S
npm install sass --dev-S


1.8-引入sross-env環(huán)境變量配置

(1)安裝。

npm i --save-dev cross-env
npm install dotenv-cli --dev-s

(2)創(chuàng)建文件。
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦

--【.env.dev.build】
#以下的值webpack會(huì)根據(jù)不同的環(huán)境取得不同的值,使用方法:process.env.*
#設(shè)定一個(gè)標(biāo)題,代表這個(gè)環(huán)境是development
NODE_ENV = production

# Base URL
BASE_URL = 'http://xxx.xxx.xxx:7881' 

# Base API
VUE_APP_BASE_API = 'http://xxx.xxx.xxx:7990'

# 統(tǒng)一認(rèn)證中心配置
VUE_APP_AUTH_BASEURL = 'http://xxx.xxx.xxx:5021'
VUE_APP_AUTH_LOGIN_RRDIRECTURL = 'http://xxx.xxx.xxx:7881/callback'
VUE_APP_AUTH_LOGOUT_RRDIRECTURL = 'http://xxx.xxx.xxx:7881'


--【.env.dev.serve】
#以下的值webpack會(huì)根據(jù)不同的環(huán)境取得不同的值,使用方法:process.env.*
#設(shè)定一個(gè)標(biāo)題,代表這個(gè)環(huán)境是development
NODE_ENV = development

# Base URL
BASE_URL = 'http://xxx.xxx.xxx:7881' 

# Base API
VUE_APP_BASE_API = 'http://xxx.xxx.xxx:7990'

# 統(tǒng)一認(rèn)證中心配置
VUE_APP_AUTH_BASEURL = 'http://xxx.xxx.xxx:5021'
VUE_APP_AUTH_LOGIN_RRDIRECTURL = 'http://localhost:7881/callback'
VUE_APP_AUTH_LOGOUT_RRDIRECTURL = 'http://localhost:7881'

(3) 【package.json】中的配置

 "scripts": {
    "dev": "npm run serve:dev",
    "start": "npm run serve:dev",
    "server": "npm run serve:dev",
    "build": "npm run build:dev",
    "serve:dev": "cross-env NODE_ENV=development dotenv -e .env.dev.serve vue-cli-service serve",
    "build:dev": "cross-env NODE_ENV=production  dotenv -e .env.dev.build vue-cli-service build",
    "serve:test": "cross-env NODE_ENV=development dotenv -e .env.test.serve vue-cli-service serve",
    "build:test": "cross-env NODE_ENV=production  dotenv -e .env.test.build vue-cli-service build",
    "serve:prod": "cross-env NODE_ENV=development dotenv -e .env.prod.serve vue-cli-service serve",
    "build:prod": "cross-env NODE_ENV=production  dotenv -e .env.prod.build vue-cli-service build",
    "lint": "vue-cli-service lint"
  },

1.9-引入js-cookie

(1)安裝

npm install js-cookie -s
npm install @types/js-cookie --dev-s

(2)封裝單獨(dú)的ts文件。

import Cookies from 'js-cookie'

/*
封裝操作Cookie本地存儲(chǔ)的方法:
說明:主要用途有保存登錄信息。
存儲(chǔ)大?。?KB
*/
const cookies = {
  /**
   *設(shè)置Cookies
   * @param {String} key 鍵
   * @param {Object} value 值:存儲(chǔ)的值可能是數(shù)組/對(duì)象,不能直接存儲(chǔ),需要轉(zhuǎn)換 JSON.stringify()
   * @param {Int} expiresTime 過期時(shí)間(單位:秒)
   */
  set(key: string, value: any, expiresTime: number) {
    expiresTime=arguments[2] ? arguments[2] : (60*60)*24;//默認(rèn)值為:24小時(shí)
    let expires = new Date(new Date().getTime() * 1 + expiresTime * 1000);
    return Cookies.set(key, value, {
      expires: expires
    });
  },

  /**
   * 獲得Cookies
   * @param {String} key 鍵
   * @return {Object} 根據(jù)鍵取對(duì)應(yīng)的值
   */
  get(key: string) {
    return Cookies.get(key);
  },

  /**
   * 刪除Cookies
   * @param {String} key 鍵
   */
  remove(key: string) {
    return Cookies.remove(key);
  }
};

export default cookies;


1.10-引入el-plus面包屑導(dǎo)航

(1)安裝

npm install path-to-regexp -s

(2)寫代碼。

<template>
  <el-breadcrumb class="app_breadcrumb" separator="/">
    <transition-group name="breadcrumb">
      <el-breadcrumb-item v-for="(item,index) in breadcrumbs" :key="item.path">
        <span v-if="
          item.path === ' ' ||
          item.path === '/' ||
          item.path === '-' ||
          item.redirect === 'noredirect' ||
          index == breadcrumbs.length - 1" class="no_redirect">
          {{item.meta.title}}
        </span>
        <a v-else @click.prevent="handleLink(item)">{{item.meta.title}}</a>
      </el-breadcrumb-item>
    </transition-group>
  </el-breadcrumb>
</template>

<script lang="ts" setup>
import { compile } from 'path-to-regexp'
import { useRouter, useRoute, RouteLocationMatched } from 'vue-router'
import { onBeforeMount, reactive, toRefs, watch } from 'vue'

const route = useRoute();
const router = useRouter();

const pathCompile = (path: string) => {
  const { params } = route;
  const toPath = compile(path);
  return toPath(params);
}

const state = reactive({
  // 面包屑路由
  breadcrumbs: [] as Array<RouteLocationMatched>,

  // 獲得面包屑路由
  getBreadcrumb: () => {
    let matched = route.matched.filter((item: RouteLocationMatched) => {
      return item.meta && item.meta.title;
    });
    const first = matched[0];
    if (!state.isIndex(first)) {
        matched = [{ path: '/index', meta: { title: '首頁' } } as any].concat(matched);
    }
    state.breadcrumbs = matched.filter(
      (item) => item.meta && item.meta.title
    );
  },

  // 判斷是不是首頁
  isIndex: (route: RouteLocationMatched):boolean => {
    const name = route && route.name;
    if (!name) {
      return false;
    }
    return (
      name.toString().trim().toLocaleLowerCase() === "Index".toLocaleLowerCase()
    );
  },

  // 跳轉(zhuǎn)路由
  handleLink(item: any){
    const { redirect, path } = item;
    if (redirect) {
      router.push(redirect).catch((err) => {
        console.warn(err);
      })
      return
    }
    router.push(pathCompile(path)).catch((err) => {
      console.warn(err);
    })
  }
});

// 加載
onBeforeMount(() => {
  state.getBreadcrumb();
})

// 監(jiān)聽路由變化
watch(() => route.path, (path: string) => {
  if (path.startsWith('/redirect/')) {
    return;
  }
  state.getBreadcrumb();
})

const { breadcrumbs, handleLink } = toRefs(state);
</script>

<style lang="scss" scoped>
.app_breadcrumb.el-breadcrumb{
  font-size: 14px;
  line-height: 42px;
  height:42px;

  .el-breadcrumb__inner,
  .el-breadcrumb__inner a {
    font-weight: 400 !important;
  }

  .no_redirect{
    color: #c0c4cc;
    cursor: text;
  }
}
</style>

(3)引入組件。

 <breadcrumb class="breadcrumb_container" />

1.11-封裝http請(qǐng)求【axios-mapper】

(1)安裝需要的依賴

npm install @types/qs
npm install qs

(2)創(chuàng)建【types.ts】
快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦

// 請(qǐng)求內(nèi)容類型
export enum ContentType {
  form = 'application/x-www-form-urlencoded',
  json = 'application/json; charset=utf-8',
  multipart = 'multipart/form-data'
}

// 請(qǐng)求方式
export enum Method {
  GET = 'GET',
  POST = 'POST',
  PUT = 'PUT',
  PATCH = 'PATCH',
  DELETE = 'DELETE'
}

// 網(wǎng)絡(luò)請(qǐng)求參數(shù)
export interface RequestParams {
  [key: string]: any
}

(3)創(chuàng)建【convert-model.ts】文件。

// Json-Model相互轉(zhuǎn)換
export class ConvertModel {
  /**
   * @description:  json轉(zhuǎn)model
   * @param {string} json
   * @return {*}
   */
  public static jsonToModel<T>(json: string): T {
    return JSON.parse(json) as T;
  }

  /**
   * @description: model轉(zhuǎn)json
   * @param {any} model
   * @return {*}
   */
  public static modelToJson(model: any): string {
    return JSON.stringify(model);
  }
}

(4)創(chuàng)建【index.ts】文件

import { RequestParams, Method, ContentType } from './types';
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { ConvertModel } from './convert-model';

// 導(dǎo)出所有的類型
export * from './types';

export interface HttpClientConfig extends AxiosRequestConfig {
  defaultParams?: RequestParams;
}

// 導(dǎo)出默認(rèn)請(qǐng)求
export default class HttpClient {
  private _defaultConfig: HttpClientConfig;
  public httpClient: AxiosInstance;

  // 構(gòu)造函數(shù)
  constructor(options: HttpClientConfig = {}){
    this.httpClient = axios.create(options);
    this._defaultConfig = options;
  }

  /**
   * @description: 封裝請(qǐng)求類
   * @param {string} path 請(qǐng)求路徑 
   * @param {Method} method 請(qǐng)求方式(默認(rèn):GET)
   * @param {RequestParams} params 參數(shù)
   * @param {ContentType} contentType http配置
   * @param {HttpClientConfig} optionsSource
   * @return {*}
   */
  async request<T>(
    path: string = '',
    method: Method = Method.GET,
    params?: RequestParams,
    contentType: ContentType = ContentType.json,
    optionsSource?: HttpClientConfig
  ):Promise<T> {
    const options: any = Object.assign(
      {},
      this._defaultConfig,
      optionsSource
    );

    const { headers } = options;
    headers['content-type'] = contentType;

    const allParams = Object.assign(
      {},
      this._defaultConfig.defaultParams,
      params
    );

    // 發(fā)送請(qǐng)求
    const requestConfig: HttpClientConfig = {
      url: `${path}`,
      method,
      headers,
    };

    if(contentType === ContentType.form) {
      requestConfig.params = allParams;
    } else {
      requestConfig.data =  ConvertModel.modelToJson(allParams);
    }

    return this.httpClient.request(requestConfig)
    .then(res => {
      const data: string = ConvertModel.modelToJson(res.data);
      if (res.status >= 200 && res.status < 300) {
        return ConvertModel.jsonToModel(data) as T;
      } else {
        return Promise.reject(data);
      }
    })
    .catch(async error => {
      return Promise.reject(error);
    })
  };

  // GET請(qǐng)求
  get(url: string, params?: any) {
    return this.httpClient.request({
      url: url,
      method: Method.GET,
      params
    });
  };

  // POST請(qǐng)求
  post(url: string, data?: any) {
    return this.httpClient.request({
      url: url,
      method: Method.POST,
      data
    });
  };

  // PUT請(qǐng)求
  put(url: string, data?: any) {
    return this.httpClient.request({
      url: url,
      method: Method.PUT,
      data
    });
  };

  // Delete請(qǐng)求
  del (url: string, params?: any) {
    return this.httpClient.request({
      url: url,
      method: Method.DELETE,
      params
    });
  };

  // Delete批量請(qǐng)求(Post方式傳參)
  del_batch(url: string, data?: any) {
    return this.httpClient.request({
      url: url,
      method: Method.DELETE,
      data
    });
  }
}

(5)使用,封裝【https.ts】請(qǐng)求。

import HttpClient, { HttpClientConfig } from '../kimi-axios/index';
import { ElMessage } from 'element-plus';
import { getApiUrl, getToken } from './utils';

const config: HttpClientConfig = {
  baseURL: getApiUrl(),
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  },
  timeout: 60 * 1000 // 請(qǐng)求超時(shí)時(shí)間(默認(rèn):60秒)
};

const https = new HttpClient(config);
// 請(qǐng)求攔截器
https.httpClient.interceptors.request.use(
  config => {
    // 在發(fā)送請(qǐng)求之前做些什么...
    console.log('https:請(qǐng)求攔截器...');

    // // 如果存在Token,讓請(qǐng)求攜帶令牌。
    // var curTime = new Date()
    // var expiretime = new Date(Date.parse(storeTemp.state.user.tokenExpire))
    // // 判斷是否存在token,如果存在的話,則每個(gè)http header都加上token
    // if (storeTemp.state.user.token && (curTime < expiretime && storeTemp.state.user.tokenExpire)) {
    //   //['Authorization']是一個(gè)自定義頭密鑰,請(qǐng)根據(jù)實(shí)際情況進(jìn)行修改。
    //   config.headers['Authorization'] = 'Bearer ' + storeTemp.state.user.token;
    // }

    // ['Authorization']是一個(gè)自定義頭密鑰,請(qǐng)根據(jù)實(shí)際情況進(jìn)行修改。
    // config.headers['Authorization'] = 'Bearer ' + store.state.user.kimiToken;
    config.headers = {
      Authorization: `Bearer ${getToken()}`
    };

    return config;
  },
  error => {
    // 處理請(qǐng)求錯(cuò)誤...
    return Promise.reject(error);
  }
);

// 響應(yīng)攔截器
https.httpClient.interceptors.response.use(
  /**
 * 如果您想獲取http信息,如標(biāo)題或狀態(tài)
 * 請(qǐng)返回response=>response
 */
  /**
 * 通過自定義代碼確定請(qǐng)求狀態(tài)
 * 這里只是一個(gè)例子
 * 您還可以通過HTTP狀態(tài)代碼來判斷狀態(tài)
 */
  response => {
    // 自定義錯(cuò)誤
    // if(!response.data.success){
    //   Message({
    //     message: response.data.error.message,
    //     type: 'error',
    //     duration: 2 * 1000
    //   })
    // }

    console.log('https:響應(yīng)攔截器...');
    const res = response;
    return res;
  },
  error => {
    let statusCode = 0;
    try {
      statusCode = error.response.status;
    } catch (e) {
      // 網(wǎng)絡(luò)請(qǐng)求錯(cuò)誤
      if (error.toString().indexOf('Error: Network Error') !== -1) {
        ElMessage({
          message: '您的請(qǐng)求網(wǎng)絡(luò)發(fā)生錯(cuò)誤,請(qǐng)稍后重試!',
          type: 'error',
          duration: 2 * 1000
        });
        return Promise.reject(error);
      }
    }

    // 超時(shí)請(qǐng)求處理
    var originalRequest = error.config;
    if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1 && !originalRequest._retry) {
      ElMessage({
        message: '您的請(qǐng)求超時(shí),請(qǐng)稍后重試!',
        type: 'error',
        duration: 2 * 1000
      });
      originalRequest._retry = true;
      return Promise.reject(error);
    }

    // 根據(jù)狀態(tài)碼處理
    if (statusCode) {
      if (statusCode === 401) {
        // 401:未登錄
        ElMessage({
          message: '您當(dāng)前未登錄,請(qǐng)先登錄!',
          type: 'error',
          duration: 2 * 1000
        });
      } else if (statusCode === 403) {
        // 403:無權(quán)限
        ElMessage({
          message: '您訪問的權(quán)限等級(jí)不夠,拒絕訪問!',
          type: 'error',
          duration: 2 * 1000
        });
      } else if (statusCode === 429) {
        // 429:IP限流
        ElMessage({
          message: '您刷新次數(shù)過多,請(qǐng)稍后重試!',
          type: 'error',
          duration: 2 * 1000
        });
      } else if (statusCode === 500) {
        // 500:自動(dòng)錯(cuò)誤&&系統(tǒng)自定義錯(cuò)誤
        if (!error.response.data.success && error.response.data.result === 'error_constom') {
          ElMessage({
            message: error.response.data.error.message,
            type: 'error',
            duration: 2 * 1000
          });
        } else {
          ElMessage({
            message: '對(duì)不起,在處理您的請(qǐng)求期間,產(chǎn)生了一個(gè)服務(wù)器內(nèi)部錯(cuò)誤!',
            type: 'error',
            duration: 2 * 1000
          });
        }
      } else {
        // 其他
        let errorMsg = '';
        switch (statusCode) {
        case 400:
          errorMsg = '請(qǐng)求報(bào)文中存在語法錯(cuò)誤!';
          break;
        case 404:
          errorMsg = '服務(wù)器找不到請(qǐng)求的接口!';
          break;
        case 405:
          errorMsg = '請(qǐng)求類型出錯(cuò)!';
          break;
        case 408:
          errorMsg = '請(qǐng)求超時(shí)!';
          break;
        case 415:
          errorMsg = '請(qǐng)重新登錄!';
          break;
        case 501:
          errorMsg = '服務(wù)未實(shí)現(xiàn)!';
          break;
        case 502:
          errorMsg = '服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無效響應(yīng)!';
          break;
        case 503:
          errorMsg = '服務(wù)不可用!';
          break;
        case 504:
          errorMsg = '服務(wù)器連接超時(shí)!';
          break;
        case 505:
          errorMsg = 'HTTP版本不受支持!';
          break;
        default:
          errorMsg = '其他錯(cuò)誤!';
        }
        ElMessage({
          message: errorMsg,
          type: 'error',
          duration: 3 * 1000
        });
      }
    } else {
      ElMessage({
        message: '您的接口請(qǐng)求失敗,請(qǐng)稍后重試!',
        type: 'error',
        duration: 2 * 1000
      });
    }
    return Promise.reject(error);
  }
);

export default https;

1.12-引入全局loading

(1)element-plus需要在【main.ts】中先單獨(dú)引入loading樣式。

// 引入loading樣式
import 'element-plus/theme-chalk/el-loading.css';

(2)新建【loading.ts】文件全局使用。

// 【全局 Loading】:以服務(wù)的方式調(diào)用的全屏 Loading 是單例的。
import { ElLoading } from 'element-plus'

export default function() {
  const loading = (title: string) => {
    const loadingInstance = ElLoading.service({ 
      lock: true,
      text: title,
      background: 'rgba(0, 0, 0, 0.7)',
    });
    return loadingInstance;
  };

  return {
    loading
  }
}

(3)使用。

// 導(dǎo)入
import Loading from '@/utils/loading';

//啟用
const loadingInstance = loading('登錄中...');

//關(guān)閉
loadingInstance.close();

原創(chuàng)地址:https://www.cnblogs.com/kimiliucn/p/17605624.html文章來源地址http://www.zghlxwxcb.cn/news/detail-646911.html

到了這里,關(guān)于快速掌握Vue3:速成Vue3前端開發(fā)看這篇就夠啦的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Git、GitHub、Gitee快速上手,看這篇就夠了

    Git、GitHub、Gitee快速上手,看這篇就夠了

    ? 目錄 第1章? Git 概述 1.1 何為版本控制 1.2 為什么需要版本控制 1.3 版本控制工具 1.4 Git 簡(jiǎn)史 ? 1.5 Git 工作機(jī)制 ? 1.6 Git 和代碼托管中心 第2章 Git 安裝 第 3 章 Git 常用命令 3.1 設(shè)置用戶簽名 3.2 初始化本地庫 3.3 查看本地庫狀態(tài) ? 3.3.1 首次查看(工作區(qū)沒有任何文件) 3.3.2 新

    2024年02月03日
    瀏覽(53)
  • C入門語言看這篇就夠了,教你快速上手C語言

    C入門語言看這篇就夠了,教你快速上手C語言

    ??哈嘍,各位鐵汁們好??!?今天來給大家?guī)淼氖浅踝R(shí) C語言 里面的 轉(zhuǎn)義字符 和 注釋 。 ??《入門C語言篇》主要帶大家簡(jiǎn)單認(rèn)識(shí)-一下C語言,俗話說 沒吃過豬肉,也見過豬跑。 帶大家了解下C語言??梢宰x懂C語言的簡(jiǎn)單程序,后面博主會(huì)給大家出《C語言初級(jí)》加進(jìn)階

    2024年02月13日
    瀏覽(21)
  • 快速掌握WebSocket:僅需10分鐘的速成教程!

    WebSocket是一種在客戶端和服務(wù)器之間實(shí)現(xiàn)雙向通信的網(wǎng)絡(luò)協(xié)議。它通過在單個(gè)TCP連接上提供全雙工通信功能,使得服務(wù)器可以主動(dòng)向客戶端推送數(shù)據(jù),而不需要客戶端發(fā)起請(qǐng)求。 與傳統(tǒng)的HTTP協(xié)議相比,WebSocket具有以下幾個(gè)顯著的區(qū)別: 雙向通信 :WebSocket支持客戶端和服務(wù)器

    2024年02月20日
    瀏覽(28)
  • 【vue3】13-前端路由-Vue-Router的詳解: 從入門到掌握

    【vue3】13-前端路由-Vue-Router的詳解: 從入門到掌握

    路由其實(shí)是網(wǎng)絡(luò)工程中的一個(gè)術(shù)語: 在 架構(gòu)一個(gè)網(wǎng)絡(luò) 時(shí),非常重要的兩個(gè)設(shè)備就是 路由器和交換機(jī) 。 當(dāng)然,目前在我們生活中 路由器 也是越來越被大家所熟知,因?yàn)槲覀兩钪卸紩?huì)用到 路由器 : 事實(shí)上, 路由器 主要維護(hù)的是一個(gè) 映射表 ; 映射表 會(huì)決定數(shù)據(jù)的流向; 路由

    2024年02月09日
    瀏覽(58)
  • uniapp Android原生插件開發(fā)和離線打包調(diào)試看這篇就夠了!(保姆級(jí)手把手教學(xué))

    uniapp Android原生插件開發(fā)和離線打包調(diào)試看這篇就夠了!(保姆級(jí)手把手教學(xué))

    此文章最適合第一次開發(fā)原生插件并且無原生開發(fā)經(jīng)驗(yàn)的攻城獅! uni-app 官方文檔地址:uni原生插件開發(fā)教程 原生插件必備離線SDK下載:Android 離線SDK - 正式版 要擁有JAVA環(huán)境 jdk1.8 版本,其他版本根據(jù)情況自我調(diào)整 想必讀者在看此文章之前電腦就有HBuilderX和Android Studio開發(fā)工

    2024年02月10日
    瀏覽(54)
  • Vue3+SpringBoot快速開發(fā)模板

    Vue3+SpringBoot快速開發(fā)模板

    起因:個(gè)人開發(fā)過程經(jīng)常會(huì)使用到Vue3+SpringBoot技術(shù)棧來開發(fā)項(xiàng)目,每次在項(xiàng)目初始化時(shí)都需要涉及一些重復(fù)的整理工作,于是結(jié)合一些個(gè)人覺得不錯(cuò)的前后端模板進(jìn)行整合,打通一些大多數(shù)項(xiàng)目都需要的實(shí)現(xiàn)的基礎(chǔ)功能,以便于快速開發(fā)項(xiàng)目。代碼已按個(gè)人力所能及的規(guī)范編

    2024年02月14日
    瀏覽(25)
  • 【前端開發(fā)工具】VUE3 devtools安裝

    【前端開發(fā)工具】VUE3 devtools安裝

    尤雨溪在2020年9月19日晚正式發(fā)布vue3.0 one piece。此版本相較于vue2版本,更快、更小、更易維護(hù)、更易于原生、讓開發(fā)者更輕松;所以學(xué)習(xí)vue3,對(duì)于一個(gè)前端開發(fā)者來說是一個(gè)刻不容緩的學(xué)習(xí)趨勢(shì)。 學(xué)習(xí)vue3自然也離不開debug啦~~ Vue官方發(fā)布了調(diào)試工具Vue-Devtools。 VUE3的Vue-Devt

    2024年02月05日
    瀏覽(91)
  • 從Vue2到Vue3, 一鍵升級(jí)前端開發(fā)技能

    本文的目的,是為了讓已經(jīng)有 Vue2 開發(fā)經(jīng)驗(yàn)的 ? 人 ? ,快速掌握 Vue3 的寫法。 因此, ? 本篇假定你已經(jīng)掌握 Vue 的核心內(nèi)容 ? ,只為你介紹編寫 Vue3 代碼,需要了解的內(nèi)容。 首先,Vue3 新增了一個(gè)叫做組合式 api 的東西,英文名叫 Composition API 。因此 Vue3 的? script ?現(xiàn)在支

    2024年02月08日
    瀏覽(26)
  • 「Vue|網(wǎng)頁開發(fā)|前端開發(fā)」01 快速入門:用vue-cli快速寫一個(gè)Vue的HelloWorld項(xiàng)目

    「Vue|網(wǎng)頁開發(fā)|前端開發(fā)」01 快速入門:用vue-cli快速寫一個(gè)Vue的HelloWorld項(xiàng)目

    本文主要介紹如何用vue開發(fā)的標(biāo)準(zhǔn)化工具vue-cli快速搭建一個(gè)符合實(shí)際業(yè)務(wù)項(xiàng)目結(jié)構(gòu)的hello world網(wǎng)頁項(xiàng)目并理解vue的代碼文件結(jié)構(gòu)以及頁面渲染流程。 Windows 系統(tǒng)的 node.js 安裝十分簡(jiǎn)易,沒有環(huán)境安裝經(jīng)驗(yàn)的伙伴可以參考文章:Windows系統(tǒng)下安裝node.js 我們需要先創(chuàng)建一個(gè)用于放

    2024年02月12日
    瀏覽(24)
  • Vue3前端開發(fā),computed計(jì)算屬性的基礎(chǔ)練習(xí)

    Vue3前端開發(fā),computed計(jì)算屬性的基礎(chǔ)練習(xí)

    Vue3前端開發(fā),computed計(jì)算屬性的基礎(chǔ)練習(xí)! 在新版里面,和傳統(tǒng)的vue2一樣,計(jì)算屬性,都是對(duì)一些數(shù)據(jù)運(yùn)算進(jìn)行了封裝操作。返回結(jié)果是一個(gè)實(shí)時(shí)監(jiān)控的效果。區(qū)別在于,寫法不同。效果是一樣。 下面給大家展示一個(gè)簡(jiǎn)單的案例。 如圖,自定義一個(gè)組件,ComputedDemo.vue。里

    2024年01月18日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包