mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-24 12:45:18 +08:00
refactor(anchor): use composition api
This commit is contained in:
parent
7108717fcd
commit
a8449c9842
@ -2,7 +2,11 @@ import {
|
||||
ref,
|
||||
computed,
|
||||
watch,
|
||||
onMounted, inject, toRef
|
||||
onMounted,
|
||||
inject,
|
||||
toRef,
|
||||
getCurrentInstance,
|
||||
onBeforeUnmount
|
||||
} from 'vue'
|
||||
|
||||
export function useFalseUntilTruthy (valueRef) {
|
||||
@ -62,4 +66,59 @@ export function useInjectionRef (injectionName, key, fallback) {
|
||||
return toRef(injection, key)
|
||||
}
|
||||
|
||||
export function onFontReady (callback) {
|
||||
onMounted(() => {
|
||||
const fontsReady = document.fonts.ready
|
||||
const currentInstance = getCurrentInstance().proxy
|
||||
fontsReady.then(() => {
|
||||
callback(currentInstance)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function useInjectionCollection (injectionName, collectionKey, valueRef) {
|
||||
const injection = inject(injectionName)
|
||||
if (!(collectionKey in injection)) {
|
||||
injection[collectionKey] = []
|
||||
}
|
||||
injection[collectionKey].push(valueRef.value)
|
||||
watch(valueRef, (value, prevValue) => {
|
||||
const collectionArray = injection[collectionKey]
|
||||
const index = collectionArray.findIndex(
|
||||
collectionValue => collectionValue === prevValue
|
||||
)
|
||||
if (~index) collectionArray.splice(index, 1)
|
||||
collectionArray.push(value)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
const collectionArray = injection[collectionKey]
|
||||
const index = collectionArray.findIndex(
|
||||
collectionValue => collectionValue === valueRef.value
|
||||
)
|
||||
if (~index) collectionArray.splice(index, 1)
|
||||
})
|
||||
}
|
||||
|
||||
export function useInjectionElementCollection (injectionName, collectionKey, getElement) {
|
||||
const injection = inject(injectionName)
|
||||
if (!(collectionKey in injection)) {
|
||||
injection[collectionKey] = []
|
||||
}
|
||||
onMounted(() => {
|
||||
const currentInstance = getCurrentInstance().proxy
|
||||
injection[collectionKey].push(
|
||||
getElement(currentInstance)
|
||||
)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
const collectionArray = injection[collectionKey]
|
||||
const currentInstance = getCurrentInstance().proxy
|
||||
const element = getElement(currentInstance)
|
||||
const index = collectionArray.findIndex(
|
||||
collectionElement => collectionElement === element
|
||||
)
|
||||
if (~index) collectionArray.splice(index, 1)
|
||||
})
|
||||
}
|
||||
|
||||
export { default as useLastClickPosition } from './use-last-click-position'
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div />
|
||||
<!-- <n-base-anchor
|
||||
<n-base-anchor
|
||||
v-if="!affix"
|
||||
ref="anchor"
|
||||
:bound="bound"
|
||||
@ -26,7 +25,7 @@
|
||||
>
|
||||
<slot />
|
||||
</n-base-anchor>
|
||||
</n-affix> -->
|
||||
</n-affix>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -24,10 +24,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { nextTick, ref, markRaw } from 'vue'
|
||||
import getScrollParent from '../../_utils/dom/getScrollParent'
|
||||
import withapp from '../../_mixins/withapp'
|
||||
import themeable from '../../_mixins/themeable'
|
||||
import fontawarable from '../../_mixins/fontawarable'
|
||||
import { onFontReady } from '../../_utils/composition/index'
|
||||
import { warn } from '../../_utils/naive/warn'
|
||||
|
||||
function getOffset (el, container) {
|
||||
const {
|
||||
@ -45,7 +47,15 @@ function getOffset (el, container) {
|
||||
|
||||
export default {
|
||||
name: 'NBaseAnchor',
|
||||
mixins: [withapp, themeable, fontawarable],
|
||||
mixins: [
|
||||
withapp,
|
||||
themeable
|
||||
],
|
||||
provide () {
|
||||
return {
|
||||
NAnchor: this
|
||||
}
|
||||
},
|
||||
props: {
|
||||
target: {
|
||||
type: Function,
|
||||
@ -60,12 +70,17 @@ export default {
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
setup () {
|
||||
onFontReady(vm => {
|
||||
vm.init()
|
||||
vm.setActiveHref(window.location)
|
||||
vm.handleScroll(false)
|
||||
})
|
||||
return {
|
||||
collectedLinkHrefs: [],
|
||||
titleEls: [],
|
||||
activeHref: null,
|
||||
container: null
|
||||
collectedLinkHrefs: markRaw([]),
|
||||
titleEls: markRaw([]),
|
||||
activeHref: ref(null),
|
||||
container: ref(null)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -76,17 +91,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
provide () {
|
||||
return {
|
||||
NAnchor: this
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleFontReady () {
|
||||
this.init()
|
||||
this.setActiveHref(window.location)
|
||||
this.handleScroll(false)
|
||||
},
|
||||
disableTransitionOneTick () {
|
||||
const barEl = this.$refs.bar
|
||||
const slotEl = this.$refs.slot
|
||||
@ -100,7 +105,7 @@ export default {
|
||||
titleEls.forEach(titleEl => {
|
||||
titleEl.style.transition = 'none'
|
||||
})
|
||||
this.$nextTick().then(() => {
|
||||
nextTick(() => {
|
||||
const nextBarEl = this.$refs.bar
|
||||
const nextSlotEl = this.$refs.slot
|
||||
if (nextBarEl) {
|
||||
@ -229,8 +234,8 @@ export default {
|
||||
const target = this.target()
|
||||
if (target instanceof Element) {
|
||||
this.container = target
|
||||
} else {
|
||||
console.error('[naive-ui/Anchor]: target is not a element')
|
||||
} else if (__DEV__) {
|
||||
warn('anchor', 'target is not a element')
|
||||
}
|
||||
}
|
||||
if (this.container) {
|
||||
|
@ -18,8 +18,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import collectable from '../../_mixins/collectable'
|
||||
import simlulatedComputed from '../../_mixins/simulatedComputed'
|
||||
import { toRef } from 'vue'
|
||||
import {
|
||||
useMemo,
|
||||
useInjectionRef,
|
||||
useInjectionCollection,
|
||||
useInjectionElementCollection
|
||||
} from '../../_utils/composition'
|
||||
|
||||
export default {
|
||||
name: 'AnchorLink',
|
||||
@ -28,19 +33,6 @@ export default {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
mixins: [
|
||||
simlulatedComputed({
|
||||
active: {
|
||||
get () {
|
||||
const href = this.href
|
||||
return href && (this.activeHref === href)
|
||||
},
|
||||
deps: ['activeHref', 'href'],
|
||||
default: false
|
||||
}
|
||||
}),
|
||||
collectable('NAnchor', 'collectedLinkHrefs', 'href')
|
||||
],
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
@ -51,9 +43,20 @@ export default {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
activeHref () {
|
||||
return this.NAnchor.activeHref
|
||||
setup (props) {
|
||||
const activeHrefRef = useInjectionRef('NAnchor', 'activeHref')
|
||||
const hrefRef = toRef(props, 'href')
|
||||
const activeRef = useMemo(() => {
|
||||
return hrefRef.value && (hrefRef.value === activeHrefRef.value)
|
||||
}, [
|
||||
hrefRef,
|
||||
activeHrefRef
|
||||
])
|
||||
useInjectionCollection('NAnchor', 'collectedLinkHrefs', hrefRef)
|
||||
useInjectionElementCollection('NAnchor', 'titleEls', vm => vm.$refs.title)
|
||||
return {
|
||||
activeHref: activeHrefRef,
|
||||
active: activeRef
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -61,19 +64,7 @@ export default {
|
||||
if (value) this.NAnchor.updateBarPosition(this.$refs.title)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.NAnchor.titleEls.push(this.$refs.title)
|
||||
},
|
||||
beforeDestroy () {
|
||||
const titleElIndex = this.NAnchor.titleEls.findIndex(el => el === this.$refs.title)
|
||||
if (~titleElIndex) this.NAnchor.titleEls.splice(titleElIndex, 1)
|
||||
},
|
||||
methods: {
|
||||
handleFontReady () {
|
||||
if (this.active) {
|
||||
this.NAnchor.updateBarPosition(this.$refs.title, false)
|
||||
}
|
||||
},
|
||||
handleClick (e) {
|
||||
this.NAnchor.setActiveHref(this.href)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user