current position:Home>[Vue] understanding and thinking of new features based on Vue 3

[Vue] understanding and thinking of new features based on Vue 3

2022-06-24 08:16:39GavinUI

vue The emergence of new features often requires attention to , What better technical solutions can be optimized and adjusted for my previous projects or projects to be developed by his features , It can also be said to be it What problems have been solved . and Composition API This time vue 3 Update focus of .

Composition API

Composition API In order to solve the problem of heavy interaction logic , Make the function more convenient to call and easy for developers to understand . The core idea is to collect the relevant code .

Let go of Vue2 perhaps Vue3 , In my previous project development , Due to the relatively large number of processing logic , I just separated some logic and put it in different functions , Vue2 The code is as follows :

  methods: {
    format() {
      this.fun1();
      this.fun2();
      this.fun3();
      this.fun4();
      this.fun5();
    },
    fun1() { },
    fun2() { },
    fun3() { },
    fun4() { },
    fun5() { },
  },

Of course, here is a logical simplification , Writing is definitely not like this , Just to explain format This method references and at least 5 A function , I was very happy when I pulled away from logic , After drawing a large pile of code, you can call feel thief slip .

But I am codeReview When you give it to the big guy , After reading it, he immediately pointed out the shortcomings of this place , Because I write very well , But the viewer is not like this. After a while, he scrolls to 20 OK, look fun1 , I will scroll to 130 OK, look fun2 , In a little while, scroll to 1000 OK, look fun3 , So in the end, not only are others tired , I was confused .

therefore , He proposed to put the relevant function points in the same function as far as possible , The code is as follows

  methods: {
    format() {
      const fun1 = () => { };
      const fun2 = () => { };
      const fun3 = () => { };
      const fun4 = () => { };
      const fun5 = () => { };
    },
  },

His actual optimization is from the original :

Change it to :

In this way, we can understand this more clearly format Function modules depend on what they do , Not only can I understand the execution of functions very quickly , It's easy for others to read , This is the idea of simplifying code development .

go back to vue here , stay Vue2 Version of , Develop page logic using watch ,methods,data ,computed And other component options are very convenient to organize logic , But facing the pages with heavy interaction , These logic will also look bloated , Not easy to understand .

The official website documentation also gives a simple example that tends to be practical :

export default {
  components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
  props: {
    user: { 
      type: String,
      required: true
    }
  },
  data () {
    return {
      repositories: [], 
      filters: { ... }, 
      searchQuery: '' 
    }
  },
  computed: {
    filteredRepositories () { ... }, 
    repositoriesMatchingSearchQuery () { ... }, 
  },
  watch: {
    user: 'getUserRepositories' 
  },
  methods: {
    getUserRepositories () {
    }, 
    updateFilters () { ... }, 
  },
  mounted () {
    this.getUserRepositories() 
  }
}

The options of the components here are all used , The more interaction later , The interaction code of various logic must be one by one “ block ” The units are built up . and Composition API The purpose of using is to aggregate logic .

Composition API Use

vue 3 A new component option has been added in setup, It is executed before creation , stay props When parsing , Just as Composition API Entrance .

export default {
  components: { ... },
  props: {
    user: {
      type: String,
      required: true
    }
  },
  setup(props) {
    console.log(props)
    return {}
  }

}

He and props And other component options , It returns an object , This object can be used elsewhere , It can be said that the component provides a api The generic function .

belt ref The response variable of

stay vue3 in , Through a new ref Function to make any immediate response variable work anywhere .

import { ref } from 'vue'
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0

counter.value++
console.log(counter.value) // 1

Encapsulate a value in an object , The advantage is that the object takes a reference , It will not affect the old data when modifying the new data , Official website DEMO Exhibition .

import { fetchUserRepositories } from '@/api/repositories'
import { ref } from 'vue'

export default {
  components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
  props: {
    user: {
      type: String,
      required: true
    }
  },
  setup (props) {
    const repositories = ref([])
    const getUserRepositories = async () => {
      repositories.value = await fetchUserRepositories(props.user)
    }

    return {
      repositories,
      getUserRepositories
    }
  },
  data () {
    return {
      filters: { ... }, 
      searchQuery: '' 
    }
  },
  computed: {
    filteredRepositories () { ... }, 
    repositoriesMatchingSearchQuery () { ... }, 
  },
  watch: {
    user: 'getUserRepositories' 
  },
  methods: {
    updateFilters () { ... },
  },
  mounted () {
    this.getUserRepositories() 
  }
}

It should be noted that , You need to change the original data Medium repositories Get rid of , because repositories This variable is now represented by setup This component option returns .

setup The use of hook functions in

stay setup in , Hook function and option expression of life cycle API It's the same , But the name of his hook function has been added in front on . give an example mount and beforeount .

  setup(props) {
    const resList = ref([]);
    const fetchUserList = () => {
      resList.value = props.user;
    }
    onBeforeMount(getClass);
    onMounted(fetchUserList);
    return {
      resList,
      fetchUserList
    }
  },

So here are some ways to avoid hanging on the outer layer , As long as through the onMounted To execute .

setup Medium watch monitor

Methods and options of listener API The method of the master is the same ,watch You can also listen here props The content of , But there are differences , The object to listen to is after toRefs Method , Just give props in user Responsive reference to .

import {toRefs } from 'vue';
const { user } = toRefs(props);

The purpose of this is to better monitor props in user The change of , On the use ,watch The second parameter of is to execute the callback function when the listening object changes .

import { ajax } from 'majax';
import { ref, onMounted, watch, toRefs } from 'vue'

setup (props) {
  const { user } = toRefs(props)
  const resList = ref([])
  const fetchUserList = async () => {
    resList.value = await ajax(user.value)
  }
  onMounted(fetchUserList)
  watch(user, fetchUserList)
  return {
    resList,
    fetchUserList
  }
}

setup In the middle computed attribute

Combine the most basic demo And instructions :

import { ref, computed } from 'vue'
const counter = ref(0)
const twiceTheCounter = computed(() => counter.value * 2)
counter.value++
console.log(counter.value) 
console.log(twiceTheCounter.value)

computed Take a parameter , This parameter is equivalent to a fallback function , stay setup You still need Calculate the new variable , As in the above example conter.value. The real use case is :

import { majax } from 'majax'
import { ref, onMounted, watch, toRefs, computed } from 'vue'

setup (props) {
  const { user } = toRefs(props)
  const resList = ref([])
  const fetchUserList = async () => {
    resList.value = await majax(user.value)
  }
  onMounted(fetchUserList)
  watch(user, fetchUserList)
  const searchQuery = ref('')
  const MatchingQuery = computed(() => {
    return resList.value.filter(
      item => item.name.includes(searchQuery.value)
    )
  })
  return {
    resList,
    fetchUserList,
    searchQuery,
    MatchingQuery
  }
}

Until this whole setup There is a complete function , His options api Contains watch,computed,data also ref function .

Moving the function points to setup In the following , Although the logic will be more clear , But what follows is setup It's getting bigger and bigger . We need to further separate the method just described , For example, there are two functions: query and list rendering , Put their functional logic and hooks, etc Composition API The required attributes are separated and placed in two different JS Module export . I will DEMO The code has been simplified , The following two code blocks , They are the functions of query and list acquisition :

Get the code of the list module :

// fetchUserList.js
import { ajax } from 'majax';
import { ref, onMounted, watch } from 'vue';

export default function fetchUserList(user) {
  const resList = ref([])
  const fetchUserList = async () => {
    resList.value = await ajax(user.value)
  }
  onMounted(fetchUserList)
  watch(user, fetchUserList)
  return {
    resList,
    fetchUserList
  }
}

Filter module code :

// searchUserList.js
import { ref, computed } from 'vue'

export default function searchName(resList) {
  const searchQuery = ref('')
  const MatchingQuery = computed(() => {
    return resList.value.filter(repository => {
      return repository.name.includes(searchQuery.value)
    })
  })
  return {
    searchQuery,
    MatchingQuery
  }
}

With the code for these two modules , Then introduce it back to setup In the options :

import fetchUserList from 'fetchUserList.js'
import searchUserList from 'searchUserList.js'
import { toRefs } from 'vue'

export default {
...
  setup (props) {
    const { user } = toRefs(props)
    const { resList, fetchUserList } = fetchUserList(user)
    const { searchQuery, MatchingQuery } = searchUserList(repositories)
    return {
      resList: MatchingQuery,
      fetchUserList,
      searchQuery,
    }
  },
  ...
}

To sum up ,Composition API Did such a thing , He does not use the same logic as before , Logic codes are scattered in watch Or is it computed in , Instead, the related code logic is aggregated into a functional module , Then use the functions on this module , Using a picture to represent is :

They are transformed into functional modules . The above is right Composition API Functional understanding of .

copyright notice
author[GavinUI],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/175/20210627143233434n.html

Random recommended