一篇文章看懂Vue組合式API
一. 為什么要使用Composition API
1.1.一個Options API實例
在前面的課程中,我們都是采用 Options API(基于選項的 API ) 來寫一個組件的。下面是一個實例:
<template>
Count is: {{ count }}, doubleCount is: {{ doubleCount }}
<button @click="add">加</button>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
computed: {
doubleCount() {
return this.count * 2;
},
},
methods: {
add() {
this.count++;
}
}
}
</script>當要去理解一個組件時,我們更加關心的是:“這個組件是要干什么(即代碼背后的意圖)”,而不是:“這個組件用到了什么選項”。
Options API 撰寫出來的代碼自然采用了后者的表述方式,然而對前者的表述并不好。
1.2.Options API存在的問題
在 Options API 中實際上形成了一種強制的約定:
- props 里面設置接收參數
- data 里面設置變量
- computed 里面設置計算屬性
- watch 里面設置監(jiān)聽屬性
- methods 里面設置事件方法
我們會發(fā)現: Options API 都約定了我們該在哪個位置做什么事,這在一定程度上也強制我們進行了代碼分割。這就為展示背后的邏輯關注點設置了障礙。我們必須不斷地在選項代碼塊之間“跳轉”,以找到與該關注點相關的部分。
尤其是在大型組件中,數據與方法會很多,而數據與其相關聯的方法就會被其他數據和方法分隔的很遠,往往很難被看出它們之間的關聯。

這是一個大型組件的示例,其中邏輯關注點是按顏色分組。
這種碎片化使得理解和維護復雜組件變得困難。選項的分離掩蓋了潛在的邏輯問題。此外,在處理單個邏輯關注點時,我們必須不斷地“跳轉”相關代碼的選項塊。
如果我們能夠將與同一個邏輯關注點相關的代碼配置在一起,這樣會更好。而這正是組合式 API 使我們能夠做到的。
1.3.Composition API簡介
Composition API:組合式 API;一組低侵入式的、函數式的 API,使得我們能夠更靈活地【組合】組件的邏輯。
這是有別于 Options API 的一種函數式 API。無需通過很多選項來完成業(yè)務邏輯,Composition API提供了一個setup函數,我們可以將data數據、計算屬性、方法等等,都放在setup函數中,這樣就可以對業(yè)務進行集中處理了。
采用Composition API來重寫上面的組件:
<template>
Count is: {{ state.count }}, doubleCount is: {{ state.doubleCount }}
<button @click="add">加</button>
</template>
<script>
import { reactive, computed } from "vue";
export default {
setup() {
const state = reactive({
count: 0,
doubleCount: computed(() => state.count * 2),
});
function add() {
state.count++;
}
return {
state,
add
}
}
}
</script>還有一個 setup 函數,setup 函數是一個新的組件選項。作為在組件內使用 Composition API 的入口點,如果 setup 返回一個對象,則對象的屬性將會被合并到組件模板的渲染上下文,我們就可以在模板里使用對應的屬性和方法。
二.Composition API
2.1.setup()入口
setup 函數是一個新的組件選項,它是在組件內使用 Composition API 的入口點。它會在Vue實例創(chuàng)建完成前被調用。所以,setup函數中沒有this指針
<template>
<div></div>
</template>
<script>
export default {
setup() {
//這里書寫本地狀態(tài)(data數據)、計算屬性或方法等
console.log('setup函數');
}
}
</script>如果 setup 返回一個對象,則對象的屬性將會被合并到組件模板的渲染上下文,我們就可以在模板里使用對應的屬性和方法。所以,我們可以將本地狀態(tài)(data數據)、方法、計算屬性等寫在 setup 函數中。
<template>
Count is: {{ count }}
</template>
<script>
export default {
setup() {
let count = 10;
return {
count
}
}
}
</script>上面代碼中,在 setup 函數中聲明了一個 count 數據。然后使用 return 返回需要暴露的內容。運行之后可以看到:視圖能夠正確顯示count數據。
setup函數總結:
- setup函數是Composition API 的入口點,是它的核心。
- 由于執(zhí)行 setup 時,組件實例尚未被創(chuàng)建,因此在 setup 中不能使用 this。
- setup中定義的東西必須要return出去,才能被使用或綁定視圖。
2.2.ref 響應式監(jiān)聽
上面實例中,雖然視圖能夠顯示數據。但當改變數據時,視圖卻不會得到響應。
<template>
Count is: {{ count }}
<button @click="add">加</button>
</template>
<script>
export default {
setup() {
let count = 10;
function add(){
count++; //setup函數中沒有this指針
}
return {
count,
add
}
}
}
</script>原因很簡單,count只是聲明的一個普通數據,不具備響應功能。
在 Vue 3.0 中,我們可以通過一個 ref 函數來實現響應式數據監(jiān)聽。ref 接受一個參數,并將其包裹在一個帶有 value 屬性的對象中返回,然后可以使用該 value 屬性訪問或更改響應式變量的值:
<template>
Count is: {{ count }}
<button @click="add">加</button>
</template>
<script>
//注意:要導入ref
import {ref} from 'vue';
export default {
setup() {
let count = ref(10); //count成為響應式數據。
function add(){
count.value++; //使用value屬性獲取響應數據
}
return {
count,
add
}
}
}
</script>為什么要將值封裝在一個對象中,看似沒有必要,但為了保持 JavaScript 中不同數據類型的行為統(tǒng)一,這是必須的。因為在 JavaScript 中,Number 或 String 等基本類型是通過值傳遞的,而不是通過引用傳遞的:

2.3.reactive與toRefs
上面實例中,操作數據時需要使用 value 屬性,比較麻煩。
可以使用 reactive 與 toRefs 解決這個問題。首先使用 reactive 創(chuàng)建響應式對象,封裝數據。
<template>
<p>Count is: {{ state.count }}</p>
<button @click="add">加</button>
<p>{{ state.user.username }}</p>
</template>
<script>
//注意:要導入ref
import {reactive} from 'vue';
export default {
setup() {
//所有響應數據都聲明在這里,包括對象、數組
const state = reactive({
count: 10,
user:{
userId: 1,
username: '張三'
}
})
function add(){
state.count++; //這里可以不使用value了
}
return {
state,
add
}
}
}
</script>此時不用使用 value 屬性了。
但是因為只有state是響應式數據,而state中的那些數據還不是響應式的。所以在視圖訪問數據時都需要使用 state 作為前綴才可以。這就比較麻煩了。
此時我們可以使用 toRefs 進行優(yōu)化。toRefs可以將state中的每一個數據進行展開,且都包裝成響應數據。這樣視圖層就可以直接使用了。
<template>
<p>Count is: {{ count }}</p>
<button @click="add">加</button>
<p>{{ user.username }}</p>
</template>
<script>
//注意:要導入ref
import {reactive, toRefs} from 'vue';
export default {
setup() {
//所有響應數據都聲明在這里,包括對象、數組
const state = reactive({
count: 10,
user:{
userId: 1,
username: '張三'
}
})
function add(){
state.count++; //這里可以不使用value了
}
return {
...toRefs(state), //這里使用使用 ...toRefs(state)
add
}
}
}
</script>在返回時使用 ...toRefs(state) ,這樣視圖層就可以不使用 state 前綴了。
為什么要使用 ... 參數擴展運輸符呢?因為toRefs(state) 將state對象展開,并包裝成多個響應數據。
2.4.computed的用法
<template>
<p>Count is: {{ count }}</p>
<p>doubleCount is: {{ doubleCount }}</p>
<button @click="add">加</button>
<p>{{ user.username }}</p>
</template>
<script>
//注意:要導入ref
import { reactive, toRefs, computed } from "vue";
export default {
setup() {
//所有響應數據都聲明在這里,包括對象、數組
const state = reactive({
count: 10,
user: {
userId: 1,
username: "張三",
},
doubleCount: computed(() => { //使用computed函數
return state.count * 2;
}),
});
function add() {
state.count++; //這里可以不使用value了
}
return {
...toRefs(state),
add,
};
},
};
</script>首先要import導入computed。
在reactive({})中聲明computed即可。
到現在為止,響應式數據就都可以處理了。
2.5.watch的用法
<template>
<div>
{{ num }}
<button @click="add">加</button>
</div>
</template>
<script>
import { reactive, toRefs, watch } from "vue";
export default {
setup() {
const state = reactive({
num: 0,
});
watch(state,(newValue, oldValue) => {
console.log(newValue, oldValue);
}
);
function add() {
state.num++;
}
return {
...toRefs(state),
add,
};
},
};
</script>使用watch函數來進行數據監(jiān)聽。watch函數有兩個參數。
第一個參數:要監(jiān)聽的數據。
第二個參數:觸發(fā)監(jiān)聽時的處理函數(包括newValue, oldValue)
上面實例中直接監(jiān)聽state響應對象。但我們知道,在state中會有很多數據,如果只想監(jiān)聽其中的某個數據,就需要換一種寫法:
watch(() => state.num,(newValue, oldValue) => {
console.log(newValue, oldValue);
});第一個參數要寫成函數返回值的形式,這樣就能監(jiān)聽state響應對象中的某個數據了。
2.6.setup()參數
setup() 函數有兩個參數:props 和 context。
為什么要有這兩個參數呢?我們知道父子組件之間是可以傳值。但是現在我們的業(yè)務邏輯都寫在setup函數中,而setpu中沒有this指針,那么就只能靠這兩個參數來進行傳遞了。
- props:父組件向子組件傳值的參數。
- context:子組件向父組件傳值的參數。
2.6.1.props參數
setup() 函數的 props 是父組件向子組件傳值的參數。
在components文件夾中創(chuàng)建子組件(Hello.vue):
<template>
<div>我是子組件</div>
</template>
<script>
export default {
setup(props, context) {
console.log(props.msg)
},
props: {
msg: String,
},
};
</script>
<style>
</style>父組件(HomeView.vue):
<template>
<div>
<Hello msg="hello"></Hello>
</div>
</template>
<script>
import Hello from '../components/Hello.vue'
import { reactive, toRefs, computed } from "vue";
export default {
setup() {
const state = reactive({
});
return {
...toRefs(state),
};
},
components:{
Hello
}
};
</script>注意,要先import導入子組件,然后使用components掛載子組件。
2.6.2.context參數
setup() 函數的 context 是子組件向父組件傳值的參數。
子組件(Hello.vue):
<template>
<div>
<div>我是子組件</div>
<button @click="send">給父組件發(fā)數據</button>
</div>
</template>
<script>
export default {
setup(props, context) {
function send() {
context.emit("childmsg", "hello world!");
}
return {
send,
};
},
props: {
msg: String,
},
};
</script>
<style>
</style>父組件(HomeView.vue):
<template>
<div>
<Hello msg="hello" @childmsg="get"></Hello>
<p>我是父組件,接受子組件傳的值:{{welcome}}</p>
</div>
</template>
<script>
import Hello from '../components/Hello.vue'
import { reactive, toRefs, computed } from "vue";
export default {
setup() {
//所有響應數據都聲明在這里,包括對象、數組
const state = reactive({
welcome: ''
});
function get(param) {
state.welcome = param;
}
return {
...toRefs(state),
get
};
},
components:{
Hello
}
};
</script>三.Composition API的使用
下面我們會將前面學過的知識點都改寫為Composition API的形式。而且,Vue3兼容Options API和Composition API兩種寫法。所以這兩種寫法都要會。
3.1.provide與inject的使用
我們學過provide與inject可用于多級組件直接傳遞數據,下面學習provide與inject在Composition API中的使用。
創(chuàng)建孫子組件(SubHello.vue)
<template>
<div>
<div>我是孫組件</div>
</div>
</template>
<script>
import { inject } from "vue";
export default {
setup(props, context) {
console.log(inject('msg'))
return {};
}
};
</script>在孫子組件中import導入inject,并使用inject接收上級組件的傳值。
在子組件(Hello.vue)中使用孫子組件
<template>
<div>
<div>我是子組件</div>
<SubHello></SubHello>
</div>
</template>
<script>
import SubHello from './SubHello.vue'
export default {
setup(props, context) {
return {};
},
components:{
SubHello
}
};
</script>
<style>
</style>在父組件中使用provide給多級組件傳值
<template>
<div>
<Hello></Hello>
</div>
</template>
<script>
import Hello from "../components/Hello.vue";
import { provide } from "vue";
export default {
setup() {
provide('msg','hello');
},
components:{
Hello
}
};
</script>注意,由于父組件向孫子組件傳遞數據是單向的,所以孫子組件不能修改傳遞的值。如果子組件
3.2.vue生命周期的用法
在 setup () 內部調用生命周期鉤子:
選項式API | setup () 內部調用生命周期鉤子 |
beforeCreate() | setup() |
created() | setup() |
beforeMount() | onBeforeMount() |
mounted() | onMounted() |
beforeUpdate() | onBeforeUpdate() |
updated() | onUpdated() |
beforeUnmount() | onBeforeUnmount() |
unmounted() | onUnmounted() |
注意:在Composition API中沒有beforeCreate()和created()這里兩個聲明周期函數了,統(tǒng)一使用setup()。
實例:
<template>
<div>
{{ num }}
<button @click="add">加</button>
</div>
</template>
<script>
import { reactive,toRefs,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted } from "vue";
export default {
setup() {
const state = reactive({
num: 1,
});
function add() {
state.num++;
}
onBeforeMount(() => {
console.log("DOM掛載前!");
});
onMounted(() => {
console.log("DOM掛載后!");
});
onBeforeUpdate(() => {
console.log("數據更新前!");
})
onUpdated(() => {
console.log("數據更新后!");
})
onBeforeUnmount(() => {
console.log("實例卸載前!");
})
onUnmounted(() => {
console.log("實例卸載后!");
})
return {
...toRefs(state),
add,
};
},
};
</script>3.3.編程式路由的使用
下面學習如何在Composition API中使用路由。
打開App.vue組件,這里已經有了路由。當然,是使用router-link標簽來實現的?,F在我們將它改成編程式路由。
<template>
<nav>
<!--
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
-->
<button @click="toHome">Home</button>
<button @click="toAbout">About</button>
</nav>
<router-view />
</template>
<script>
import { useRouter } from "vue-router";
export default{
setup() {
const router = useRouter();
function toHome(){
router.push('/');
}
function toAbout(){
router.push({path:'/about',query:{name:'zhangsan'}});
}
return {
toHome,
toAbout
}
},
}
</script>先import導入useRouter模塊。
通過useRouter模塊獲取router對象。以后的路由寫法就與前面所學一樣了。
下面是獲取路由參數,打開AboutView.vue文件
<template>
<div>
</div>
</template>
<script>
import { useRoute } from "vue-router";
export default {
setup(){
const route = useRoute();
console.log(route.query.name);
}
}
</script>通過同樣的方式獲取route對象后就可以獲取路由參數了。
3.4.Vuex的使用
下面學習如何在Composition API中使用Vuex。
<template>
<div>
</div>
</template>
<script>
import { useStore } from "vuex";
export default {
setup() {
const store = useStore();
console.log(store.state.num);
console.log(store.getters.newnum);
}
};
</script>先import導入useStore模塊。
通過useStore模塊獲取store對象。就可以通過store對象獲取Vuex中的所有數據了。
3.5.獲取DOM的使用
前面我們知道在Vue中,可以使用ref來獲取DOM對象。下面學習如何在Composition API中使用ref。
<template>
<div ref="myRef">獲取單個DOM元素</div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
setup() {
const myRef = ref(null); //ref(null)是一個固定的寫法
onMounted(() => {
console.dir(myRef.value);
});
return {
myRef
};
}
};
</script>
- 在HTML標簽中使用 ref 屬性標識一個DOM對象。
- 需要 import 導入 ref 對象。
- 使用 const myRef = ref(null); 的方式獲取包裝好的DOM對象,命名為HTML中的 ref 屬性名。并且此數據需要暴露出去。
- 使用 value 屬性即可獲取 DOM對象。
四.使用Composition API重寫todoList
AddNew組件
<template>
<div>
<input type="text" v-model="newItem" />
<button @click="handleAdd">添加</button>
</div>
</template>
<script>
import {reactive, toRefs} from 'vue';
export default {
setup(props, context){
const state = reactive({
newItem: ""
})
function handleAdd() {
if (state.newItem == "") {
alert("不能為空");
return;
}
//注意:這里使用setup參數context來出發(fā)父組件事件
context.emit("submitNewItem", state.newItem);
state.newItem = "";
}
return {
...toRefs(state),
handleAdd
}
}
}
</script>TheList組件
<template>
<ol>
<li v-for="(item, index) in list" :key="index" @click="judgeItem(index)">
{{ item }}
</li>
</ol>
</template>
<script>
export default {
setup(props, context) {
//這里分別使用了setup的兩個參數
function judgeItem(index) {
if (props.listType) {
context.emit("handleDelete", index);
} else {
context.emit("handleJudge", index);
}
}
return {
judgeItem
};
},
props: {
list: {
type: Array,
required: true,
},
listType: {
type: Boolean,
default: false,
},
},
};
</script>TodoList組件
<template>
<div>
<h1>todoList</h1>
<AddNew @submitNewItem="addNewItem"></AddNew>
<TheList :list="todoList" @handleJudge="toDone"></TheList>
<hr />
<TheList :list="doneList" :listType="true" @handleDelete="toDelete"></TheList>
</div>
</template>
<script>
import AddNew from "../components/AddNew.vue";
import TheList from "../components/TheList.vue";
import {reactive, toRefs} from 'vue';
export default {
setup(){
const state = reactive({
todoList: [], //待辦事項
doneList: [] //完成事項
})
function addNewItem(newItem){
state.todoList.push(newItem);
}
function toDone(index){
state.doneList.push(state.todoList.splice(index,1)[0]);
}
function toDelete(index){
state.doneList.splice(index,1);
}
return {
...toRefs(state),
addNewItem,
toDone,
toDelete
}
},
components: {
AddNew,
TheList,
},
};
</script>五.setup語法糖
在Composition API中,在setup函數中聲明的數據、函數等內容,都需要通過 return 對外暴露,才能被組件的視圖模板(template)使用,這就造成了書寫上的不方便。于是,Vue官方又給我們推出了一個新的setup語法糖。
使用setup語法糖,就可以不用寫setup函數了。并且,數據和函數也不用返回,組件也不需要注冊了。
5.1.setup語法糖的基本結構
<template> </template> <script setup> //此處直接寫setup函數中的內容 </script> <style> </style>
- 在script標簽中使用setup屬性即可。
- 運行時,script標簽中的內容會被重新編譯成 setup() 函數的形式。
- 而且,聲明的數據、函數不需要通過 return 暴露,即可被 template所使用
5.2.響應數據的使用
<template>
<div>
<p>{{ num }}</p>
<button @click="add">加</button>
</div>
</template>
<script setup>
let num = 10;
//const num = 10;
//由于num不是響應數據,所以改變num是無效的。
const add = ()=>{
alert("觸發(fā)了此方法");
num++;
}
</script>直接聲明的數據不是響應式的,數據改變時不會響應到視圖模板中。
<template>
<div>
<p>{{ num }}</p>
<p>{{ dept.deptno }},{{ dept.dname }},{{ dept.loc }}</p>
<ul>
<li v-for="user in userArr" :key="user.userId">
{{user.userId}},{{user.userName}},{{user.userAge}}
</li>
</ul>
<button @click="add">加</button>
</div>
</template>
<script setup>
import { reactive, ref } from "vue";
const num = ref(10);
const dept = reactive({
deptno: 20,
dname: "技術部",
loc: '沈陽市',
});
const userArr = ref([
{
userId: 100,
userName: "張三",
userAge: 25,
},
{
userId: 101,
userName: "李四",
userAge: 26,
},
{
userId: 102,
userName: "王五",
userAge: 27,
},
]);
const add = () => {
num.value++; //注意:要使用value屬性獲取
dept.deptno++;
//userArr.value[0].userAge++;
userArr.value = [];
}
</script>ref 和 reactive 都可以做響應式數據,它們的區(qū)別如下:
- reactive:用于定義引用類型。只能修改數據,不能改變其引用。
- ref:用于定義基本類型和引用類型。可以修改數據,也可以改變其引用。
- 在方法中修改數據時需要使用 value屬性。因為,Ref的本質是通過Reactive創(chuàng)建的,Ref(10) 就相當于:Reactive({value:10});
- 在視圖模板調用可以省略value屬性的書寫。
5.3.其它語法的使用
下面例子演示了computed計算屬性、watch監(jiān)聽、生命周期函數的使用。
<template>
<div>
{{ num }}
{{ newNum }}
<button @click="add">add</button>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
const num = ref(10);
const newNum = computed(() => {
return num.value*2;
})
const add = ()=>{
num.value++;
}
watch(num,(newValue,oldValue)=>{
console.log(newValue,oldValue);
})
//生命周期函數
onMounted(() => {
console.log("DOM掛載后!");
});
</script>5.4.引入組件的使用
引入的組件不必注冊,可以直接使用。
<template>
<div class="home">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script setup>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
</script>5.5.父子組件傳值的使用
5.5.1.defineProps的使用
defineProps用于父組件向子組件傳值。
父組件
<template>
<div class="home">
<HelloWorld msg="Welcome to Your Vue.js App" :num="num"/>
</div>
</template>
<script setup>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
const num = 20
</script>子組件
<template>
<div class="hello">
<h1>{{ msg }},{{ num }}</h1>
</div>
</template>
<script setup>
//const myProps = defineProps(['msg','num']);
const myProps = defineProps({
msg:{
type: String
},
num:{
type: Number,
required: true
}
});
</script>
<style scoped>
</style>defineProps也可以有數組形式和對象形式兩種寫法。
5.5.2.defineEmits的使用
defineEmits用于子組件向父組件傳值。
父組件
<template>
<div class="home">
<HelloWorld
msg="Welcome to Your Vue.js App"
:num="num"
@childmsg="get"/>
</div>
</template>
<script setup>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
const num = 20;
const get = (value) => {
console.log(value)
}
</script>子組件
<template>
<div class="hello">
<h1>{{ msg }},{{ num }}</h1>
<button @click="send">給父組件傳值</button>
</div>
</template>
<script setup>
const myProps = defineProps(['msg','num']);
const emit = defineEmits(['childmsg']);
const send = () => {
emit('childmsg','子組件向父組件傳的值');
}
</script>
<style scoped>
</style>六.使用setup語法糖重寫todoList
AddNew組件
<template>
<div>
<input type="text" v-model="newItem" />
<button @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref } from "vue";
const newItem = ref("");
const emit = defineEmits(["submitNewItem"]);
const handleAdd = () => {
if (newItem.value == "") {
alert("不能為空");
return;
}
emit("submitNewItem", newItem.value);
newItem.value = "";
};
</script>TheList組件
<template>
<ol>
<li v-for="(item, index) in list" :key="index" @click="judgeItem(index)">
{{ item }}
</li>
</ol>
</template>
<script setup>
const emit = defineEmits(['handleDelete','handleJudge']);
const judgeItem = (index) => {
if (myProps.listType) {
emit("handleDelete", index);
} else {
emit("handleJudge", index);
}
};
const myProps = defineProps({
list: {
type: Array,
required: true,
},
listType: {
type: Boolean,
default: false,
},
});
</script>TodoList組件
<template>
<div>
<h1>todoList</h1>
<AddNew @submitNewItem="addNewItem"></AddNew>
<TheList :list="todoList" @handleJudge="toDone"></TheList>
<hr />
<TheList
:list="doneList"
:listType="true"
@handleDelete="toDelete"
></TheList>
</div>
</template>
<script setup>
import AddNew from "../components/AddNew.vue";
import TheList from "../components/TheList.vue";
import { reactive } from "vue";
const todoList = reactive([]); //待辦事項
const doneList = reactive([]); //完成事項
const addNewItem = (newItem) => {
todoList.push(newItem);
}
const toDone = (index) => {
doneList.push(todoList.splice(index, 1)[0]);
}
const toDelete = (index) => {
doneList.splice(index, 1);
}
</script>七. 總結
到此這篇關于Vue組合式API的文章就介紹到這了,更多相關Vue組合式API內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
axios無法加載響應數據:no?data?found?for?resource?with?given?i
最近在在做一個小查詢功能的時候踩了一個坑,所以這篇文章主要給大家介紹了關于axios無法加載響應數據:no?data?found?for?resource?with?given?identifier報錯的解決方法,需要的朋友可以參考下2022-11-11

