滑动切换路由 + 重构
编码规范
const test = ref()
console.log(test.value === undefined) // true
// ref 默认值 undefined,方便统一推荐写法
const div = ref<HTMLDivElement>()
// 不推荐写法
const div = ref<HTMLDivElement | null>(null)
useRoute、useRouter
useRoute:返回当前的路由地址。相当于在模板中使用 $route
useRouter:返回路由器实例。相当于在模板中使用 $router
...
const pushMap: Record<string, string> = {
'Welcome1': '/welcome/2',
'Welcome2': '/welcome/3',
'Welcome3': '/welcome/4',
'Welcome4': '/start',
}
export const Welcome = defineComponent({
setup: (props, context) => {
...
const route = useRoute()
const router = useRouter()
const replace = throttle(() => {
const name = (route.name || 'Welcome1').toString()
router.replace(pushMap[name])
}, 500)
...
return () => <div class={s.wrapper}>
...
</div>
}
})
FunctionalComponent 和 defineComponent
[Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup().
First 组件是函数式组件,使用到 useSwipe,而 useSwipe 中用到了 onMounted 和 unMounted,改成 defineComponent
这个不用改,因为后面把 useSwipe 移到外层 Welcome 组件用了,知道提醒信息什么意思即可
自定义 Hook 钩子
useSwipe 添加可选 option
interface Options {
beforeStart?: (e: TouchEvent) => void
afterStart?: (e: TouchEvent) => void
beforeMove?: (e: TouchEvent) => void
afterMove?: (e: TouchEvent) => void
beforeEnd?: (e: TouchEvent) => void
afterEnd?: (e: TouchEvent) => void
}
watch vs. watchEffect
watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch
只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。
懒执行副作用
更加明确是应该由哪个状态触发侦听器重新执行
可以访问所侦听状态的前一个值和当前值
watchEffect
则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。
节流 throttle
export const throttle = (fn: Function, time: number) => {
let timer: number | undefined = undefined
return (...args: any[]) => {
if (timer) {
return
} else {
fn(...args)
timer = setTimeout(() => {
timer = undefined
}, time)
}
}
}
TS 内置类型
- Record<K,T>
将 K 的每一个值都定义为 T 类型