vue3.0+ts+pinia移动端实现下拉刷新

首先下拉刷新功能就是为了让用户拿到最新的内容,提高用户体验。 实现思路:监听用户的在屏幕上的操作,用touchstart监听用户手指触摸屏幕, touchmove监听用户手指滑动, touchend监听用户手指离开屏幕。

先进行布局 Pull.vue

  <div class="pull" ref="pull">
    <div class="pull-top" ref="pullTop">
      <div class="loading" ref="span">
      </div>
    </div>
    <div class="pull-box">
    </div>
  </div>

css样式布局

.pull {
  width: 100vw;

  .pull-top {
    width: 100vw;
    background-color: hotpink;
    .loading {
      text-align: center;
    }
  }

  .pull-box {
    width: 100vw;
    height: 100vh;
    background-color: skyblue;
  }
}

创建一个Pull.ts文件( .ts文件名与.vue的文件名要一致)

在pull.ts文件中首先需要获取最大的盒子pull ,在获取第一个子盒子 pullTop

const pull = ref<HTMLDivElement>()

const pullTop = ref<HTMLDivElement>()

const span = ref<HTMLDivElement>()

onMounted里面首先在touchstart中获取用户手指在屏幕上 的初始位置(使用 e.changedTouches[0].pageY,将这个初始值保存起来 (disY) ,同时还需要清除过渡,将transition为nonoe,其次在touchmove事件里获取手指的移动位置(e.changedTouches[0].pageY) ,用这个值减去初始值,就是用户滑动的距离,将这个值保存起来(Y),然后在把这个值(Y)赋给下拉刷新的盒子的高然后在手指离开的时候,判断一下下拉的距离是否大于等于60如果要是符合条件,就把这个Y设置为40,然后再设置一个定时器让他在1秒以后让这个值(Y)设置为0;然后再将这个(Y)的设置为下拉刷新盒子的高度;然后还要让他阻尼,阻尼的时候在(touchmove )的时候去设置,刚开始的时候先在(onMounted)获取整个屏幕的可视区的高度,然后让这个高度 / 150;这个150也就是超过150阻尼的效果才会明显,然后在将原来的Y值 / 阻尼的结果 赋值给下拉刷新盒子的高度,然后还要设置一个过渡的效果在(touchend)的时候设置一下transition,然后在让刚开始的时候要清空一下transition   然后还要解除绑定事件,touchmove和touchend设置为null。下拉的时候会把整个页面拉下来 所以要设置一下阻止默认事件用 ev.preventDefault && ev.preventDefault()

完整的Pull.vue代码

<template>
  <div class="pull" ref="pull">
    <div class="pull-top" ref="pullTop">
      <div class="loading" ref="span">
      </div>
    </div>
    <div class="pull-box">
    </div>
  </div>
</template>
  
<script setup lang="ts">
import { pulldownStore } from '@/store/Pull'
import { storeToRefs } from 'pinia'
const LoginStore = pulldownStore()

const { pull, pullTop, span } = storeToRefs(LoginStore)
const { } = LoginStore

</script>
  
<style scoped lang="less">
.pull {
  width: 100vw;

  .pull-top {
    width: 100vw;
    background-color: hotpink;
    overflow: hidden;

    .loading {
      text-align: center;
    }
  }

  .pull-box {
    width: 100vw;
    height: 100vh;
    background-color: skyblue;
  }
}
</style>

完整的Pull.ts的代码

import { defineStore } from 'pinia'
import { ref, onMounted } from 'vue'

export const pulldownStore = defineStore('pull', () => {
  const Position = {
    disY: 0,
    Y: 0,
    height: 0,
    timer: 0,
    scale: 0,
  }
  const pull = ref<HTMLDivElement>()
  const pullTop = ref<HTMLDivElement>()
  const span = ref<HTMLDivElement>()

  const FnStart = (e: TouchEvent) => {
    pullTop.value!.style.transition = 'none'
    Position.disY = e.changedTouches[0].pageY - Position.Y
    document.ontouchmove = FnMove
    document.ontouchend = FnEnd
  }

  const FnMove = (e: TouchEvent) => {
    if (Position.Y > 35) {
      span.value!.textContent = '下拉刷新'
    }
    if (Position.Y > 60) {
      span.value!.textContent = '释放刷新'
    }
    Position.Y = e.changedTouches[0].pageY - Position.disY
    Position.scale = Position.height / 150
    Position.Y = Position.Y / Position.scale
    pullTop.value!.style.height = Position.Y + 'px'
  }

  const FnEnd = () => {
    clearTimeout(Position.timer)
    pullTop.value!.style.transition = `.3s ease-in height`
    if (Position.Y >= 60) {
      span.value!.textContent = '刷新中'
      Position.Y = 40
      Position.timer = setTimeout(() => {
        Position.Y = 0
        pullTop.value!.style.height = Position.Y + 'px'
        span.value!.textContent = '刷新成功'
      }, 1000)

    } else {
      span.value!.textContent = ''
      Position.Y = 0
    }
    pullTop.value!.style.height = Position.Y + 'px'

  }
  onMounted(() => {
    pull.value!.ontouchstart = FnStart
    Position.height = document.documentElement.clientHeight
  })

  return {
    pull,
    pullTop,
    span
  }
})

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是搭建 Vue 3.0 + Vite + Pinia + TypeScript 的步骤: 1. 安装 Node.js,推荐使用 LTS 版本。 2. 安装 Vite: ``` npm init vite-app my-project ``` 这里我们使用 Vite 初始化一个新项目,名称为 my-project。 3. 安装依赖: ``` cd my-project npm install ``` 4. 安装 Vue 3.0: ``` npm install vue@next ``` 5. 安装 Pinia: ``` npm install pinia ``` 6. 安装 TypeScript: ``` npm install --save-dev typescript ``` 7. 配置 TypeScript: 在项目根目录下创建 `tsconfig.json` 文件,内容如下: ```json { "compilerOptions": { "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "sourceMap": true, "moduleResolution": "node", "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx"], "exclude": ["node_modules"] } ``` 8. 安装 Pinia Devtools(可选): ``` npm install @pinia/devtools --save-dev ``` 9. 在 `main.ts` 中进行配置: ```typescript import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) // 创建 Pinia 实例 const pinia = createPinia() // 将 Pinia 实例挂载到 app 上 app.use(pinia) app.mount('#app') ``` 10. 编写组件: 在 `src` 目录下创建一个 `components` 目录,然后创建一个 `HelloWorld.vue` 组件: ```vue <template> <div> <h1>Hello, {{ name }}</h1> <button @click="increase">Increase</button> <p>{{ count }}</p> </div> </template> <script lang="ts"> import { defineComponent } from 'vue' import { useStore } from 'pinia' export default defineComponent({ name: 'HelloWorld', setup() { const store = useStore() const name = store.getters.getName const count = store.state.count const increase = () => { store.commit('increase') } return { name, count, increase } }, }) </script> ``` 11. 在 `App.vue` 中使用组件: ```vue <template> <HelloWorld /> </template> <script lang="ts"> import { defineComponent } from 'vue' import HelloWorld from './components/HelloWorld.vue' export default defineComponent({ name: 'App', components: { HelloWorld, }, }) </script> ``` 12. 运行项目: ``` npm run dev ``` 至此,我们已经成功搭建了 Vue 3.0 + Vite + Pinia + TypeScript 的项目。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值