用Vue3.0开发音乐Web app(视频源码齐)去网盘学习啦

用Vue3.0开发音乐Web appjavascript


Vue3.0高阶实战:开发高质量音乐Web app  vx(cmL46679910)css

  第5章的学习内容以下:播放器基础样式及歌曲播放功能开发 、播放器播放按钮的暂停与播放逻辑开发 、vue

<script>
  import Scroll from '@/components/base/scroll/scroll'
  import Confirm from '@/components/base/confirm/confirm'
  import AddSong from '@/components/add-song/add-song'
  import { ref, computed, nextTick, watch } from 'vue'
  import { useStore } from 'vuex'
  import useMode from './use-mode'
  import useFavorite from './use-favorite'

  export default {
    name: 'playlist',
    components: {
      AddSong,
      Confirm,
      Scroll
    },
    setup() {
      const visible = ref(false)
      const removing = ref(false)
      const scrollRef = ref(null)
      const listRef = ref(null)
      const confirmRef = ref(null)
      const addSongRef = ref(null)

      const store = useStore()
      const playlist = computed(() => store.state.playlist)
      const sequenceList = computed(() => store.state.sequenceList)
      const currentSong = computed(() => store.getters.currentSong)

      const { modeIcon, modeText, changeMode } = useMode()
      const { getFavoriteIcon, toggleFavorite } = useFavorite()

      watch(currentSong, async (newSong) => {
        if (!visible.value || !newSong.id) {
          return
        }
        await nextTick()
        scrollToCurrent()
      })

      function getCurrentIcon(song) {
        if (song.id === currentSong.value.id) {
          return 'icon-play'
        }
      }

      async function show() {
        visible.value = true

        await nextTick()
        refreshScroll()
        scrollToCurrent()
      }

      function hide() {
        visible.value = false
      }

      function selectItem(song) {
        const index = playlist.value.findIndex((item) => {
          return song.id === item.id
        })

        store.commit('setCurrentIndex', index)
        store.commit('setPlayingState', true)
      }

      function refreshScroll() {
        scrollRef.value.scroll.refresh()
      }

      function scrollToCurrent() {
        const index = sequenceList.value.findIndex((song) => {
          return currentSong.value.id === song.id
        })
        if (index === -1) {
          return
        }
        const target = listRef.value.$el.children[index]

        scrollRef.value.scroll.scrollToElement(target, 300)
      }

      function removeSong(song) {
        if (removing.value) {
          return
        }
        removing.value = true
        store.dispatch('removeSong', song)
        if (!playlist.value.length) {
          hide()
        }
        setTimeout(() => {
          removing.value = false
        }, 300)
      }

      function showConfirm() {
        confirmRef.value.show()
      }

      function confirmClear() {
        store.dispatch('clearSongList')
        hide()
      }

      function showAddSong() {
        addSongRef.value.show()
      }

      return {
        visible,
        removing,
        scrollRef,
        listRef,
        confirmRef,
        addSongRef,
        playlist,
        sequenceList,
        getCurrentIcon,
        show,
        hide,
        selectItem,
        removeSong,
        showConfirm,
        confirmClear,
        showAddSong,
        // mode
        modeIcon,
        modeText,
        changeMode,
        // favorite
        getFavoriteIcon,
        toggleFavorite
      }
    }
  }
</script>

播放器歌曲前进与后退逻辑开发 、 播放器 DOM 异常错误处理 、(视频资源vxcmL46679910)) java

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

播放器 歌曲播放模式相关逻辑开发 、 播放器 歌曲收藏功能相关逻辑开发(1) 、 播放器 歌曲收藏功能相关逻辑开发(2)、 播放器 进度条相关逻辑开发、 播放器 进度条相关逻辑开发(下) 、 播放器 cd 唱片旋转相关逻辑开发 、 播放器 歌词相关逻辑开发(01) 、 播放器 歌词相关逻辑开发(02) 、vuex

script>
  export default {
    name: 'tab',
    data() {
      return {
        tabs: [
          {
            name: '推荐',
            path: '/recommend'
          },
          {
            name: '歌手',
            path: '/singer'
          },
          {
            name: '排行',
            path: '/top-list'
          },
          {
            name: '搜索',
            path: '/search'
</script>

播放器 歌词相关逻辑开发(03)、播放器 中间视图层手指交互相关逻辑开发(上) 、播放器 中间视图层手指交互相关逻辑开发(下) 、播放器 mini 播放器开发(01) 、 播放器 mini 播放器开发(02) 、播放器 mini 播放器开发(视频资源vxcmL46679910))(03)、 播放器 mini 播放器开发(04)、 播放器 全屏切换过渡效果实现(上) 、播放器 全屏切换过渡效果实现(下) 、播放器 播放列表组件实现(01)、播放器 播放列表组件实现(02)、 播放器 播放列表组件实现(03) 、 播放器 播放列表组件实现(04) 、 播放器 播放列表组件实现(05)、 播放器 滚动列表高度自适应、播放器 高阶 Scroll 组件的实现 。app

  第6章 的学习内容以下: 歌单详情页开发(上) 、歌单详情页开发(下)、排行榜页面开发 、排行榜详情页开发(上) 、 排行榜详情页开发(下).异步

<script>
  export default {
    name: 'suggest',
    props: {
      query: String,
      showSinger: {
        type: Boolean,
        default: true
      }
    },
    emits: ['select-song', 'select-singer'],
    setup(props, { emit }) {
      const singer = ref(null)
      const songs = ref([])
      const hasMore = ref(true)
      const page = ref(1)
      const loadingText = ref('')
      const noResultText = ref('抱歉,暂无搜索结果')
      const manualLoading = ref(false)

      const loading = computed(() => {
        return !singer.value && !songs.value.length
      })

      const noResult = computed(() => {
        return !singer.value && !songs.value.length && !hasMore.value
      })

      const pullUpLoading = computed(() => {
        return isPullUpLoad.value && hasMore.value
      })

      const preventPullUpLoad = computed(() => {
        return loading.value || manualLoading.value
      })

      const { isPullUpLoad, rootRef, scroll } = usePullUpLoad(searchMore, preventPullUpLoad)

      watch(() => props.query, async (newQuery) => {
        if (!newQuery) {
          return
        }
        await searchFirst()
      })

      async function searchFirst() {
        if (!props.query) {
          return
        }
        page.value = 1
        songs.value = []
        singer.value = null
        hasMore.value = true

        const result = await search(props.query, page.value, props.showSinger)
        songs.value = await processSongs(result.songs)
        singer.value = result.singer
        hasMore.value = result.hasMore
        await nextTick()
        await makeItScrollable()
      }

      async function searchMore() {
        if (!hasMore.value || !props.query) {
          return
        }
        page.value++
        const result = await search(props.query, page.value, props.showSinger)
        songs.value = songs.value.concat(await processSongs(result.songs))
        hasMore.value = result.hasMore
        await nextTick()
        await makeItScrollable()
      }

      async function makeItScrollable() {
        if (scroll.value.maxScrollY >= -1) {
          manualLoading.value = true
          await searchMore()
          manualLoading.value = false
        }
      }

      function selectSong(song) {
        emit('select-song', song)
      }

      function selectSinger(singer) {
        emit('select-singer', singer)
      
      }
    }
  }
</script>

 

  第7章的学习内容以下:搜索页面搜索框开发、搜索页面热门搜索开发、 搜索页面 Suggest 组件开发(01) 、搜索页面 Suggest 组件开发(02) 、搜索页面 Suggest 组件开发(03)、 搜索页面 Suggest 组件开发(04)、(视频资源vxcmL46679910))搜索页面 Suggest 组件开发(05) 、 搜索页面 Suggest 组件开发(06)、 搜索页面 Suggest 组件开发、 搜索页面搜索历史功能开发(01) 、 搜索页面搜索历史功能开发(02)、搜索页面搜索历史功能开发(03)、搜索页面搜索历史功能开发(04) 。async

<script>
  import { debounce } from 'throttle-debounce'

  export default {
    name: 'search-input',
    props: {
      modelValue: String,
      placeholder: {
        type: String,
        default: '搜索歌曲、歌手'
      }
    },
    data() {
      return {
        query: this.modelValue
      }
    },
    created() {
      this.$watch('query', debounce(300, (newQuery) => {
        this.$emit('update:modelValue', newQuery.trim())
      }))

      this.$watch('modelValue', (newVal) => {
        this.query = newVal
      })
    },
    methods: {
      clear() {
        this.query = ''
      }
    }
  }
</script>

<style lang="scss" scoped>
  .search-input {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    width: 100%;
    padding: 0 6px;
    height: 32px;
    background: $color-highlight-background;
    border-radius: 6px;
    .icon-search {
      font-size: 24px;
      color: $color-text-d;
    }
    .input-inner {
      flex: 1;
      margin: 0 5px;
      line-height: 18px;
      background: $color-highlight-background;
      color: $color-text;
      font-size: $font-size-medium;
      outline: 0;
      &::placeholder {
        color: $color-text-d;
      }
    }
    .icon-dismiss {
      font-size: 16px;
      color: $color-text-d;
    }
  }
</style>

  第8章 的学习内容以下: 添加歌曲到列表功能开发(01)、添加歌曲到列表功能开发(02) 、添加歌曲到列表功能开发(03) 、添加歌曲到列表功能开发(04) 、
 添加歌曲到列表功能开发(05)、用户中心页面开发(01)、用户中心页面开发(02)、用户中心页面开发(03)。ide

export default {
    name: 'add-song',
    components: {
      SearchInput,
      Suggest,
      Switches,
      Scroll,
      SongList,
      SearchList,
      Message
    },
    setup() {
      const visible = ref(false)
      const query = ref('')
      const currentIndex = ref(0)
      const scrollRef = ref(null)
      const messageRef = ref(null)

      const store = useStore()
      const searchHistory = computed(() => store.state.searchHistory)
      const playHistory = computed(() => store.state.playHistory)

      const { saveSearch } = useSearchHistory()

      watch(query, async () => {
        await nextTick()
        refreshScroll()
      })

      async function show() {
        visible.value = true

        await nextTick()
        refreshScroll()
      }

      function hide() {
        visible.value = false
      }

      function refreshScroll() {
        scrollRef.value.scroll.refresh()
      }

      function addQuery(s) {
        query.value = s
      }

      function selectSongBySongList({ song }) {
        addSong(song)
      }

      function selectSongBySuggest(song) {
        addSong(song)
        saveSearch(query.value)
      }

      function addSong(song) {
        store.dispatch('addSong', song)
        showMessage()
      }

      function showMessage() {
        messageRef.value.show()
      }

  第9章 的学习内容以下: vxcmL46679910keep-alive 组件应用 、路由组件异步加载 、 项目部署 。学习

相关文章
相关标签/搜索