用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 組件應用 、路由組件異步加載 、 項目部署 。學習

相關文章
相關標籤/搜索