zoukankan      html  css  js  c++  java
  • vue中使用vuex管理各种状态

    要使用vuex首先得安装然后引入,在项目的src目录下建立store文件夹,分别新建state,js,mutation.js,index.js.getter.js,actions.js

    state.js,存储了组件之间需要共享的变量:

    import {
      playMode
    } from '@/utils/config.js'
    const state = {
      // 歌手信息:
      singer: {},
      // 是否正在播放音乐
      playing: false,
      // 播放器展开或者收起:
      fullScreen: false,
      // 播放的列表:
      playList: [],
      // 顺序列表
      sequenceList: [],
      // 播放模式:
      mode: playMode.sequence,
      // 当前播放歌曲的索引:
      currentIndex: -1
    }
    export default state
    

     其中播放模式可以从外部引用,方便语义化的管理 config.js:

    // 配置文件:
    
    // 播放模式:
    export const playMode = {
      // 顺序播放:
      sequence: 0,
      // 循环播放:
      loop: 0,
      //   随机播放:
      random: 2
    }
    

     mutations.js定义了修改state的方法

    const matutaions = {
      SET_SINGER(state, singer) {
        state.singer = singer
      },
      SET_PLAYING_STATE(state, flag) {
        state.playing = flag
      },
      SET_FULL_SCREEN(state, flag) {
        state.fullScreen = flag
      },
      SET_PLAYLIST(state, list) {
        state.playList = list
      },
      SET_SEQUENCE_LIST(state, list) {
        state.sequenceList = list
      },
      SET_PLAY_MODE(state, mode) {
        state.mode = mode
      },
      SET_CURRENT_INDEX(state, index) {
        state.currentIndex = index
      }
    }
    export default matutaions
    

     getters.js类似于组件中computed,可以对mutations的数据再处理,也可以直接拿到state的数据

    // 重新包装一下方便直接从组件中拿到数据
    export const singer = state => state.singer
    
    export const playing = state => state.playing
    
    export const fullScreen = state => state.fullScreen
    
    export const playList = state => state.playList
    
    export const sequenceList = state => state.sequenceList
    
    export const mode = state => state.mode
    
    export const currentIndex = state => state.currentIndex
    
    // 获取当前播放歌曲
    export const currentSong = (state) => {
      return state.playList[state.currentIndex] || {}
    }
    

    actions可以同时提交多个mutations,一些异步方法也可以在这里使用

    // 同时操纵多个mutation可以使用actions;
    
    // 封装多个mutations:
    export const selectPlay = function ({
      commit,
      state
    }, {
      list,
      index
    }) {
      console.log(state);
    
      commit('SET_SEQUENCE_LIST', list)
      commit('SET_PLAYLIST', list)
      commit('SET_CURRENT_INDEX', index)
      commit('SET_FULL_SCREEN', true)
      commit('SET_PLAYING_STATE', true)
    }
    

    在歌手列表页点击歌手之后需要跳转到歌手详情,同时需要把歌手信息传递进去,方法一可以用参数传递的方式,方法二传递歌手ID直接再歌手详情页面,重新获取数据,方法三可以直接使用 vuex

    在这里使用vuex,因为要改变state,所以引入 mapMutations,

    先引入mapMutations

    import { mapMutations } from "vuex";
    

    methods中展开mutations,SET_SINGER为mutations中的方法名

        ...mapMutations({
          setSinger: "SET_SINGER"
        })
    

     点击事件传递item给mutation 

    this.setSinger(item); 传递item

        Todetail(item) {
          // console.log(item);
          this.$router.push({
            path: `/singer/${item.id}`
          });
          // 实际调用了this.$store.commit('setSinger',item)....
          this.setSinger(item);
        },  

     歌手详情页的头部需要用到vuex中保存的歌手信息

     在singer-detail组件中的computed方法中定义getters:

    import { mapGetters } from "vuex";
    

     

        ...mapGetters(["singer"]),
        title() {
          return this.singer.name;
        },
        bgImage() {
          return this.singer.avatar;
        }
    

     因为这个音乐列表在其他歌单列表也会用到,所以抽象成组件,把参数作为props传递进去

    前面因为传递了歌手id,所以可以根据这个id去获取该歌手的top50首歌

          const { artist, hotSongs } = await getSingerMusic(this.singer.id);
          // 歌手信息
          this.artistInfo = artist;
          // 热门歌曲
          this.hotSongs = hotSongs;
    

     解构出的artist保存着歌手更全的信息

     

        

    hotSongs保存着那50首歌曲的信息

      

       这同样是没法用的,所以也需要一个格式化函数获取需要的数据

    需要的是歌曲id,歌单id,唱这首歌的全部歌手,姓名(主唱),专辑,播放时长,图片

    在common文件夹中新建一个song.js

    歌曲的播放地址需要通过id发送请求再获得

    //获取歌曲播放地址
    export const getsongUrl = p => get(`/song/url`, p)
    

    song.js中引入

    import {
      getsongUrl,
    } from "@/request/api.js";
    

    歌手可能有多个所以准备一个转换函数把数组转换成‘/’分割的字符串

    function filterSinger(singer) {
      let ret = [];
      if (!singer) {
        return ''
      }
      singer.forEach((s) => {
        ret.push(s.name)
      })
      return ret.join('/')
    }  

    定义一个构造函数

    export default class Song {
      constructor({
        id,
        mid,
        singer,
        name,
        album,
        duration,
        image,
    
      }) {
        this.id = id;
        this.mid = mid;
        this.singer = singer;
        this.name = name;
        this.album = album;
        this.duration = duration;
        this.image = image;
        getsongUrl({
          id: this.id
        }).then(res => {
          // console.log(res.data[0]);
          this.url = res.data[0].url
        })
      }
    }
    

     导出一个歌曲生成的构造函数,参数是全部数据的data,根据参数返回需要的结果

    export function createSong(musicData) {
      return new Song({
        id: musicData.id,
        mid: musicData.al.id,
        singer: filterSinger(musicData.ar),
        duration: musicData.duration ? musicData.duration : musicData.dt ? musicData.dt : '',
        name: musicData.name,
        album: musicData.al.name,
        image: musicData.al.picUrl + '?param=300y300',
        url: musicData.id
      })
    }  

    回到singer-detail,引入这个函数

    import { createSong } from "@/common/song";
    

     定义格式化函数,在执行函数时确保id存在

        _normalizeSongs(list) {
          let ret = [];
          list.forEach(item => {
            // console.log(item);
            if (item.id && item.al.id) {
              ret.push(createSong(item));
            }
          });
          return ret;
        }  

    使用该函数

          // 热门歌曲
          this.songs = this._normalizeSongs(hotSongs);
          console.log(this.songs);
    

     可以看到那50首歌都格式化好了

     

      最后把数据给子组件就好了

      <music-list :songs="songs" :bg-image="bgImage" :title="title"></music-list>
    

      

     

     

      

      

      

      

     

     

  • 相关阅读:
    雅虎天气API调用
    HttpOperater
    HttpOperater-模拟HTTP操作类
    页面局部加载,适合Ajax Loading场景(Demo整理)
    FTPHelper-封装FTP的相关操作
    使用SOCKET实现TCP/IP协议的通讯
    IIS目录禁止执行权限
    Oracle10g 安装步骤
    SQL Server 2008、SQL Server 2008R2 自动备份数据库
    SQL列转行
  • 原文地址:https://www.cnblogs.com/rmty/p/12973965.html
Copyright © 2011-2022 走看看