setup
原因:邏輯點(diǎn)分散對(duì)接手項(xiàng)目的人不友好
// 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` 獲取用戶倉(cāng)庫(kù)
}, // 1
updateFilters () { ... }, // 3
},
mounted () {
this.getUserRepositories() // 1
}
}
方法(關(guān)注點(diǎn)拆分)
該組件有以下幾個(gè)職責(zé):(邏輯點(diǎn)在代碼中分散)
1.從假定的外部 API 獲取該用戶名的倉(cāng)庫(kù),并在更改時(shí)刷新倉(cāng)庫(kù)
2.使用 searchQuery 字符串搜索倉(cāng)庫(kù)
3.使用 filters 對(duì)象篩選searchQuery匹配倉(cāng)庫(kù)
可見(jiàn)代碼中分布太散(理解太浪費(fèi)時(shí)間)
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
}
}
總結(jié)抽象方法(歡迎修改)
useXXX(...params)(XXX多為data即使用對(duì)象、params為該方法依賴(lài))
data: ref(基本數(shù)據(jù)類(lèi)型) 、reactive(指向數(shù)據(jù)類(lèi)型) xxx
methods: 封裝在引用xxx的useXXX中
watch: 封裝在被觀察xxx的useXXX中
computed:封裝在使用xxx的useXXX中
方法實(shí)踐(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
調(diào)用load方法修改show,并更具show判斷是否加展示$slot.default
find nodes which in viewport and trigger load // inview
init IntersectionObserver // isIntersecting