欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章看懂Vue組合式API

 更新時間:2023年04月07日 10:11:02   作者:Hulake_  
眾所周知組合式API是一系列API的集合,使我們可以使用函數(shù)而不是聲明選項的方式書寫Vue組件,這篇文章主要給大家介紹了關(guān)于Vue組合式API的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

一. 為什么要使用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>

當(dāng)要去理解一個組件時,我們更加關(guān)心的是:“這個組件是要干什么(即代碼背后的意圖)”,而不是:“這個組件用到了什么選項”。

Options API 撰寫出來的代碼自然采用了后者的表述方式,然而對前者的表述并不好。

1.2.Options API存在的問題

在 Options API 中實際上形成了一種強(qiáng)制的約定:

  • props 里面設(shè)置接收參數(shù)
  • data 里面設(shè)置變量
  • computed 里面設(shè)置計算屬性
  • watch 里面設(shè)置監(jiān)聽屬性
  • methods 里面設(shè)置事件方法

我們會發(fā)現(xiàn): Options API 都約定了我們該在哪個位置做什么事,這在一定程度上也強(qiáng)制我們進(jìn)行了代碼分割。這就為展示背后的邏輯關(guān)注點設(shè)置了障礙。我們必須不斷地在選項代碼塊之間“跳轉(zhuǎn)”,以找到與該關(guān)注點相關(guān)的部分。

尤其是在大型組件中,數(shù)據(jù)與方法會很多,而數(shù)據(jù)與其相關(guān)聯(lián)的方法就會被其他數(shù)據(jù)和方法分隔的很遠(yuǎn),往往很難被看出它們之間的關(guān)聯(lián)。

這是一個大型組件的示例,其中邏輯關(guān)注點是按顏色分組。

這種碎片化使得理解和維護(hù)復(fù)雜組件變得困難。選項的分離掩蓋了潛在的邏輯問題。此外,在處理單個邏輯關(guān)注點時,我們必須不斷地“跳轉(zhuǎn)”相關(guān)代碼的選項塊。

如果我們能夠?qū)⑴c同一個邏輯關(guān)注點相關(guān)的代碼配置在一起,這樣會更好。而這正是組合式 API 使我們能夠做到的。

1.3.Composition API簡介

Composition API:組合式 API;一組低侵入式的、函數(shù)式的 API,使得我們能夠更靈活地【組合】組件的邏輯。

這是有別于 Options API 的一種函數(shù)式 API。無需通過很多選項來完成業(yè)務(wù)邏輯,Composition API提供了一個setup函數(shù),我們可以將data數(shù)據(jù)、計算屬性、方法等等,都放在setup函數(shù)中,這樣就可以對業(yè)務(wù)進(jìn)行集中處理了。

采用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 函數(shù),setup 函數(shù)是一個新的組件選項。作為在組件內(nèi)使用 Composition API 的入口點,如果 setup 返回一個對象,則對象的屬性將會被合并到組件模板的渲染上下文,我們就可以在模板里使用對應(yīng)的屬性和方法。

二.Composition API

2.1.setup()入口

setup 函數(shù)是一個新的組件選項,它是在組件內(nèi)使用 Composition API 的入口點。它會在Vue實例創(chuàng)建完成前被調(diào)用。所以,setup函數(shù)中沒有this指針

<template>
  <div></div>
</template>
 
<script>
export default {
  setup() {
	//這里書寫本地狀態(tài)(data數(shù)據(jù))、計算屬性或方法等
    console.log('setup函數(shù)');
  }
}
</script>

如果 setup 返回一個對象,則對象的屬性將會被合并到組件模板的渲染上下文,我們就可以在模板里使用對應(yīng)的屬性和方法。所以,我們可以將本地狀態(tài)(data數(shù)據(jù))、方法、計算屬性等寫在 setup 函數(shù)中。

<template>
  Count is: {{ count }}
</template>
 
<script>
export default {
  setup() {
    let count = 10;
    
    return {
      count
    }
  }
}
</script>

上面代碼中,在 setup 函數(shù)中聲明了一個 count 數(shù)據(jù)。然后使用 return 返回需要暴露的內(nèi)容。運行之后可以看到:視圖能夠正確顯示count數(shù)據(jù)。

setup函數(shù)總結(jié):

  • setup函數(shù)是Composition API 的入口點,是它的核心。
  • 由于執(zhí)行 setup 時,組件實例尚未被創(chuàng)建,因此在 setup 中不能使用 this。
  • setup中定義的東西必須要return出去,才能被使用或綁定視圖。

2.2.ref 響應(yīng)式監(jiān)聽

上面實例中,雖然視圖能夠顯示數(shù)據(jù)。但當(dāng)改變數(shù)據(jù)時,視圖卻不會得到響應(yīng)。

<template>
  Count is: {{ count }}
  <button @click="add">加</button>
</template>
 
<script>
export default {
  setup() {
    let count = 10;
 
    function add(){
      count++;       //setup函數(shù)中沒有this指針
    }
    
    return {
      count,
      add
    }
  }
}
</script>

原因很簡單,count只是聲明的一個普通數(shù)據(jù),不具備響應(yīng)功能。

在 Vue 3.0 中,我們可以通過一個 ref 函數(shù)來實現(xiàn)響應(yīng)式數(shù)據(jù)監(jiān)聽。ref 接受一個參數(shù),并將其包裹在一個帶有 value 屬性的對象中返回,然后可以使用該 value 屬性訪問或更改響應(yīng)式變量的值:

<template>
  Count is: {{ count }}
  <button @click="add">加</button>
</template>
 
<script>
//注意:要導(dǎo)入ref
import {ref} from 'vue';
 
export default {
  setup() {
    let count = ref(10);  //count成為響應(yīng)式數(shù)據(jù)。
 
    function add(){
      count.value++;       //使用value屬性獲取響應(yīng)數(shù)據(jù)
    }
    
    return {
      count,
      add
    }
  }
}
</script>

為什么要將值封裝在一個對象中,看似沒有必要,但為了保持 JavaScript 中不同數(shù)據(jù)類型的行為統(tǒng)一,這是必須的。因為在 JavaScript 中,Number 或 String 等基本類型是通過值傳遞的,而不是通過引用傳遞的:

2.3.reactive與toRefs

上面實例中,操作數(shù)據(jù)時需要使用 value 屬性,比較麻煩。

可以使用 reactive 與 toRefs 解決這個問題。首先使用 reactive 創(chuàng)建響應(yīng)式對象,封裝數(shù)據(jù)。

<template>
  <p>Count is: {{ state.count }}</p>
  <button @click="add">加</button>
  <p>{{ state.user.username }}</p>
</template>
 
<script>
//注意:要導(dǎo)入ref
import {reactive} from 'vue';
 
export default {
  setup() {
    //所有響應(yīng)數(shù)據(jù)都聲明在這里,包括對象、數(shù)組
    const state = reactive({
      count: 10,
      user:{
        userId: 1,
        username: '張三'
      }
    })
 
    function add(){
      state.count++;       //這里可以不使用value了
    }
    
    return {
      state,
      add
    }
  }
}
</script>

此時不用使用 value 屬性了。

但是因為只有state是響應(yīng)式數(shù)據(jù),而state中的那些數(shù)據(jù)還不是響應(yīng)式的。所以在視圖訪問數(shù)據(jù)時都需要使用 state 作為前綴才可以。這就比較麻煩了。

此時我們可以使用 toRefs 進(jìn)行優(yōu)化。toRefs可以將state中的每一個數(shù)據(jù)進(jìn)行展開,且都包裝成響應(yīng)數(shù)據(jù)。這樣視圖層就可以直接使用了。

<template>
  <p>Count is: {{ count }}</p>
  <button @click="add">加</button>
  <p>{{ user.username }}</p>
</template>
 
<script>
//注意:要導(dǎo)入ref
import {reactive, toRefs} from 'vue';
 
export default {
  setup() {
    //所有響應(yīng)數(shù)據(jù)都聲明在這里,包括對象、數(shù)組
    const state = reactive({
      count: 10,
      user:{
        userId: 1,
        username: '張三'
      }
    })
 
    function add(){
      state.count++;       //這里可以不使用value了
    }
    
    return {
      ...toRefs(state),    //這里使用使用 ...toRefs(state)
      add
    }
  }
}
</script>
在返回時使用 ...toRefs(state) ,這樣視圖層就可以不使用 state 前綴了。
為什么要使用 ... 參數(shù)擴(kuò)展運輸符呢?因為toRefs(state) 將state對象展開,并包裝成多個響應(yīng)數(shù)據(jù)。

2.4.computed的用法

<template>
  <p>Count is: {{ count }}</p>
  <p>doubleCount is: {{ doubleCount }}</p>
  <button @click="add">加</button>
  <p>{{ user.username }}</p>
</template>
 
<script>
//注意:要導(dǎo)入ref
import { reactive, toRefs, computed } from "vue";
 
export default {
  setup() {
    //所有響應(yīng)數(shù)據(jù)都聲明在這里,包括對象、數(shù)組
    const state = reactive({
      count: 10,
      user: {
        userId: 1,
        username: "張三",
      },
      doubleCount: computed(() => {    //使用computed函數(shù)
        return state.count * 2;
      }),
    });
 
    function add() {
      state.count++; //這里可以不使用value了
    }
 
    return {
      ...toRefs(state),
      add,
    };
  },
};
</script>
首先要import導(dǎo)入computed。
在reactive({})中聲明computed即可。

到現(xiàn)在為止,響應(yīng)式數(shù)據(jù)就都可以處理了。

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函數(shù)來進(jìn)行數(shù)據(jù)監(jiān)聽。watch函數(shù)有兩個參數(shù)。
第一個參數(shù):要監(jiān)聽的數(shù)據(jù)。
第二個參數(shù):觸發(fā)監(jiān)聽時的處理函數(shù)(包括newValue, oldValue)

上面實例中直接監(jiān)聽state響應(yīng)對象。但我們知道,在state中會有很多數(shù)據(jù),如果只想監(jiān)聽其中的某個數(shù)據(jù),就需要換一種寫法:

watch(() => state.num,(newValue, oldValue) => {
    console.log(newValue, oldValue);
});

第一個參數(shù)要寫成函數(shù)返回值的形式,這樣就能監(jiān)聽state響應(yīng)對象中的某個數(shù)據(jù)了。

2.6.setup()參數(shù)

setup() 函數(shù)有兩個參數(shù):props 和 context。

為什么要有這兩個參數(shù)呢?我們知道父子組件之間是可以傳值。但是現(xiàn)在我們的業(yè)務(wù)邏輯都寫在setup函數(shù)中,而setpu中沒有this指針,那么就只能靠這兩個參數(shù)來進(jìn)行傳遞了。

  • props:父組件向子組件傳值的參數(shù)。
  • context:子組件向父組件傳值的參數(shù)。

2.6.1.props參數(shù)

setup() 函數(shù)的 props 是父組件向子組件傳值的參數(shù)。

在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導(dǎo)入子組件,然后使用components掛載子組件。

2.6.2.context參數(shù)

setup() 函數(shù)的 context 是子組件向父組件傳值的參數(shù)。

子組件(Hello.vue):

<template>
  <div>
    <div>我是子組件</div>
    <button @click="send">給父組件發(fā)數(shù)據(jù)</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() {
    //所有響應(yīng)數(shù)據(jù)都聲明在這里,包括對象、數(shù)組
    const state = reactive({
      welcome: ''
    });
 
    function get(param) {
      state.welcome = param;
    }
 
    return {
      ...toRefs(state),
      get
    };
  },
  components:{
    Hello
  }
};
</script>

三.Composition API的使用

下面我們會將前面學(xué)過的知識點都改寫為Composition API的形式。而且,Vue3兼容Options API和Composition API兩種寫法。所以這兩種寫法都要會。

3.1.provide與inject的使用

我們學(xué)過provide與inject可用于多級組件直接傳遞數(shù)據(jù),下面學(xué)習(xí)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導(dǎo)入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>

注意,由于父組件向?qū)O子組件傳遞數(shù)據(jù)是單向的,所以孫子組件不能修改傳遞的值。如果子組件

3.2.vue生命周期的用法

在 setup () 內(nèi)部調(diào)用生命周期鉤子:

選項式API

setup () 內(nèi)部調(diào)用生命周期鉤子

beforeCreate()

setup()

created()

setup()

beforeMount()

onBeforeMount()

mounted()

onMounted()

beforeUpdate()

onBeforeUpdate()

updated()

onUpdated()

beforeUnmount()

onBeforeUnmount()

unmounted()

onUnmounted()

注意:在Composition API中沒有beforeCreate()和created()這里兩個聲明周期函數(shù)了,統(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("數(shù)據(jù)更新前!");
    })
 
    onUpdated(() => {
      console.log("數(shù)據(jù)更新后!");
    })
 
    onBeforeUnmount(() => {
      console.log("實例卸載前!");
    })
 
    onUnmounted(() => {
      console.log("實例卸載后!");
    })
 
    return {
      ...toRefs(state),
      add,
    };
  },
};
</script>

3.3.編程式路由的使用

下面學(xué)習(xí)如何在Composition API中使用路由。

打開App.vue組件,這里已經(jīng)有了路由。當(dāng)然,是使用router-link標(biāo)簽來實現(xiàn)的?,F(xiàn)在我們將它改成編程式路由。

<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導(dǎo)入useRouter模塊。
通過useRouter模塊獲取router對象。以后的路由寫法就與前面所學(xué)一樣了。

下面是獲取路由參數(shù),打開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對象后就可以獲取路由參數(shù)了。

3.4.Vuex的使用

下面學(xué)習(xí)如何在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導(dǎo)入useStore模塊。
通過useStore模塊獲取store對象。就可以通過store對象獲取Vuex中的所有數(shù)據(jù)了。

3.5.獲取DOM的使用

前面我們知道在Vue中,可以使用ref來獲取DOM對象。下面學(xué)習(xí)如何在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標(biāo)簽中使用 ref 屬性標(biāo)識一個DOM對象。
  • 需要 import 導(dǎo)入 ref 對象。
  • 使用 const myRef = ref(null); 的方式獲取包裝好的DOM對象,命名為HTML中的 ref 屬性名。并且此數(shù)據(jù)需要暴露出去。
  • 使用 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參數(shù)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的兩個參數(shù)  
    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函數(shù)中聲明的數(shù)據(jù)、函數(shù)等內(nèi)容,都需要通過 return 對外暴露,才能被組件的視圖模板(template)使用,這就造成了書寫上的不方便。于是,Vue官方又給我們推出了一個新的setup語法糖。

使用setup語法糖,就可以不用寫setup函數(shù)了。并且,數(shù)據(jù)和函數(shù)也不用返回,組件也不需要注冊了。

5.1.setup語法糖的基本結(jié)構(gòu)

<template>
</template>
 
<script setup>
//此處直接寫setup函數(shù)中的內(nèi)容
</script>
 
<style>
</style>
  • 在script標(biāo)簽中使用setup屬性即可。
  • 運行時,script標(biāo)簽中的內(nèi)容會被重新編譯成 setup() 函數(shù)的形式。
  • 而且,聲明的數(shù)據(jù)、函數(shù)不需要通過 return 暴露,即可被 template所使用

5.2.響應(yīng)數(shù)據(jù)的使用

<template>
  <div>
    <p>{{ num }}</p>
    <button @click="add">加</button>
  </div>
</template>
 
<script setup>
let num = 10;
//const num = 10;
 
//由于num不是響應(yīng)數(shù)據(jù),所以改變num是無效的。
const add = ()=>{
  alert("觸發(fā)了此方法");
  num++;
}
</script>

直接聲明的數(shù)據(jù)不是響應(yīng)式的,數(shù)據(jù)改變時不會響應(yīng)到視圖模板中。

<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: "技術(shù)部",
  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 都可以做響應(yīng)式數(shù)據(jù),它們的區(qū)別如下:

  • reactive:用于定義引用類型。只能修改數(shù)據(jù),不能改變其引用。
  • ref:用于定義基本類型和引用類型??梢孕薷臄?shù)據(jù),也可以改變其引用。
    • 在方法中修改數(shù)據(jù)時需要使用 value屬性。因為,Ref的本質(zhì)是通過Reactive創(chuàng)建的,Ref(10) 就相當(dāng)于:Reactive({value:10});
    • 在視圖模板調(diào)用可以省略value屬性的書寫。

5.3.其它語法的使用

下面例子演示了computed計算屬性、watch監(jiān)聽、生命周期函數(shù)的使用。

<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);
})
 
//生命周期函數(shù)
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也可以有數(shù)組形式和對象形式兩種寫法。

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>

七. 總結(jié)

到此這篇關(guān)于Vue組合式API的文章就介紹到這了,更多相關(guān)Vue組合式API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue3中關(guān)于路由hash與History的設(shè)置

    vue3中關(guān)于路由hash與History的設(shè)置

    這篇文章主要介紹了vue3中關(guān)于路由hash與History的設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 詳解vue如何封裝封裝一個上傳多張圖片的組件

    詳解vue如何封裝封裝一個上傳多張圖片的組件

    上傳圖片不管是后臺還是前端小程序,上傳圖片都是一個比不可少的功能有時候需要好幾個頁面都要上傳圖片,每個頁面都寫一個非常不方便,本文就給大家介紹vue如何封裝一個上傳多張圖片的組件,需要的朋友可以參考下
    2023-07-07
  • vue中.env文件配置環(huán)境變量的實現(xiàn)

    vue中.env文件配置環(huán)境變量的實現(xiàn)

    本文主要介紹了vue中.env文件配置環(huán)境變量的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • vue實現(xiàn)將數(shù)據(jù)存入vuex中以及從vuex中取出數(shù)據(jù)

    vue實現(xiàn)將數(shù)據(jù)存入vuex中以及從vuex中取出數(shù)據(jù)

    今天小編就為大家分享一篇vue實現(xiàn)將數(shù)據(jù)存入vuex中以及從vuex中取出數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 茶余飯后聊聊Vue3.0響應(yīng)式數(shù)據(jù)那些事兒

    茶余飯后聊聊Vue3.0響應(yīng)式數(shù)據(jù)那些事兒

    這篇文章主要介紹了茶余飯后聊聊Vue3.0響應(yīng)式數(shù)據(jù)那些事兒,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • vue element 多圖片組合預(yù)覽的實現(xiàn)

    vue element 多圖片組合預(yù)覽的實現(xiàn)

    本文主要介紹了vue element多圖片預(yù)覽實現(xiàn)的相關(guān)資料,最近的項目中有圖片預(yù)覽的場景,本文就來介紹一下如何使用,感興趣的可以了解一下
    2023-08-08
  • axios無法加載響應(yīng)數(shù)據(jù):no?data?found?for?resource?with?given?identifier報錯解決

    axios無法加載響應(yīng)數(shù)據(jù):no?data?found?for?resource?with?given?i

    最近在在做一個小查詢功能的時候踩了一個坑,所以這篇文章主要給大家介紹了關(guān)于axios無法加載響應(yīng)數(shù)據(jù):no?data?found?for?resource?with?given?identifier報錯的解決方法,需要的朋友可以參考下
    2022-11-11
  • Vue.js用法詳解

    Vue.js用法詳解

    Vue.js(讀音 /vju&#720;/, 類似于 view) 是一套構(gòu)建用戶界面的漸進(jìn)式框架。這篇文章主要介紹了Vue.js用法詳解,需要的朋友可以參考下
    2017-11-11
  • Vue3.2單文件組件setup的語法糖與新特性總結(jié)

    Vue3.2單文件組件setup的語法糖與新特性總結(jié)

    ue3上線已經(jīng)很久了,許多小伙伴應(yīng)該都已經(jīng)使用過vue3了,下面這篇文章主要給大家介紹了關(guān)于Vue3.2單文件組件setup的語法糖與新特性總結(jié)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • vue項目打包后proxyTable代理失效問題及解決

    vue項目打包后proxyTable代理失效問題及解決

    這篇文章主要介紹了vue項目打包后proxyTable代理失效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。
    2023-05-05

最新評論