用Vue3.0开发音乐Web app
Vue3.0高阶实战:开发高质量音乐Web app vx(cmL46679910)
第5章的学习内容如下:(视频资源vx( cmL46679910 **))**播放器基础样式及歌曲播放功能开发 、
<script>
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.disp**(视频资源vx(** cmL46679910 **))**atch('clearSongList')
hide()
}
function showAddSong() {
addSongRef.value.show()
}
}
}
</script>
播放器播放按钮的暂停与播放逻辑开发、播放器歌曲前进与后退逻辑开发 、播放器 DOM 异常错误处理、播放器 歌曲播放模式相关逻辑开发 、
播放器 歌曲收藏功能相关逻辑开发(1)、播放器 歌曲收藏功能相关逻辑开发(2)、播放器 进度条相关逻辑开发、 播放器 进度条相关逻辑开发**(视频资源vx(** cmL46679910 ))(下)、播放器 cd 唱片旋转相关逻辑开发 、 播放器 歌词相关逻辑开发(01) 、播放器 歌词相关逻辑开发(02)、播放器 歌词相关逻辑开(03)、播放器
export default {
name: 'tab',
data() {
return {
tabs: [
{
name: '推荐',
path: '/recommend'
},
{
name: '歌手',
path: '/singer'
},
{
name: '排行',
path: '/top-list'
},
{
name: '搜索',
path: '/search'
}
</script>
中间视图层手指交互相关逻辑开发(上)、播放器 中间视图层手指交互相关逻辑开发(下)、播放器 mini 播放器开发(01)、播放器 mini 播放器开发(02)、播放器 mini 播放器开(03)、播放器 mini 播放器开发(04)、播放器 全屏切换过渡效果实现(上)、播放器 全屏切换过渡效果实现(下)、播放器 播放列表组件实现(01)、播放器 播放列表组件实现(02)、播放器播放列表组件实现(03)、播放器 播放列表组件实现(04)、播放器 播放列表组件实现(05)、播放器滚动列表高度自适应、播放器高阶Scroll 组件的实现 。
第6章的学习内容如下: 歌单详情页开发(上)、歌单详情页开发(下)、排行榜页面开发、排行榜详情页开发(上)、排行榜详情页开发(下)。
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) 、
export default {
name: 'tab',
data() {
return {
tabs: [
{
name: '推荐',
path: '/recommend'
},
{
name: '歌手',
path: '/singer'
},
{
name: '排行',
path: '/top-list'
},
{
name: '搜索',
path: '/search'
}
]
}
}
}
</script>
搜索页面 Suggest 组件开发(03)、搜索页面 Suggest 组件开发(04)、搜索页面 Suggest 组件开发(05)、搜索页面Suggest组件开发(06)、(视频资源vx( cmL46679910 )) 搜索页面 Suggest 组件开发、搜索页面搜索历史功能开发(01)、搜索页面搜索历史功能开发(02)、搜索页面搜索历史功能开发(03)、搜索页面搜索历史功能开发(04) 。
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) 、(视频资源vx( cmL46679910 )) 添加歌曲到列表功能开发(05)、用户中心页面开发(01)、用户中心页面开发(02)、用户中心页面开发(03)。
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章的学习内容如下: keep-alive 组件应用 、路由组件异步加载 、 项目部署 。