In Vue, Mixins can contain options for any component. This makes it easy to abstract the common parts between multiple components using Mixins, but it also brings some problems:

  1. The uncertainty of running results caused by naming conflicts. Data name and method name conflicts can occur between components and imported Mixins, as well as between imported Mixins. When a naming conflict occurs, data or methods with the same name will be overwritten and the corresponding business will fail.
  2. High coupling due to implicit dependencies. There can be dependencies between components and imported Mixins, and if the dependent data or methods are renamed, the data or methods will not be found.

The Composition API solves these problems well. Responsible data that components can expose using the Composition API. Components and Composition apis cannot read and modify their internal data and methods.

The solution

Let’s do a Demo. Make a list page for the admin background. List page support filter search, display list, list page function.

With Mixins implementation

Can bring in the required components; List, search criteria for paging data; And data interaction into Mixins. As follows:

import SearchForm from '@/components/search-form.vue'
import SearchItem from '@/components/search-item.vue'
import TableGrid from '@/components/search-item.vue'

export default {
  components: {
    SearchForm, // Search the conditional form component
    SearchItem, // Search criteria component
    TableGrid // Table component
  },
  data() {
    return {
      list: [/* List data */].searchQuery: {/* Search criteria */}, 
      pager: {/ * paging * /}
    }
  },
  mounted () {
    this.fetchList();
  },
  watch: {
    searchQuery: {
      handler() {this.fetchList()},
      deep: true}},methods: {
    fetchList() {/* Get the list */}}},Copy the code

The list page reads:

<template>
  <div>
    <! -- Search function -->
    <SearchForm @search="fetchList">
      <div>
        <SearchItem title="Name">
          <input type="text" v-model="searchQuery.name">
        </SearchItem>
      </div>
    </SearchForm>
    <! - form - >
    <TableGrid :list="list" :pager="pager"/>
  </div>
</template>

<script>
import listMixins from './mixin'
export default {
  mixins: [listMixins],
}
</script>
Copy the code

Refactor using the Composition API

We used the Composition API to reconstruct the Mixins above. As follows:

import { onMounted, reactive, watch, toRefs } from 'vue'
import SearchForm from '@/components/search-form.vue'
import SearchItem from '@/components/search-item.vue'
import TableGrid from '@/components/search-item.vue'

export default function useList() {
  const data = reactive({
    searchQuery: {},
    list: [].pager: {}})const fetchList = () = > {/* Get the list */}

  onMounted(fetchList)

  watch(() = > data.searchQuery, fetchList, { deep: true })

  return {
    ...toRefs(data),
    fetchList,
    components: {
      SearchForm,
      SearchItem,
      TableGrid
    }
  }
}
Copy the code

The list page reads:

<template>
  <div>
    <! -- Search function -->
    <SearchForm @search="fetchList">
      <SearchItem title="Name">
        <input type="text" v-model="searchQuery.name">
      </SearchItem>
    </SearchForm>
    <! - form - >
    <TableGrid :list="list" :pager="pager"/>
  </div>
</template>

<script setup>
import useList from './use-list'
const {
  components: {
    SearchForm,
    SearchItem,
    TableGrid
  },
  list,
  fetchList,
  searchQuery,
} = useList()
</script>
Copy the code

Reference documentation

  • How does Vue3 Composition API replace Vue Mixins
  • Composition API

Recommended reading

  • Aggregation of disparate business code solutions – Vue 3 Composition API