「折腾」Vue 简单的状态管理实践

吐槽/反馈/建议:我的咸鱼心  爱发电-@wdssmq

正式接触 Vue.js 也两年多了,实际写过的项目好像也就 4 个?「基于 Vite」

另外还试过 mpvue 和 taro 写小程序 —— 同样的功能需求,用两个框架加 Vue 分别实现了一遍;

最早写作为 Z-BlogPHP 主题的 vite_zbp_vue_TestType 项目时,使用了 Vuex 管理状态,后来官方推荐换 Pinia,然而一直懒得更新,实际上两者具体使用上的区别也还没了解清楚;再然后,以这个项目来说,可能不用专门的状态管理大概也可以?

用响应式 API 做简单状态管理 | Vue.js

https://cn.vuejs.org/guide/scaling-up/state-management.html#simple-state-management-with-reactivity-api

然后目前的第四个项目是一个集成 DPlayer 的在线视频播放器,作品 + 分集切换的实现就需要用到状态管理,算是一个很恰当的实践;

下边是实现思路的讲解 ——

· 封装一个 store 对象用于全局状态管理;

· 对于状态属性的读写,以及和 localStorage 的交互,封装为相应方法;

// store.ts

// 引入响应式 API 和 localStorage 的封装
import { reactive } from 'vue'
import { useStorage } from '@vueuse/core'

// 省略了一些类型定义和具体方法的实现

const lsStore = useStorage('lsStore', { lst_work: 0 } as TypeLsStore)

export const store = reactive({
  // 当前剧集信息
  work_id: 0,
  work_name: '',
  work_ep: 1,
  work_ep_time: 0,
  work_ep_max: 0,
  // 剧集列表
  work_list: [] as TypeData['items'],
  // 初始化
  init: (list: TypeData['items']) => {
    // 写入剧集列表
    store.work_list = list
    // 切换到上次播放的作品
    store.changeWork(lsStore.value.lst_work)
  },
  // 作品切换
  changeWork: (id: number) => {
  },
  // 剧集切换
  changeEp: (ep: number) => {
  },
  // 判断并读取上次播放记录,第几集的第几秒
  getProg: () => {
  },
  // 写入播放记录
  setProg: () => {
    lsStore.value[store.work_id] = {
      lst_ep: store.work_ep,
      lst_ep_time: store.work_ep_time,
    }
  },
})

· 只有一个 App.vue 页面,所以不需要路由;

<script setup lang="ts">
// 引入 API 和状态管理对象
import { computed } from 'vue'
import { store } from './base/store'

// 其他组件、数据处理等
// ...

// 初始化状态
store.init(data.items)

// 分页切换后,将新的“页码”更新到 store
function pageChange(type: string, page: number) {
  if (type === 'ep') {
    store.changeEp(page)
  } else if (type === 'works') {
    store.changeWork(page - 1)
  }
}

// ↑ 分页组件内绑定点击事件,向上传递给父组件内监听函数,更新 store 状态后把切换效果渲染回分页组件;
// ↑ 这里可以在分页组件内直接更新 store 状态,切换函数放在分页组件自身,具体取舍看实际需要;
// dplayer 组件内有自动续播及时间进度记录之类的,所以就选择了直接更新 store 状态;

// 作品分页信息
const worksPageInfo = computed(() => {
  return {
    name: '作品列表',
    type: 'works',
    page: store.work_id + 1,
    items: store.work_list,
  }
})

// 分集翻页信息
const epPageInfo = computed(() => {
  return {
    name: '分集列表',
    page: store.work_ep,
    type: 'ep',
    total: store.work_list[store.work_id].maxP,
  }
})

// 当「状态」变化时,会重新获取视频数据,以及上边的分页信息
const dplayerInfo = computed(() => {
  return buildDplayerInfo(data as TypeData, store.work_id, store.work_ep)
})

</script>

<!-- ↓↓ computed 封装的数据更新时,会触发相应的组件重新渲染 ↓↓ -->

<template>
  <!-- 视频播放器调用 -->
  <dplayer :dplayerInfo="dplayerInfo"></dplayer>
  <!-- 分集翻页 -->
  <pagebar :pageInfo="epPageInfo"
           @page-change="pageChange"></pagebar>
  <!-- 作品列表分页 -->
  <pagebar :pageInfo="worksPageInfo"
           @page-change="pageChange"></pagebar>
</template>

「- -」「- -」「- -」「- -」「- -」「- -」「- -」「- -」

然后这个 Vue DPlayer 项目写在了私有 Git 里,有兴趣的加 QQ 群下载吧……

· 各种 QQ 群

咸鱼自习室: 576621997

我的咸鱼心: 189574683

· 作品信息

Vue 集成 DPlayer | 作品 + 分集切换

Vite + Vue3 + TypeScript + DPlayer

针对每部作品记录播放进度(localStorage);

· 附图

001.png

002.png


爱发电

本文标题:《「折腾」Vue 简单的状态管理实践》作者:沉冰浮水
原文链接:https://www.wdssmq.com/post/20220810247.html
特别注明外均为原创,转载请注明。

分享到微信

扫描二维码

可在微信查看或分享至朋友圈。

相关文章

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

网站分类

  • 订阅本站的 RSS 2.0 新闻聚合

搜索

本周旧文

近期观影记录:超级马里奥,死侍与金刚狼。。

搬家也告一段落,虽然搬过来的东西还得归置,新衣柜虽说已经散俩月味儿了,但还是不想放衣服进去。

要不我每年汇总整理一次??碎雨集_沉冰浮水_第1页

所以,不带这条的话,2024 年目前只发了 13 条嘟????

VSCode 内 git 操作卡住的时候没办法主动取消一直是个痛点,一般都是推送或拉取,今天连提交都卡了。。

又一个夏天过去了,所以今年也没买防水鞋套;然后天凉了,为了应对踢被子买了睡袋,不知道 1.2 米会不会略窄。。

《五至七时的克莱奥》,2018 年 6 月加入列表,21 年 11 月底发现 B 站上线了这部,直到前几天才看完,还是分两次看的。。接下来有五项是 2019 年的,都是电影 —— 略长的待办列表。。

有用程序自动抓取自己带 tag 的嘟,然后按年备份后从线上删除;刚发现去年的数据有备份但是没删线上??和本地数据对比后发现线上的还少一条,Why??

本质上,每个人需要的是「让自己面临的问题得到解决」的能力。。

这又涉及到直接能力和间接能力,,缺乏直接能力很正常,视情况可以通过学习来掌握直接能力,或者「请」有直接能力的人来帮自己解决。。

缺乏间接能力的情况是真没救,尤其是对「这是**我自己**面临的问题」这一前提没有明确认知的人。。

其实,在认知意义上,焦虑时我知道这种情绪对应「焦虑」这个文法词汇,此外还有「压抑」「悲伤」等等,然而「抑郁」其实是个我认知体系外的词,虽然经常一些情绪感受我找不到对应的语言词汇来表述,却也只能将其实表述为「找不到对应的语言词汇来表述」的某些感受。。

爱发电支持者

最新留言

友情链接