The “composite API” is a new syntax extended to Vue3. The syntax explained in the previous basic lesson is called” option API”. Both apis are supported in VUe3.
What does it solve?
“Combination of the API“You can split it even further.”Option APIIn the”JS logic.can put a certain logical”Data/computed/watch/methods/hook statement cycle“Wrapped in a separate function (or file). The split function is usually named “useXxx”.
Breaking down actual requirements
Analyzing the shopping cart module below, I plan to put the JS partSplit into 2 parts (function): One is used to get the shopping cart item data and the total price, and one is used to calculate the coupon and the total price after the discount. Subtables are functions:useGetCart“And”useCoupon“.
The setup structure
The old “options API” does not have the “methods” field, but it can also encapsulate functions. Let’s look at the code format of the” composition API”. A new field, “setup”, is the signature property of the “composition API”, which is a function. The return value is recognized and rendered by the template, similar to “data”.
Pay special attention to the return values of the two functions, which return data (similar to data) and functions (similar to methods). The actual function contains a separate “watch/computed/ lifecycle hook “that groups the contents of a VUE component’s “data” and “methods”, which is why it is called a” composite API”.
<template>
<article v-if="cart.length > 0">
<ul>
<li v-for="item in cart" :key="item.name">{{item.name}} : {{item.price}} element<input v-model="item.count" type="number" style="width: 48px" />
</li>
</ul>
<h5 style="margin-left: 100px">Price :{{totalPrice}} yuan</h5>
<h5 style="margin-left: 100px; color: #f10">Total price :{{realTotalPrice}} yuan</h5>
<button @click="createOrder">pay</button>
</article>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: 'Cart'.setup(){
// Shopping cart details and total price
const [cart,totalPrice,createOrder] = useGetCart();
// Discount price
const realTotalPrice = useCoupon();
// Returns the data identified by the template, as defined by data
return{cart,totalPrice,realTotalPrice,createOrder}; }});</script>
Copy the code
Internal implementation of “useXxx” function
This “use” as a prefix for function names is a naming convention, and there are no actual restrictions on naming. For every “watch/computed/ lifecycle hook “in a function, they all appear as functions.
import {computed} from 'vue';
/** * get shopping cart details */
function useGetCart() {
// Shopping cart details (reactive)
const cart = reactive<{ name: string; count: number; price: number} [] > ([]);// Simulate an asynchronous request
setTimeout(() = > {
cart.push(
{ name: The word "apple".count: 10.price: 10 },
{ name: "Banana".count: 20.price: 20}); },1000);
// Total price (computed)
const totalPrice = computed(() = > {
return cart.reduce((total, item) = > item.count * item.price + total, 0);
});
return [cart, totalPrice] as const;
}
Copy the code
There’s a new function called ref, which is used to “define the response data,” and we’re going to talk about what ref is.
Pay attention to
- “As const” means to assert that the array type is a primitive, so if you forgot the TS part, you might want to review ts before we move on.
- Mounted => onMounted
Define response data (Reactive/REF)
“Response data” is the data that changes in value can drive changes in the DOM, and the data we defined earlier in “data” is the response data. But in “setup” if we want to define data, there is no “data” function. Instead, there is a” reactive/ref” function:
reactive
Defines the response data, the input can only be the object type, and returns the response version of the input object.
<template>
<h1>{{count}}</h1>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
setup(){
return reactive({count:99}); }});</script>
Copy the code
The actualI don’t need to be reactive in this case, the result is the same, but if the “count” data is changed, then the interface will not automatically change, it will always display “99”.
ref
Reactive: Reactive: reactive: reactive: reactive: reactive: reactive: reactive: reactive: reactive: reactive: reactive
const n = ref(110);
console.log(n);
Copy the code
Can see the return value in the value field, do so because the data changes in js monitoring only supports the “reference data type”, for the string and number type if you need to monitor need to construct an object, so this ref internal need to construct a {110} value: variable.​
Reactive and REF selection
Important: Use Reactive if the data to be monitored is object, and ref if it is primitive (number/ Boolean /string).
Encapsulating functions (useXxx)
Now let’s go back to the implementation of two functions.
useGetCart
Returns the item information in the shopping cart and the total price, which uses a “computed property” function (computed property) and a “generate order” function encapsulated because it needs the item information in the shopping cart as a parameter, so we use 2 as a group.
import {computed} from 'vue';
/** * get shopping cart details */
function useGetCart() {
// Shopping cart details (reactive)
const cart = reactive<{ name: string; count: number; price: number} [] > ([]);// Simulate an asynchronous request
setTimeout(() = > {
cart.push(
{ name: The word "apple".count: 10.price: 10 },
{ name: "Banana".count: 20.price: 20}); },1000);
// Total price (computed)
const totalPrice = computed(() = > {
return cart.reduce((total, item) = > item.count * item.price + total, 0);
});
// Generate order (methods)
function createOrder(){
// Simulate order generation
setTimeout(() = >{
console.log('Successful purchase${cart.length}Goods `);
},1000)}return [cart, totalPrice,createOrder] as const;
}
Copy the code
useCoupon
Get the discount amount, and return to calculate the discount amount. Use watch to monitor the “total price “, recalculate the” total price after discount “when it changes, and use “onMounted” to control the timing of data request triggering (this example is not useful, only to demonstrate the use of “onMounted”).
import {watch,onMounted} from 'vue';
/** ** get coupon */
function useCoupon(totalPrice: Ref<number>) {
const realTotalPrice = ref(0);
// Instead of using onMouted,
// Just to demonstrate usage
onMounted(() = > {
// Simulate an asynchronous request
setTimeout(() = > {
const coupon = 9;
watch(
totalPrice,
(value) = > {
realTotalPrice.value = value - coupon;
},
{ immediate: true}); },1000);
});
return realTotalPrice;
}
Copy the code
As a function, the second parameter of “watch” is an object, with the field “immediate” indicating that the callback is initialized and run, and “deep” indicating the depth monitoring data (Object).
Complete source code
Github.com/any86/vue3-…
WeChat group
Thank you for your reading. If you have any questions, you can add me to the wechat group, and I will pull you into the wechat group (Because Tencent limits the number of wechat groups to 100, when the number exceeds 100, you must be joined by group members).
To be continued
Please follow me for updates