vue3hook

0.0.5 • Public • Published

vue3hook

介绍

vue3hook 是针对 vue3.x 的一款 composition api 的工具库

安装:

npm install --save vue3hook

使用:

import { useRequest } from 'vue3hook'

Api Table of Contents

useRequest

Demo:

<template>
<div class="list-page">
  <div v-if="getListReq.state.loading">loading...</div>
  <div v-if="getListReq.state.error">{{ getListReq.state.error }}</div>
  <div v-if="getListReq.state.data">
    <div v-for="item in getListReq.state.data"></div>
  </div>
</template>
<script>
const testPromise = (testData, timeout) =>
  new Promise(resolve => {
    setTimeout(() => {
      resolve(testData)
    }, timeout || 500)
  })
export default {
  setup() {
    const getList = () => testPromise([])
    const getListReq = useRequest(getList, {
      auto: true,
    })
    return {
      getListReq,
    }
  }

</script>

Config:

<script>
  const {
    // 请求的结果集合
    states,
    // 没有设置 fetckKey 时候,默认的结果
    state: states['_default'],
    // 主动发起请求
    run,
    // 中断请求
    cancel,
    // 中断请求,并重置 state
    reset,
    // 根据 fetchKey 获取对应的 state
    getState,
    // 对 run 进行 debounce
    runDebounce,
    // 对 run 进行 throttle
    runThrottle,
    // 轮询 run
    runPolling,
  } = useRequest(
    // 返回 promise 对象的函数
    fetcher: () => Promise,
    {
      // 请求设定的 key,用来设置并发
      fetchKey: () => {},
      // 默认的 state.data 为 undefined,可以通过此设置默认的数据类型
      dataType: () => {},
      // 设置默认的请求参数,参数会被传给 fetcher
      defaultParams: () => {},
      // 如何处理 fetcher 返回的数据,默认是直接赋值给 state.data
      updater: (state, data) => {
        state.data = data
      },
      // 当 fetcher 成功后的回调
      onSuccess: () => {},
      // 当 fetcher 失败后的回调
      onError: () => {},
      // 设置 debounce 相关参数,同 lodash.throttle
      debounceWait: 0,
      debounceOptions: {},
      // 设置 throttle 相关参数,同 lodash.throttle
      throttleWait: 0,
      throttleOptions: {},
      // 设置轮询请求的间隔时间
      pollingInterval: 1000,
      // 是否自动触发 fetcher 请求
      auto: false,
    }
  )
</script>

useQuickState

Demo:

<template>
  <form>
    <form-item label="name">
      <input v-model="writeQState.state.name" />
    </form-item>
    <form-item label="gender">
      <input v-model="writeQState.state.gender" />
    </form-item>
    <button @click="writeState.reset">Reset</button>
  </form>
</template>
<script>
  export default {
    setup() {
      const writeQState = useQuickState({
        name: '',
        gender: '',
      })
      return {
        writeQState,
      }
    },
  }
</script>

Config:

const {
  // 传入的 params,比如:state.name, state.gender
  state,
  // 原始数据的备份,深拷贝
  backupState,
  // 拷贝一份当前的 state,深拷贝
  clone,
  // 重置 state 为原始数据,行为同 lodash.clonedeep
  reset,
  // 对 state 进行 assign,assign 行为同 lodash.assign
  assign: newParams => assign(state, newParams),
  // 拷贝一份原始数据,深拷贝
  cloneBackup,
} = useQuickState(params = {})

useSwitch

Demo:

<template>
  <dialog v-model="detailSwitch.state.value"></dialog>
</template>
<script>
  export default {
    setup() {
      const detailSwitch = useSwitch()
      return {
        detailSwitch,
      }
    },
  }
</script>

Config:

const {
  // state.value
  state,
  // 设置 value 为 true
  on,
  // 设置 value 为 false
  off,
  // 切换 on 和 off
  toggle,
  // 设置 value,用来做多状态切换
  setValue,
  // 判断 value,用来做多状态切换
  isValue,
} = useSwitch((initValue = false))

useRouteQueryChange

Demo:

<script>
  // 监听 route 参数变化
  export default {
    setup() {
      useRouteQueryChange({ callback: () => {} })
    },
  }
</script>

Config:

useRouteQueryChange({
  // 是否在组件初始化时候立即执行一次,时机为 created
  immediate: true,
  // 要执行的函数
  callback: () => {},
})

usePageSearch

Demo:

// 在搜索列表页,我们经常需要把搜索参数挂到 url 上,并能从 url 上同步参数到搜索参数
<template>
  <form>
    <form-item label="name">
      <input v-model="searchQState.state.name" />
    </form-item>
    <form-item label="gender">
      <input v-model="searchQState.state.gender" />
    </form-item>
    <button @click="pageSearch.reset">Reset</button>
    <button @click="pageSearch.search">Search</button>
  </form>
</template>
<script>
  export default {
    setup() {
      const searchQState = useQuickState({
        name: '',
        gender: '',
      })
      const pageSearch = usePageSearch({
        quickState: searchQState,
        onSearch: () => {
          // listReq.run()
        },
      })
      return {
        searchQState,
        pageSearch,
      }
    },
  }
</script>

Config:

const {
  // 此方法会把请求参数挂到 url 上,并触发传入的 onSearch 方法
  search,
  // 此方法会把 url 上的参数清空,并触发传入的 onSearch 方法
  reset,
} = usePageSearch({
  // 这是一个 quickState 类型对象,请用上面的 useQuickState 生成
  quickState: useQuickState(),
  // 定义在把参数挂到 url 上的时候如何序列化和反序列化
  format: {
    // 参数名
    gender: {
      // 序列化
      stringify: (value) => value,
      // 反序列化
      parse: (value) => parseInt(value),
    },
  },
  // 当执行 search 方法时候或者 router 参数变化时候触发的回调
  onSearch: () => {},
})

useMouse

Demo:

// state: { screenX, screenY, clientX, clientY, pageX, pageY }
const { state, start, stop } = useMouse(() => {
  console.log('mouse move')
})
start()
stop()

useFingerMouse

Demo(移动端使用):

const { state, start, stop } = useFingerMouse(() => {
  console.log('mouse move')
})
start()
stop()

useMove

Config:

const move = useMove([options])

Demo:

<template lang="pug">
  <div @mousedown="(e) => move(e, divPos)" :style='{ left: divPos.x + "px", top: divPos.y + "px" }'>
    move me
  </div>
</template>
<script>
  import { useMove } from 'vue3hook'
  import { reactive } from 'vue'
  export default {
    name: 'Mouse',
    setup() {
      const divPos = reactive({ x: 100, y: 100 })
      const move = useMove({
        onMove: (pos, moveDistance) => {
          pos.x = Math.max(0, pos.x)
          pos.y = Math.max(0, pos.y)
          console.log('on move', pos)
        },
        onMoveEnd: (pos) => console.log('on move end', pos),
      })
      return {
        divPos,
        move,
      }
    },
  }
</script>

useFingerMove

Config:

const move = useFingerMove([options])

Demo(移动端使用):

<template lang="pug">
  <div
    @touchstart="(e) => move(e, divPos)"
    :style='{ left: divPos.x + "px", top: divPos.y + "px" }'
  >
    move me
  </div>
</template>
<script>
  import { useFingerMove } from 'vue3hook'
  import { reactive } from 'vue'
  export default {
    name: 'Mouse',
    setup() {
      const divPos = reactive({ x: 100, y: 100 })
      const move = useFingerMove({
        onMove: (pos, moveDistance) => {
          pos.x = Math.max(0, pos.x)
          pos.y = Math.max(0, pos.y)
          console.log('on move', pos)
        },
        onMoveEnd: (pos) => console.log('on move end', pos),
      })
      return {
        divPos,
        move,
      }
    },
  }
</script>

useFullscreen

Config

const { state, setFull, exitFull, toggleFull } = useFullscreen(target, [options])

Demo

<template>
  <div class="fullscreen" ref="div">
    <div>{{ fullscreen.state.value }}</div>
    <el-button-group>
      <el-button @click="fullscreen.setFull()"> setFull </el-button>
      <el-button @click="fullscreen.exitFull()"> exitFull </el-button>
      <el-button @click="fullscreen.toggleFull()">toggleFull</el-button>
    </el-button-group>
  </div>
</template>
<script>
  import { useFullscreen } from 'vue3hook'
  export default {
    name: 'Fullscreen',
    setup() {
      const div = ref(null)
      const fullscreen = useFullscreen(() => div.value, {
        onFull: () => console.log('full'),
        onExitFull: () => console.log('exit full'),
      })
      return {
        fullscreen,
        div,
      }
    },
  }
</script>

useInterval

Config

const { state, start, stop, restart } = useInterval(callback, (delay = 1000), (immediate = true))

Demo

<style lang="sass" scoped></style>
<template lang="pug">
  <el-button @click="msgCountdown.restart" , :disabled="msgCountdown.state.activated">
    {{ msgCountdownValue }}
  </el-button>
</template>
<script>
  import { useInterval, useComputed } from 'vue3hook'
  export default {
    name: 'Interval',
    setup() {
      const msgCountdown = useInterval(
        () => {
          if (msgCountdown.state.counter >= 5) msgCountdown.stop()
        },
        1000,
        false,
      )
      useComputed('msgCountdownValue', () =>
        msgCountdown.state.activated ? 5 - msgCountdown.state.counter : '点击发送',
      )

      return { msgCountdown }
    },
  }
</script>

useTimeout

Config

const { start, stop } = useTimeout(callback, (delay = 1000), (immediate = true))

Demo

<template lang="pug">
  .timeout h2 test timeout el-button-group el-button(@click='timeout.stop') 停止
  el-button(@click='timeout.start') 开始
</template>
<script>
  import { useTimeout } from 'vue3hook'
  export default {
    name: 'Timeout',
    setup() {
      const timeout = useTimeout(() => {
        console.log('test timeout')
      })
      return {
        timeout,
      }
    },
  }
</script>

useTitle

Config

const state = useTitle((title = document.title), (restoreOnUnmount = false))

Demo

<template lang="pug">
  .title h2 test title div 页面加载时候改标题为 “你好” div 2s 后改标题为 “世界” a(href='#/move')
  离开此页面,标题还原为默认标题
</template>
<script>
  import { useTitle, useTimeout } from 'vue3hook'
  export default {
    name: 'Timeout',
    setup() {
      const title = useTitle('你好', true)
      useTimeout(() => {
        title.value = '世界'
      }, 2000)
      return {
        title,
      }
    },
  }
</script>

useCountdown

Config

// state = {
//   targetDate
//   countdown
//   formatted: {
//     days
//     hours
//     minutes
//     seconds
//     milliseconds
//   },
// )
const state = useCountdown(targetDate, (interval = 1000))

Demo

<template lang="pug">
  <p>
    There are {{ countdown.formatted.days }} days {{ countdown.formatted.hours }} hours {{
    countdown.formatted.minutes }} minutes {{ countdown.formatted.seconds }} seconds {{
    countdown.formatted.milliseconds }} milliseconds until {{ countdown.targetDate }}
  </p>
</template>
<script>
  import { useCountdown, useTimeout } from 'vue3hook'
  import { computed } from 'vue'
  export default {
    name: 'Countdown',
    setup() {
      const countdown = useCountdown()
      useTimeout(() => {
        countdown.targetDate = '2021-12-31 24:00:00'
      }, 1000)

      const msgCountdown = useCountdown()
      const msgCountdownValue = computed(() =>
        msgCountdown.countdown ? Math.round(msgCountdown.countdown / 1000) + 's' : '发送验证码',
      )
      return { countdown, msgCountdown, msgCountdownValue }
    },
  }
</script>

useWheel

Demo

<template lang="pug">
  <div>(:style='{ transform: "scale(" + zoomState.value + ")" }')</div>
</template>
<script>
  import { reactive } from 'vue'
  import { useWheel } from 'vue3hook'
  export default {
    name: 'Wheel',
    setup() {
      const zoomState = reactive({
        value: 1,
      })
      const zoom = (type = '+') => {
        if (type === '+') {
          zoomState.value *= 1 + 0.015
        } else {
          zoomState.value /= 1 + 0.015
          zoomState.value = Math.max(0.1, zoomState.value)
        }
      }
      const wheel = useWheel((delta) => {
        if (delta > 0) {
          zoom('+')
        } else {
          zoom('-')
        }
      })
      wheel.start()
      return {
        zoomState,
      }
    },
  }
</script>

Readme

Keywords

none

Package Sidebar

Install

npm i vue3hook

Weekly Downloads

8

Version

0.0.5

License

none

Unpacked Size

125 kB

Total Files

42

Last publish

Collaborators

  • bravf