Проект на Vue.js
# Установить зависимости
npm install
# Запустить с горячей перезагрузкой на локальном хосте:8080
npm run dev
# Собрать для продакшена с минификацией
npm run build
# Собрать для продакшена и посмотреть отчёт о сборке бандла
npm run build --report
Для подробного объяснения работы проекта ознакомьтесь с руководством и документацией по vue-loader.
[TOC]
npm install vue-cli --save
Установка stylus для поддержки синтаксиса stylus
npm install stylus --save
Установка stylus-loader
babel-runtime для перевода es6 в es5
fastclick для решения проблемы задержки кликов на мобильных устройствах
В main.js:
import fastclick from 'fastclick'
fastclick.attach(document.body)
babel-polyfill для исправления некоторых проблем с es6
Создание файла m-header.vue, который будет использоваться как точка входа в проект. Добавление страниц rank, recommend, search, singer, tab и т. д. Настройка маршрутизации в файле index.js в папке router. Импорт компонента tab.vue в файл App.vue. Настроить навигацию в компоненте tab.vue для перехода на другие страницы.
Установить:
npm install jsonp --save
Использовать jsonp:
common/js/jsonp.js
src/common/js/jsonp.js
src/api/config
src/api/recommend.js
Создать новую папку base для хранения базовых компонентов. Создать компонент slider.vue с использованием слота. Установить better-scroll. При изменении размера окна браузера размер карусели должен меняться.
// При изменении ширины окна обновить размер карусели
window.addEventListener('resize', () => {
if (!this.slider) {
return
}
this._setSliderWidth(true)
this.slider.refresh()
})
APP.vue
<template>
<div id="app">
<m-header></m-header>
<tab></tab>
<!-- Сохранить их DOM в памяти -->
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</template>
500: ошибка сервера
Невозможно напрямую вызвать API QQ Music. Решение: использовать прокси на сервере.
webpack.dev.config.js
// Прокси на сервере
const express = require('express')
const axios = require('axios')
const app = express()
const apiRoutes = express.Router()
app.use('/api', apiRoutes)
Установить axios:
npm install axios --save
Использовать axios для проксирования запросов:
before(app){
// Использовать axios для проксирования
// Данные плейлиста
app.get('/api/getDiscList', function (req, res) {
let url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
axios.get(url, {
headers: {
referer: 'https://c.y.qq.com/',
host: 'c.y.qq.com'
},
// Параметры
params: req.query
}).then((response) => {
res.json(response.data)
}).catch((e) => {
console.log(e.response)
})
})
},
<h2 class="name" v-html="item.creator.name"></h2>
v-html="item.creator.name" используется для экранирования символов.
Установка: npm install vue-lazyload --save Использование: импортировать в main.js import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad, {
loading: require('@/common/image/default.png')
})
В recommend.vue:
<img v-lazy="item.imgurl" width="60" height="60">
Файлы в папке src/store:
store/index.js // Изменить состояние Текст запроса:
时 在控制台打印 logger 日志,方便查看修改了什么.
Перевод:
Время в консоли выводит логи logger, чтобы было удобно просматривать изменения.
import createLogger from 'vuex/dist/logger'
// Регистрация store
import store from './store'
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
music-list.vue 组件 [6-8] - [6-14]
singer-detail.vue и music-list.vue компоненты между данными передают (родительский компонент <=> дочерний компонент).
song-list.vue [6-9]
Создан @/base/song-list/song-list.vue базовый компонент. Список песен. Через цикл for данные перебирают.
music-list.vue компонент реализует список выпадающих изображений для увеличения [6-12].
let scale = 1
const percent = Math.abs(newY / this.imageHeight)
// Если список выпадает, изображение scale увеличивается
if (newY > 0) {
scale = 1 + percent
zIndex = 14
}
Проверка поставщика [6-13].
Плеер страница [седьмая глава].
Данные плеера Vuex дизайн [7-2]
Данные игрока являются глобальными.
Состояние воспроизведения.
Данные плеера Vuex дизайн [7-3]
Новый компонент commponents/player/plyer.vue страница. Определяется в APP.vue.
Анимация расширения и сжатия плеера [7-6]
Устанавливается create-keyframe-animation.
npm install create-keyframe-animation --save
Воспроизведение песни функционал [7-8].
Перемотка вперёд и назад функционала [7-9].
Изменение текущего индекса воспроизведения песни. Изменение currentIndex. Слишком быстрая смена песен может вызвать ошибку программы. Решение проблемы: добавление @canplay="ready" и @error="error" в player.vue.
<audio ref='audio' :src="currentSong.url" @canplay="ready" @error="error"></audio>
Смена песни сопровождается контролем.
data() {
return {
songReady: false
}
}
<!-- methods -->
ready(){
this.songReady = true
},
Получение и обновление времени воспроизведения [7-11].
Компонент progress-bar.vue индикатор выполнения [7-12].
Реализация минимального индикатора выполнения [7-15].
Создаётся progress-circle.
Режим воспроизведения переключается [7-16].
Анализ данных текста песни [7-19].
Устанавливаются js-base64 для преобразования формата текста песни.
npm install js-base64 --save
npm install lyric-parser --save
Индикация текста песни прокрутка списка [7-21].
Текст песни перемещается влево и вправо [7-22].
Оставшееся время воспроизведения [7-23].
Обработка граничных условий: только одна песня.
Нижняя часть плеера адаптируется с использованием mixin.
Страница списка песен [восьмая глава].
Обзор макета страницы списка песен и реализация связи данных через Vuex [8-1].
Новый файл @/components/disc/disc.vue. Изменён router/index.js маршрутизатор. Добавлен дочерний маршрут для recommend.
{
path: '/recommend',
name: 'Recommend',
component: Recommend,
children: [
{
path: ':id',
component: Disc
}
]
},
В recommend.vue добавлен <router-view></router-view>.
Сбор информации о списке песен [8-2].
Используется axios для проксирования, прямой доступ к данным невозможен.
__webpack.dev.config.js__
// Получение данных о списке песен
app.get('/api/getSongList', function (req, res) {
var url = 'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
axios.get(url, {
headers: {
referer: 'https://y.qq.com/',
host: 'c.y.qq.com'
},
params: req.query
}).then((response) => {
res.json(response.data)
}).catch((e) => {
console.log(e)
})
})
@/api/recommend.js
// Сбор данных о списке песен
export function getSongList (disstid) {
const url = '/api/getSongList'
const data = Object.assign({}, commonParams, {
uin: 0,
format: 'json',
notice: 0,
needNewCode: 1,
new_format: 1,
pic: 500,
disstid: disstid,
type: 1,
json: 1,
utf8: 1,
onlysong: 0,
picmid: 1,
nosign: 1,
song_begin: 0,
platform: 'h5',
song_num: 100,
_: +new Date()
})
return axios.get(url, {
params: data
}).then((res) => {
return Promise.resolve(res.data)
})
}
Обработка и применение данных списка песен [8-3].
common/js/song.js
// Данные песни
export function creatSongList (musicData) {
return new Song({
id: musicData.id,
mid: musicData.mid,
singer: filterSinger(musicData.singer),
name: musicData.name,
album: musicData.albumname,
duration: musicData.interval,
image: `https://y.gtimg.cn/music/photo_new/T002R300x300M000${musicData.album.mid}.jpg?max_age=2592000`,
url: `http://ws.stream.qqmusic.qq.com/C100${musicData.mid}.m4a?fromtag=0&guid=126548448`
})
}
function filterSinger(singer) {
let ret = []
if (!singer) {
return ''
}
singer.forEach((s) => {
ret.push(s.name)
})
return ret.join('/')
}
При нажатии на список, переход на страницу disc.vue. Здесь данные помещаются в результат (creatSongList).
disc.vue
if (musicData.id && musicData.album) {
ret.push(creatSongList(musicData))
}
Рейтинг страница [девятая глава].
Обзор страницы рейтинга и получение данных рейтинга [9-1].
Новый @/components/rank/rank.vue рейтинг страница. Новый @/api/rank.js для получения данных рейтинга. **Данные приложения для списка лидеров [9-2]**
**Описание списка лидеров и его компоновка, а также реализация коммуникации данных с помощью Vuex [9-3]**
Создайте новый компонент @/components/top-list/top-list.vue и сделайте ссылку на него в файле router/index.js.
**Получение и применение данных на странице со списком лидеров [9-4]**
**Расширение и применение компонента списка лидеров с песней (song-list) [9-5]**
## **Поисковая страница [Глава 10]**
**Функции и описание компоновки поисковой страницы [10-1]**
**Разработка компонента search-box [10-2]**
Создайте новый компонент @/base/search-box/search-box.vue. Используйте двустороннюю привязку данных v-model="query".
`<i v-show="query" class="icon-dismiss"></i>` — этот код показывает значок крестика только если есть значение query.
**Извлечение и применение популярных поисковых запросов на поисковой странице [10-3]**
Создайте файл @api/search.js.
**Разработка компонента suggest на поисковой странице [10-4]–[10-10]**
**[10-5] Ошибка:**
``` js
mutate vuex store state outside mutation handlers.
at assert
Причина: не следует изменять состояние хранилища Vuex вне обработчиков мутаций.
Решение: добавьте метод slice(), чтобы вернуть копию состояния, и затем измените эту копию.
Пример кода:
let playlist = state.playlist.slice();
let sequenceList = state.sequenceList.slice();
[10-10] Обработка граничных случаев
Создайте файл @/base/no-result/no-result.vue.
При остановке ввода или удалении символов во время поиска выполняйте запрос данных. Реализуйте функцию прерывания потока (input) в common/js/util.js и используйте её в search-box.vue.
Реализация функции сохранения результатов поиска [10-11]–[10-13]
Сохраните историю поиска с помощью пакета good-storage. Установите пакет с помощью команды npm install good-storage --save.
Реализация функций компонента search-list [10-14]–[10-15]
Остальные функции поисковой страницы [10-18]
Реализуйте диалоговое окно подтверждения с помощью нового файла @/base/confirm/confirm.vue.
Компоновка и функции компонента списка песен [11-1]
Создайте новый файл @/components/playlist/playlist.vue.
Управление отображением и скрытием компонента списка песен [11-2]
Реализация воспроизведения списка песен [11-3]–[11-9]
[11-12]
Создайте файлы @/base/add-song/add-song.vue и @/base/switches/switches.vue. Привяжите событие клика к элементу списка с помощью @click="switchItem(index)"
.
Код:
<li class="switch-item" v-for="(item, index) in switches" :class="{'active': currentIndex === index}" @click="switchItem(index)">
<span>{{item.name}}</span>
В методе switchItem() генерируйте событие switch и передавайте индекс в родительский компонент.
Код:
methods: { // 点击之后派发 switch 事件, 在父组件内用 @switch="switchItem" // 同时把index传递到父组件 switchItem(index) { this.$emit('switch', index) } }
Добавьте @switch="switchItem"
в родительском компоненте add-song.vue. В методе switchItem() установите текущий индекс.
Код родительского компонента:
<switches :switches="switches" :currentIndex="currentIndex" @switch="switchItem"></switches>
switchItem(index) { this.currentIndex = index }
Создайте prod.server.js и выполните команду npm run build. Запустите сервер с помощью node prod.server.js. Для асинхронной загрузки маршрутов используйте следующий код:
Импортируйте компонент Recommend:
import Recommend from 'components/recommend/recommend'
Определите компонент Recommend как асинхронный:
const Recommend = (resolve) => { import ('components/recommend/recommend').then((module) => { resolve(module) }) }
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )