Vue3 setup a new world

setup

原因:逻辑点分散对接手项目的人不友好
// src/components/UserRepositories.vue
export default {
  components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
  props: {
    user: { 
      type: String,
      required: true
    }
  },
  data () {
    return {
      repositories: [], // 1
      filters: { ... }, // 3
      searchQuery: '' // 2
    }
  },
  computed: {
    filteredRepositories () { ... }, // 3
    repositoriesMatchingSearchQuery () { ... }, // 2
  },
  watch: {
    user: 'getUserRepositories' // 1
  },
  methods: {
    getUserRepositories () {
      // 使用 `this.user` 获取用户仓库
    }, // 1
    updateFilters () { ... }, // 3
  },
  mounted () {
    this.getUserRepositories() // 1
  }
}
方法(关注点拆分)

该组件有以下几个职责:(逻辑点在代码中分散)

1.从假定的外部 API 获取该用户名仓库,并在更改时刷新仓库
2.使用 searchQuery 字符串搜索仓库
3.使用 filters 对象筛选searchQuery匹配仓库

可见代码中分布太散(理解太浪费时间)

1.有 getUserRepositories、repositories 
useRepository(user) {
  // 闭包searchQuery
  return {
     getUserRepositories,
      repositories
  }
}
2. searchQuery、repositoriesMatchingSearchQuery 
useRepositoryNameSearch(repositories) {
  // 闭包searchQuery
  return {
      searchQuery,
      repositoriesMatchingSearchQuery
   }
}
3. filteredRepositories、updateFilters 、filteredRepositories
useRepositoryFilters(repositoriesMatchingSearchQuery) {
  // 闭包filters
  return {
      updateFilters ,filteredRepositories
  }
}

总结抽象方法(欢迎修改)

useXXX(...params)(XXX多为data即使用对象、params为该方法依赖)
data: ref(基本数据类型) 、reactive(指向数据类型) xxx
methods: 封装在引用xxx的useXXX中
watch: 封装在被观察xxx的useXXX中
computed:封装在使用xxx的useXXX中

方法实践(LazyLoad)

import { inBrowser } from './util'
import Lazy from './lazy'

const LazyComponent = (lazy) => {
  return {
    props: {
      tag: {
        type: String,
        default: 'div'
      }
    },
    render (h) {
      return h(this.tag, null, this.show ? this.$slots.default : null)
    },
    data () {
      return {
        el: null, // 1
        state: { // 2
          loaded: false
        },
        rect: {}, // 3
        show: false // 5
      }
    },
    mounted () {
      this.el = this.$el
      lazy.addLazyBox(this)
      lazy.lazyLoadHandler()
    },
    beforeDestroy () {
      lazy.removeComponent(this)
    },
    methods: {
      getRect () {
        this.rect = this.$el.getBoundingClientRect()
      },
      checkInView () {
        this.getRect()
        return inBrowser &&
                    (this.rect.top < window.innerHeight * lazy.options.preLoad && this.rect.bottom > 0) &&
                    (this.rect.left < window.innerWidth * lazy.options.preLoad && this.rect.right > 0)
      },
      load () {
        this.show = true
        this.state.loaded = true
        this.$emit('show', this)
      },
      destroy () {
        return this.$destroy
      }
    }
  }
}

LazyComponent.install = function (Vue, options = {}) {
  const LazyClass = Lazy(Vue)
  const lazy = new LazyClass(options)
  Vue.component('lazy-component', LazyComponent(lazy))
}

export default LazyComponent
调用load方法修改show,并更具show判断是否加展示$slot.default

find nodes which in viewport and trigger load // inview
init IntersectionObserver // isIntersecting

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容