首页 前端知识 vue3 vite ts中pinia的基本使用

vue3 vite ts中pinia的基本使用

2024-08-18 22:08:13 前端知识 前端哥 582 160 我要收藏

注释很详细,直接上代码

温馨提示:本博客建立在ElementPlus组件库pinia及其持久化插件已安装的前提下,前两者很容易找到相应博客,后者可能会踩坑,此处附上另一篇博客

vue3+vite+ts+pinia实现持久化存储

项目结构:

在这里插入图片描述

源码:

other.ts

import {ref,computed} from "vue";
import {defineStore} from "pinia";

export const useOtherStore = defineStore(
    "other",
    () => {
        let useLessMess=ref('ggggg');

        let doubleMess = computed(() => {
            return useLessMess.value+useLessMess.value;
        }) 

        let getDoubleMess=()=>{
            return doubleMess.value;
        }
        return {getDoubleMess}
    }
)

video.ts

import { ref, computed } from "vue";
import { defineStore } from "pinia";
import {useOtherStore} from "./other";
import axios from "axios";

export const useVideoStore = defineStore(
  "video",
  () => {
    /**
     * 当前播放视频索引
     */
    let videoIndex = ref(0);

    /**
     * 当前播放视频地址                          
     */
    let videoUrl = computed(() => {
      return videoUrlList.value[videoIndex.value];
    });

    /**
     * 视频地址列表
     */
    let videoUrlList = ref<string[]>([]);

    /**
     * 上一曲按钮是否可用
     */
    let isPreviousButtonShow = computed(() => {
      return !(videoIndex.value == 0);
    });

    /**
     * 下一曲按钮是否正在加载中
     */
    let isNextButtonLoading = ref(false);

    /**
     * 初始化
     * @returns {void}
     */
    function init() {
      //如果没有视频则获取视频
      if (videoUrlList.value.length == 0) {
        getVideoJson(false);
      }
    }

  /**
   * 获取视频Json
   * @param {boolean} [op=true] -是否是初始化以外的操作
   * @returns {void}
   */
    function getVideoJson(op: boolean = true) {
      axios
        .get("http://api.treason.cn/API/nan.php")
        .then(function (response) {
          const data = response.data;
          //判断是否重复
          if (op && videoUrlList.value.find((item) => item == data)) {
            console.log("重复");
            getVideoJson();
          } else {
            //去掉最后两个字符
            const url = data.substring(0, data.length - 2);
            videoUrlList.value.push(url);
          }
        })
        .catch(function (error) {
          console.log(error);
        });
    }

    /**
     * 点击上一曲按钮
     */
    function previousVideo() {
      if (videoIndex.value > 0) {
        videoIndex.value--;
      }
    }

  
    /**
     * 点击下一曲按钮
     */
    async function nextVideo() {
      if (videoIndex.value < videoUrlList.value.length - 1) {
        videoIndex.value++;
      } else {
        isNextButtonLoading.value = true;
        await getVideoJson();
        isNextButtonLoading.value = false;
        videoIndex.value++;
      }
    }

    /**
     * 获取其他模块的数据
     */
    function getOtherData() {
      return useOtherStore().getDoubleMess();
    }

    return {
      /**
       * 当前播放视频索引
       * @type {number}
       */
      videoIndex,

      /**
       * 当前播放视频地址
       * @type {string}
       */
      videoUrl,

      /**
       * 视频地址列表
       * @type {Array<string>}
       */
      videoUrlList,

      /**
       * 上一曲按钮是否可用
       * @type {boolean}
       */
      isPreviousButtonShow,

      /**
       * 下一曲按钮是否正在加载中
       * @type {boolean}
       */
      isNextButtonLoading,

      /**
       * 初始化
       * @returns {void}
       */
      init,

      /**
       * 点击上一曲按钮
       * @returns {void}
       */
      previousVideo,

      /**
       * 点击下一曲按钮
       * @returns {void}
       */
      nextVideo,

      /**
       * 获取其他模块的数据
       * @returns {string}
       */
      getOtherData
    };
  },
  {
    persist:{
      key:"videoData",//可以指定存储的key(即存入的名字)
      storage:sessionStorage,//可以指定存储的存储方式:1. sessionStorage(会话储存,临时) 2. localStorage(本地储存,永久)
      // paths:["videoUrlList"]//可以指定需要存储的内容(计算属性别存啊,存了也无效的)
    }
  }
);

App.vue

<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useVideoStore } from "@/stores/video";
import { storeToRefs } from "pinia";
const videoStore = useVideoStore();
const { videoUrl, isPreviousButtonShow, isNextButtonLoading } =
  storeToRefs(videoStore);

const { init, previousVideo, nextVideo ,getOtherData} = videoStore;

/**
 * @type {boolean} -是否开启自动播放
 */
let isAuto = ref(false);

/**
 * 视频是否播放到结尾
 */
let isVideoEnd = ref(false);

/**
 * 视频播放到结尾
 */
function videoEndSlove() {
  isVideoEnd.value = true;
  if (isAuto.value) {
    setTimeout(() => {
      nextVideo();
    }, 1000)
  }
}

/**
 * 切换自动连播状态
 */
function switchSlove() {
  if (isVideoEnd.value && isAuto.value) {
    nextVideo();
  }
}

/**
 * 批量更新
 */
function usePatchJust(){
  //如果只是单个变量直接修改就行,当然得注意别修改const类型的地址

  videoStore.$patch(//没有改变内容,示范而已
    (state) => {
      state.isNextButtonLoading = state.isNextButtonLoading;
      state.videoUrlList = state.videoUrlList;
      state.videoIndex = state.videoIndex;
    }
  )
}

init(); //初始化一下
usePatchJust();//批量更新
console.log(getOtherData());//获取其他数据并输出

</script>

<template>
  <el-card class="el-card-class">
    <template #header>
      <div class="header-class">
        <div>懒大人演唱会</div>
        <div>
          <el-switch @change="switchSlove" v-model="isAuto" active-text="自动播放"></el-switch>
        </div>
      </div>
    </template>
    <template #default>
      <div>
        <video  @play="isVideoEnd = false" @ended="videoEndSlove" controls="true" autoplay :src="videoUrl"
          class="video-class"></video>
      </div>
    </template>
    <template #footer>
      <el-button type="primary" size="large" @click="previousVideo" :disabled="!isPreviousButtonShow">上一首</el-button>
      <el-button type="primary" size="large" @click="nextVideo"
        :loading="isNextButtonLoading">下一首</el-button></template>
  </el-card>
</template>

<style scoped>
.el-card-class {
  width: 1320px;
  height: 910px;
}

.header-class {
  display: flex;
  justify-content: space-between;
}

.video-class {
  width: 100%;
  max-width: 100%;
  /* 最大宽度 */
  height: 720px;
  object-fit: contain;
  /* 控制视频如何适应其框架 */
  border-radius: 5px;
}
</style>

main.ts

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

// 导入插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

import App from './App.vue'
import router from './router'

const app = createApp(App)

// 创建pinia,别创建多个了,看清楚昂
const pinia = createPinia()

// 使用pinia插件,插件是加在pinia实例上的而不是app,注意注意
pinia.use(piniaPluginPersistedstate)

app.use(pinia)//这步不能忘哇
app.use(router)

app.use(ElementPlus)
app.mount('#app')

效果演示

在这里插入图片描述

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16071.html
评论
发布的文章

无涯教程-HTML5 - MathML

2024-08-25 23:08:46

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!