Practical record of Vue3 combined with TypeScript project development

  • 2021-11-24 00:22:47
  • OfStack

Catalog Overview 1. compositon Api 1. What is the difference between ref and reactive?
2. Periodic function
3. Use of store
4. Use of router
2. Separation of concerns 3. TypeScript support Summarize

Overview

Vue3 has been out for a period of time, and in the team, a lot of business practices have been carried out, and some own thoughts have been made.

Generally speaking, Vue3 has made great progress both in the underlying principle and in the actual development of business.

Using proxy instead of Object. defineProperty's API has better performance and solves the defects of vue in dealing with objects and arrays; In the diff algorithm, the static marking method is used, which greatly improves the execution efficiency of Vue.

At the level of use, we changed from options Api to composition Api, and slowly in the actual business, we abandoned the original isolated writing of data, methods and computed. compositon Api, it is more focused, it pays attention to the aggregation of related businesses. At the same time, in composition Api, in order to prevent too heavy business logic, it provides a way to separate concerns, which greatly improves the readability of our code.

Completely supports TypeScript, and type verification has become the quality assurance for large-scale project development of Vue3 in the future. At the same time, it is also facing the trend-the future of the front end is TypeScript!

1. compositon Api

The essence of compositon Api is embodied in the code, that is, an setup function. In this setup function, the returned data will be used in the template of this component. This object of return, to some extent, represents the data attribute in vue2 before.


import { defineComponent, ref } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        return {
            counter
        }
    }
})

At this time, for most beginners, there may be doubts about whether I can define the writing of options Api, such as data, computed, watch, methods and so on.

What I need to be clear here is that Vue3 is fully compatible with options Api of Vue2, but conceptually, setup is more recommended to write our components. The reasons are as follows: The existence of Vue3 itself is to solve the problem of Vue2, and the problem of Vue2 is that the lack of aggregation will lead to more and more bloated code! The way of setup can aggregate data, method logic and dependency relationship in one block, which is more convenient for maintenance.

That is to say, we should try not to write separate data, computed, watch, methods, etc. It is not that Vue3 does not support it, but that it violates the concept of Vue3.

components attribute, that is, a subcomponent of a component. This configuration is not much different between Vue2 and 3. How to use Vue2, Vue3 is still used.

1. What is the difference between ref and reactive?

In terms of function, ref and reactive can both realize responsive data!

At the grammatical level, there are differences between the two. The responsive data defined by ref needs to be changed by [data]. value; The data defined by reactive needs to be changed in the manner of [data]. [prpoerty].


const actTitle: Ref<string> = ref(' Activity name ');

const actData = reactive({
    list: [],
    total: 0,
    curentPage: 1,
    pageSize: 10
});

actTitle.value = ' Activity name 2';

actData.total = 100;

However, at the application level, there are differences. Generally speaking, for a single common type of data, we use ref to define the response formula. In the form scenario, describe the scene of key: value of a form, and use reactive;; In some scenarios, a group of data of a certain module usually uses reactive to define data.

So, do objects have to be defined using reactive? Actually not, can, according to their own business scenarios, specific problems specific analysis! ref emphasizes the change of value of one data, and reactive emphasizes the change of one attribute of the defined object.

2. Periodic function

The periodic function, in Vue3, is used separately as follows:


import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        onMounted(() => {
            //  Handle business, 1 Make a data request like this 
        })
        return {
            counter
        }
    }
})

3. Use of store

In Vue2, it can be obtained directly through this. $store, but in Vue3, there is no concept of this, and it is used as follows:


import { useStore } from "vuex";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const store = useStore();
        const storeData = computed(() => store); //  Cooperate computed , get the store The value of. 
        return {
            counter,
            storeData
        }
    }
})

4. Use of router

In Vue2, routing is programmed functionally through this. $router, but in Vue3, it is used as follows:


import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }
        return {
            counter,
            onClick
        }
    }
})

2. Separation of concerns

The separation of concerns should be divided into two meanings: the first meaning is that setup of Vue3 puts the relevant data and processing logic into one, which is an aggregation of concerns, which is more convenient for us to look at business codes.

Layer 2 means that when setup becomes larger, we can extract a related business within setup, so as to separate the concerns of Layer 2.


import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
import useMerchantList from './merchant.js';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }
        //  In this example, we separate the related business of obtaining the merchant list. That is, the following merchant.ts
        const {merchantList} = useMerchantList();
        return {
            counter,
            onClick,
            merchantList
        }
    }
})

merchant.ts


import { getMerchantlist } from "@/api/rights/gift";
import { ref, onMounted } from "vue";

export default function useMerchantList(): Record<string, any> {
  const merchantList = ref([]);
  const fetchMerchantList = async () => {
    let res = await getMerchantlist({});
    merchantList.value = res?.data?.child;
  };

  onMounted(fetchMerchantList);

  return {
    merchantList
  };
}

3. TypeScript support

This first part, to be precise, is the content of TS, but it is closely related to the development of Vue3 project, so if we really want to use Vue3, we still need to know the use of TS.

However, in this 1 part, I will not introduce the basic syntax of TS, mainly how to organize TS in business scenarios.

When using TS for business development, one core thinking is to pay attention to data structure first, and then develop pages according to data structure. The previous front-end development mode was to write pages first and then pay attention to data.

For example, to write a gift list page, we might want to define some interface. To sum up, we need to pay attention to: interface of page data, data type returned by interface, input parameter type of interface, and so on.


//  Gift Creation, Edit, Each in the List 1 Item will be this data type. 
interface IGiftItem {
  id: string | number;
  name: string;
  desc: string;
  [key: string]: any;
}

//  Globally corresponding type definitions 
//  And 1 Generally speaking, we don't know what the type returned by the interface is (it may be null , which may be an object or an array, so use a paradigm to define the interface
interface IRes<T> {
    code: number;
    msg: string;
    data: T
}
//  Interface returns a data type definition 

interface IGiftInfo {
    list: Array<IGiftItem>;
    pageNum: number;
    pageSize: number;
    total: number;
}

In a common interface request, we generally use TS to define a data request, req type of data request and res type of data request.


export const getGiftlist = (
  params: Record<string, any>
): Promise<IRes<IGiftInfo>> => {
  return Http.get("/apis/gift/list", params);
};

Summarize


Related articles: