美文网首页前端开发那些事儿
第 008 期 用 Composition API 重构 Mix

第 008 期 用 Composition API 重构 Mix

作者: 前端GoGoGo7 | 来源:发表于2021-04-07 11:59 被阅读0次

    在 Vue 中,Mixins 可以包含任意组件的选项。这使得用 Mixins 能很方便的抽象多个组件间的公共部分,但也会带来一些问题:

    1. 命名冲突导致的运行结果的不确定性。组件 和 引入的 Mixins,引入的多个 Mixins 之间,都会出现数据名,方法名的命名冲突。出现命名冲突时,同名的数据或方法会被覆盖,对应的业务也就出错了。
    2. 隐式依赖导致的高耦合。组件 和 引入的 Mixins 之间会出现互相依赖的情况,如果依赖的数据或方法重命名了,数据或方法就找不到了。

    Composition API 可以很好的解决这些问题。组件可以用 Composition API 暴露出的可响应数据。组件和 Composition API 不能读取和修改各自内部的数据和方法。

    解决方案

    我们来看个 Demo。做一个管理后台的列表页。列表页支持筛选搜索,显示列表,列表分页的功能。

    用 Mixins 实现

    可以将需要的组件的引入;列表,搜索条件分页数据;以及数据的交互放到 Mixins。如下:

    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, // 搜索条件表单组件
        SearchItem, // 搜索条件组件
        TableGrid //表格组件
      },
      data() {
        return {
          list: [/* 列表数据 */], 
          searchQuery: {/* 搜索条件 */}, 
          pager: {/* 分页 */}
        }
      },
      mounted () {
        this.fetchList();
      },
      watch: {
        searchQuery: {
          handler() {this.fetchList()},
          deep: true
        }
      }, 
      methods: {
        fetchList() {/* 获取列表 */},
      }
    }
    

    列表页这么写:

    <template>
      <div>
        <!-- 搜索功能 -->
        <SearchForm @search="fetchList">
          <div>
            <SearchItem title="姓名">
              <input type="text" v-model="searchQuery.name">
            </SearchItem>
          </div>
        </SearchForm>
        <!-- 表格 -->
        <TableGrid :list="list" :pager="pager"/>
      </div>
    </template>
    
    <script>
    import listMixins from './mixin'
    export default {
      mixins: [listMixins],
    }
    </script>
    

    用 Composition API 重构

    我们用 Composition API 来重构上面的 Mixins。如下:

    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 = () => {/* 获取列表 */}
    
      onMounted(fetchList)
    
      watch(() => data.searchQuery, fetchList, { deep: true })
    
      return {
        ...toRefs(data),
        fetchList,
        components: {
          SearchForm,
          SearchItem,
          TableGrid
        }
      }
    }
    

    列表页这么写:

    <template>
      <div>
        <!-- 搜索功能 -->
        <SearchForm @search="fetchList">
          <SearchItem title="姓名">
            <input type="text" v-model="searchQuery.name">
          </SearchItem>
        </SearchForm>
        <!-- 表格 -->
        <TableGrid :list="list" :pager="pager"/>
      </div>
    </template>
    
    <script setup>
    import useList from './use-list'
    const {
      components: {
        SearchForm,
        SearchItem,
        TableGrid
      },
      list,
      fetchList,
      searchQuery,
    } = useList()
    </script>
    

    参考文档

    相关文章

      网友评论

        本文标题:第 008 期 用 Composition API 重构 Mix

        本文链接:https://www.haomeiwen.com/subject/jvzykltx.html