├── static └── .gitkeep ├── .eslintignore ├── .gitignore ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── src ├── assets │ ├── icon.png │ ├── logo.png │ ├── icon-mv.png │ ├── icon-back.png │ ├── icon-like.png │ ├── icon-list.png │ ├── icon-play.png │ ├── icon-RANDOM.png │ ├── icon-album.png │ ├── icon-jiantou.png │ ├── icon-music.png │ ├── icon-pause.png │ ├── icon-search.png │ ├── icon-share.png │ ├── icon-singer.png │ ├── icon-xiayiqu.png │ ├── Vue_Music_Blur.png │ ├── icon-...black.png │ ├── icon-shangyiqu.png │ ├── icon-SEQUENTIAL.png │ ├── icon-volue-left.png │ ├── icon-volue-right.png │ ├── icon-back.svg │ ├── icon-back-white.svg │ ├── icon-mvcount.svg │ ├── icon-playing.svg │ ├── icon-erji.svg │ ├── error.svg │ ├── icon-SINGLE.svg │ └── loading.svg ├── lib │ ├── components │ │ ├── actionsheet │ │ │ ├── component.json │ │ │ ├── metas.yml │ │ │ └── index.vue │ │ ├── mvitem.vue │ │ └── index.js │ ├── styles │ │ ├── index.vue │ │ ├── tap.less │ │ ├── weui │ │ │ ├── base │ │ │ │ ├── variable │ │ │ │ │ ├── weui_grid.less │ │ │ │ │ ├── weui_progress.less │ │ │ │ │ ├── weui_msg.less │ │ │ │ │ ├── monokai.less │ │ │ │ │ ├── weui_cell.less │ │ │ │ │ ├── weui_button.less │ │ │ │ │ └── global.less │ │ │ │ ├── reset.less │ │ │ │ ├── mixin │ │ │ │ │ ├── mobile.less │ │ │ │ │ ├── text.less │ │ │ │ │ ├── setChecked.less │ │ │ │ │ ├── setOnepx.less │ │ │ │ │ └── setArrow.less │ │ │ │ └── fn.less │ │ │ ├── widget │ │ │ │ ├── weui_cell │ │ │ │ │ ├── weui_check.less │ │ │ │ │ ├── weui_check │ │ │ │ │ │ ├── weui_check_common.less │ │ │ │ │ │ ├── weui_radio.less │ │ │ │ │ │ └── weui_checkbox.less │ │ │ │ │ ├── weui_form │ │ │ │ │ │ ├── weui_select_after.less │ │ │ │ │ │ ├── weui_vcode.less │ │ │ │ │ │ ├── weui_select_before.less │ │ │ │ │ │ ├── weui_select.less │ │ │ │ │ │ └── weui_form_common.less │ │ │ │ │ ├── weui_form.less │ │ │ │ │ ├── weui_access.less │ │ │ │ │ ├── weui_switch.less │ │ │ │ │ ├── weui_cell_global.less │ │ │ │ │ └── weui_uploader.less │ │ │ │ ├── weui_button │ │ │ │ │ ├── weui_btn_disabled.less │ │ │ │ │ ├── weui_btn_warn.less │ │ │ │ │ ├── weui_btn_primary.less │ │ │ │ │ ├── weui_btn_default.less │ │ │ │ │ ├── weui_btn_plain.less │ │ │ │ │ ├── weui_btn_global.less │ │ │ │ │ └── weui_button.less │ │ │ │ ├── weui_tab │ │ │ │ │ ├── weui_tab.less │ │ │ │ │ ├── weui_tab_tabbar.less │ │ │ │ │ ├── navbar.less │ │ │ │ │ └── tabbar.less │ │ │ │ ├── weui_progress │ │ │ │ │ └── weui_progress.less │ │ │ │ ├── weui_page │ │ │ │ │ ├── weui_article.less │ │ │ │ │ └── weui_msg.less │ │ │ │ ├── weui_tips │ │ │ │ │ ├── weui_mask.less │ │ │ │ │ ├── weui_actionsheet.less │ │ │ │ │ ├── weui_dialog.less │ │ │ │ │ └── weui_toast.less │ │ │ │ ├── weui_panel │ │ │ │ │ └── weui_panel.less │ │ │ │ ├── weui_grid │ │ │ │ │ └── weui_grid.less │ │ │ │ ├── weui_media_box │ │ │ │ │ └── weui_media_box.less │ │ │ │ └── weui_searchbar │ │ │ │ │ └── weui_searchbar.less │ │ │ ├── weui.less │ │ │ └── icon │ │ │ │ ├── weui_icon_font.less │ │ │ │ └── weui_font.less │ │ ├── index.less │ │ ├── center.less │ │ ├── reset.less │ │ ├── loading.less │ │ ├── transition.less │ │ ├── close.less │ │ ├── reddot.less │ │ ├── variable.less │ │ └── 1px.less │ ├── libs │ │ ├── mixin_uuid.js │ │ ├── trim.js │ │ ├── router.js │ │ ├── base.js │ │ └── eventor.js │ └── mixins │ │ └── multi-items.js ├── store │ ├── index.js │ ├── ApiService.js │ ├── NotifyService.js │ └── PlayService.js ├── components │ ├── Hello.vue │ ├── ActionSheet.vue │ ├── Lyric.vue │ ├── Rank.vue │ ├── PlayingList.vue │ ├── Recommand.vue │ ├── Play.vue │ ├── Album.vue │ ├── Cd.vue │ └── Search.vue ├── main.js ├── config │ ├── def.js │ └── api.js ├── style │ ├── weui_mask.less │ └── weui_actionsheet.less ├── router.js ├── utils │ └── base64.js └── App.vue ├── .babelrc ├── .editorconfig ├── index.html ├── .gitattributes ├── .eslintrc.js ├── package.json └── README.md /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | .idea/ -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /src/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/icon-mv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-mv.png -------------------------------------------------------------------------------- /src/lib/components/actionsheet/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "vux": { 3 | "is_weui": true 4 | } 5 | } -------------------------------------------------------------------------------- /src/assets/icon-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-back.png -------------------------------------------------------------------------------- /src/assets/icon-like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-like.png -------------------------------------------------------------------------------- /src/assets/icon-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-list.png -------------------------------------------------------------------------------- /src/assets/icon-play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-play.png -------------------------------------------------------------------------------- /src/assets/icon-RANDOM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-RANDOM.png -------------------------------------------------------------------------------- /src/assets/icon-album.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-album.png -------------------------------------------------------------------------------- /src/assets/icon-jiantou.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-jiantou.png -------------------------------------------------------------------------------- /src/assets/icon-music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-music.png -------------------------------------------------------------------------------- /src/assets/icon-pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-pause.png -------------------------------------------------------------------------------- /src/assets/icon-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-search.png -------------------------------------------------------------------------------- /src/assets/icon-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-share.png -------------------------------------------------------------------------------- /src/assets/icon-singer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-singer.png -------------------------------------------------------------------------------- /src/assets/icon-xiayiqu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-xiayiqu.png -------------------------------------------------------------------------------- /src/assets/Vue_Music_Blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/Vue_Music_Blur.png -------------------------------------------------------------------------------- /src/assets/icon-...black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-...black.png -------------------------------------------------------------------------------- /src/assets/icon-shangyiqu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-shangyiqu.png -------------------------------------------------------------------------------- /src/assets/icon-SEQUENTIAL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-SEQUENTIAL.png -------------------------------------------------------------------------------- /src/assets/icon-volue-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-volue-left.png -------------------------------------------------------------------------------- /src/assets/icon-volue-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calamus0427/vue-music/master/src/assets/icon-volue-right.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/styles/index.vue: -------------------------------------------------------------------------------- 1 | // this component is used only for building vux.css 2 | -------------------------------------------------------------------------------- /src/lib/libs/mixin_uuid.js: -------------------------------------------------------------------------------- 1 | export default { 2 | created () { 3 | this.uuid = Math.random().toString(36).substring(3, 8) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/styles/tap.less: -------------------------------------------------------------------------------- 1 | .vux-tap-active { 2 | tap-highlight-color: rgba(0,0,0,0); 3 | } 4 | .vux-tap-active:active { 5 | background-color: #ECECEC; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/weui_grid.less: -------------------------------------------------------------------------------- 1 | @weuiGridBorderColor:#D9D9D9; 2 | @weuiGridFontSize: 14px; 3 | @weuiGridIconSize: 28px; 4 | @weuiGridColumnCount: 3; -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_check.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | @import "./weui_check/weui_check_common"; 3 | @import "./weui_check/weui_radio"; 4 | @import "./weui_check/weui_checkbox"; 5 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/weui_progress.less: -------------------------------------------------------------------------------- 1 | @weuiProgressBg: #EBEBEB; 2 | @weuiProgressColor: #09BB07; 3 | @weuiProgressHeight: 3px; 4 | @weuiProgressCloseBg: #EF4F4F; 5 | @weuiProgressActiveBg: #C13E3E; 6 | -------------------------------------------------------------------------------- /src/lib/styles/index.less: -------------------------------------------------------------------------------- 1 | @import 'reset.less'; 2 | @import '1px.less'; 3 | @import 'center.less'; 4 | @import 'reddot.less'; 5 | @import 'transition.less'; 6 | @import 'loading.less'; 7 | @import 'close.less'; 8 | @import 'tap.less'; -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/weui_msg.less: -------------------------------------------------------------------------------- 1 | @weuiMsgPaddingTop:36px; 2 | @weuiMsgIconGap:30px; 3 | @weuiMsgTitleGap:5px; 4 | @weuiMsgTextGap:25px; 5 | @weuiMsgOprGap:25px; 6 | @weuiMsgExtraAreaGap:15px; 7 | @weuiMsgExtraAreaOfMinHeight:438px; -------------------------------------------------------------------------------- /src/lib/styles/center.less: -------------------------------------------------------------------------------- 1 | .vux-center-v, .vux-center-h, .vux-center { 2 | display: flex; 3 | } 4 | 5 | .vux-center-v, .vux-center { 6 | align-items: center; 7 | } 8 | 9 | .vux-center-h, .vux-center { 10 | justify-content: center; 11 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_check/weui_check_common.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | 3 | .weui_check_label { 4 | .setTapColor(); 5 | } 6 | 7 | .weui_check{ 8 | position: absolute; 9 | left: -9999em; 10 | } 11 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_form/weui_select_after.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | @import "./weui_select"; 3 | 4 | .weui_select_after { 5 | padding-left:@weuiCellGapH; 6 | .weui_select { 7 | padding-left:0; 8 | } 9 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_btn_disabled.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_btn_disabled { 4 | color: @weuiBtnDisabledFontColor; 5 | &.weui_btn_default { 6 | color: @weuiBtnDefaultDisabledFontColor; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_form.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | @import "./weui_form/weui_form_common"; 3 | @import "./weui_form/weui_select"; 4 | @import "./weui_form/weui_select_before"; 5 | @import "./weui_form/weui_select_after"; 6 | @import "./weui_form/weui_vcode"; 7 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/monokai.less: -------------------------------------------------------------------------------- 1 | @monokaiCaret:#F8F8F0; 2 | @monokaiGreen:#A6E22E; 3 | @monokaiOrange:#FD971F; 4 | @monokaiBlue:#66D9EF; 5 | @monokaiRed:#F92672; 6 | @monokaiPurple:#AE81FF; 7 | @monokaiBrown:#E6DB74; 8 | @monokaiFindHighlight:#FFE792; 9 | @monokaiLineHighlight:#3E3D32; 10 | @monokaiSelection:#49483E; 11 | @monokaiBg:#272822; -------------------------------------------------------------------------------- /src/lib/styles/reset.less: -------------------------------------------------------------------------------- 1 | html { 2 | -ms-text-size-adjust: 100%; 3 | -webkit-text-size-adjust: 100%; 4 | } 5 | 6 | body { 7 | line-height: 1.6; 8 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 9 | } 10 | 11 | * { 12 | margin: 0; 13 | padding: 0; 14 | } 15 | 16 | a img { 17 | border: 0; 18 | } 19 | 20 | a { 21 | text-decoration: none; 22 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/base/reset.less: -------------------------------------------------------------------------------- 1 | @import "fn"; 2 | 3 | html { 4 | -ms-text-size-adjust: 100%; 5 | -webkit-text-size-adjust: 100%; 6 | } 7 | 8 | body { 9 | line-height: 1.6; 10 | font-family: @sansFont; 11 | } 12 | 13 | * { 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | a img { 19 | border: 0; 20 | } 21 | 22 | a { 23 | text-decoration: none; 24 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_btn_warn.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_btn_warn { 4 | background-color: @weuiBtnWarnBg; 5 | &:not(.weui_btn_disabled):visited { 6 | color: @weuiBtnFontColor; 7 | } 8 | &:not(.weui_btn_disabled):active { 9 | color: @weuiBtnActiveFontColor; 10 | background-color: @weuiBtnWarnActiveBg; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_btn_primary.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_btn_primary { 4 | background-color: @weuiBtnPrimaryBg; 5 | &:not(.weui_btn_disabled):visited { 6 | color: @weuiBtnFontColor; 7 | } 8 | &:not(.weui_btn_disabled):active { 9 | color: @weuiBtnActiveFontColor; 10 | background-color: @weuiBtnPrimaryActiveBg; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-music 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/mixin/mobile.less: -------------------------------------------------------------------------------- 1 | // tapcolor 2 | .setTapColor(@c:rgba(0,0,0,0)) { 3 | -webkit-tap-highlight-color: @c; 4 | } 5 | 6 | //user action 7 | .no_select() { 8 | -webkit-touch-callout: none; 9 | -webkit-user-select: none; 10 | -khtml-user-select: none; 11 | -moz-user-select: none; 12 | -ms-user-select: none; 13 | user-select: none; 14 | } 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/25 0025. 3 | */ 4 | import Vue from 'vue' 5 | import Vuex from 'vuex' 6 | 7 | import PlayService from './PlayService' 8 | import ApiService from './ApiService' 9 | import NotifyService from './NotifyService' 10 | 11 | Vue.use(Vuex) 12 | 13 | export default new Vuex.Store({ 14 | modules: { 15 | PlayService, 16 | ApiService, 17 | NotifyService 18 | } 19 | }) 20 | 21 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/fn.less: -------------------------------------------------------------------------------- 1 | // mixin 2 | @import "./mixin/mobile"; 3 | @import "./mixin/setOnepx"; 4 | @import "./mixin/setArrow"; 5 | @import "./mixin/text"; 6 | 7 | 8 | // variable 9 | @import "./variable/global"; 10 | @import "./variable/monokai"; 11 | 12 | 13 | @import "./variable/weui_cell"; 14 | @import "./variable/weui_button"; 15 | @import "./variable/weui_msg"; 16 | @import "./variable/weui_progress"; 17 | @import "./variable/weui_grid"; -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_btn_default.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_btn_default { 4 | background-color: @weuiBtnDefaultBg; 5 | color: @weuiBtnDefaultFontColor; 6 | &:not(.weui_btn_disabled):visited { 7 | color: @weuiBtnDefaultFontColor; 8 | } 9 | &:not(.weui_btn_disabled):active { 10 | color: @weuiBtnDefaultActiveFontColor; 11 | background-color: @weuiBtnDefaultActiveBg; 12 | } 13 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/weui_cell.less: -------------------------------------------------------------------------------- 1 | @weuiCellBg:#FFFFFF; 2 | @weuiCellBorderColor:#D9D9D9; 3 | @weuiCellGapV:10px; 4 | @weuiCellGapH:15px; 5 | @weuiCellInnerGapH:.35em; 6 | @weuiCellHeight: 44px; 7 | @weuiCellFontSize:17px; 8 | @weuiCellTipsFontSize:14px; 9 | @weuiCellLabelWidth:105px; 10 | 11 | @weuiCellLineHeight: unit((@weuiCellHeight - 2 * @weuiCellGapV) / @weuiCellFontSize); // 高度为44px,减去上下padding的行高 12 | @weuiCellsMarginTop:unit(20 / @weuiCellFontSize, em); -------------------------------------------------------------------------------- /src/lib/libs/trim.js: -------------------------------------------------------------------------------- 1 | // http://www.cnblogs.com/rubylouvre/archive/2009/09/18/1568794.html 2 | export default function (str, replaceBreak) { 3 | str = str.replace(/^\s\s*/, '') 4 | var ws = /\s/ 5 | var i = str.length 6 | while (ws.test(str.charAt(--i))) { 7 | var rs = str.slice(0, i + 1) 8 | } 9 | if (!rs) { 10 | return '' 11 | } 12 | if (!replaceBreak) { 13 | return rs 14 | } else { 15 | return rs.replace(/(?:\r\n|\r|\n)/g, '') 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/mixin/text.less: -------------------------------------------------------------------------------- 1 | .ellipsis(@w:auto) { 2 | width: @w; 3 | overflow: hidden; 4 | text-overflow: ellipsis; 5 | white-space: nowrap; 6 | word-wrap: normal; 7 | } 8 | 9 | .ellipsisLn(@line) { 10 | overflow: hidden; 11 | text-overflow: ellipsis; 12 | display: -webkit-box; 13 | -webkit-box-orient: vertical; 14 | -webkit-line-clamp: @line; 15 | } 16 | .text_wrap() { 17 | word-wrap:break-word; 18 | word-break:break-all; 19 | } -------------------------------------------------------------------------------- /src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tab/weui_tab.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | @import "tabbar"; 3 | @import "navbar"; 4 | 5 | .weui_tab { 6 | position: relative; 7 | height: 100%; 8 | } 9 | 10 | .weui_tab_bd { 11 | box-sizing: border-box; 12 | height: 100%; 13 | padding-bottom: 55px; 14 | overflow: auto; 15 | -webkit-overflow-scrolling: touch; 16 | } 17 | 18 | .weui_tab_bd_item { 19 | display: none; 20 | } 21 | 22 | .weui_tab_bd_item_active { 23 | display: block; 24 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_progress/weui_progress.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_progress { 4 | display: flex; 5 | align-items: center; 6 | } 7 | 8 | .weui_progress_bar { 9 | background-color: @weuiProgressBg; 10 | height: @weuiProgressHeight; 11 | flex: 1; 12 | } 13 | 14 | .weui_progress_inner_bar { 15 | width: 0; 16 | height: 100%; 17 | background-color: @weuiProgressColor; 18 | } 19 | 20 | .weui_progress_opr { 21 | display: block; 22 | margin-left: 15px; 23 | font-size: 0; 24 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueResource from 'vue-resource' 3 | import VueLazyload from 'vue-lazyload' 4 | 5 | import App from './App' 6 | import store from './store' 7 | import router from './router' 8 | 9 | Vue.use(VueResource) 10 | Vue.use(VueLazyload, { 11 | error: require('./assets/loading.svg'), 12 | loading: require('./assets/loading.svg'), 13 | attempt: 1 14 | } 15 | ) 16 | 17 | /* eslint-disable no-new */ 18 | new Vue({ 19 | el: '#app', 20 | store, 21 | router, 22 | render: h => h(App) 23 | }) 24 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_form/weui_vcode.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | 3 | .weui_vcode { 4 | padding-top: 0!important; 5 | padding-right: 0!important; 6 | padding-bottom: 0!important; 7 | .weui_cell_ft { 8 | img { 9 | margin-left: 5px; 10 | height: @weuiCellHeight; 11 | vertical-align: middle; 12 | } 13 | } 14 | .weui_btn { 15 | margin-left: 5px; 16 | width: auto; 17 | display: inline-block; 18 | height: @weuiCellHeight; 19 | } 20 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tab/weui_tab_tabbar.less: -------------------------------------------------------------------------------- 1 | /** 2 | * @vux Copy weui_tab.less and Remove navbar 3 | */ 4 | 5 | @import "../../base/fn"; 6 | @import "tabbar"; 7 | 8 | .weui_tab { 9 | position: relative; 10 | height: 100%; 11 | } 12 | 13 | .weui_tab_bd { 14 | box-sizing: border-box; 15 | height: 100%; 16 | padding-bottom: 55px; 17 | overflow: auto; 18 | -webkit-overflow-scrolling: touch; 19 | } 20 | 21 | .weui_tab_bd_item { 22 | display: none; 23 | } 24 | 25 | .weui_tab_bd_item_active { 26 | display: block; 27 | } -------------------------------------------------------------------------------- /src/lib/styles/loading.less: -------------------------------------------------------------------------------- 1 | .vux-loading { 2 | animation-duration: 0.6s; 3 | animation-iteration-count: infinite; 4 | animation-name: vux-loading; 5 | animation-timing-function: linear; 6 | border-radius: 99em; 7 | border: 3px solid #DDD; 8 | border-left-color: #666; 9 | display: inline-block; 10 | width: 16px; 11 | height: 16px; 12 | border-width: 2px; 13 | display:table-cell; 14 | vertical-align:middle; 15 | } 16 | 17 | @keyframes vux-loading { 18 | from { 19 | transform: rotate(0deg) 20 | } 21 | to { 22 | transform: rotate(360deg) 23 | } 24 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/base/mixin/setChecked.less: -------------------------------------------------------------------------------- 1 | .setChecked(@c:#FFFFFF) { 2 | display: inline-block; 3 | content: ''; 4 | width: 4px; 5 | height: 8px; 6 | border-bottom: 2px solid @c; 7 | border-right: 2px solid @c; 8 | transform: translate(0, 0) rotate(45deg); 9 | } 10 | 11 | .setCheckedAbs(@c:#FFFFFF) { 12 | position: absolute; 13 | top: 50%; 14 | left: 50%; 15 | content: ''; 16 | width: 4px; 17 | height: 8px; 18 | border-bottom: 2px solid @c; 19 | border-right: 2px solid @c; 20 | transform: translate(-50%, -65%) rotate(45deg); 21 | } -------------------------------------------------------------------------------- /src/config/def.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/25 0025. 3 | */ 4 | export const PLAY_MODE_IMG = [ 5 | require('../assets/icon-SINGLE.svg'), 6 | require('../assets/icon-SEQUENTIAL.png'), 7 | require('../assets/icon-RANDOM.png') 8 | ] 9 | export const PLAY_MODE_NAME = ['单曲循环', '顺序播放', '随机播放'] 10 | export const SINGLE = 0 11 | export const SEQUENTIAL = 1 12 | export const RANDOM = 2 13 | export const DEFAULT_IMG = require('../assets/Vue_Music_Blur.png') 14 | export const DEFAULT_SONG_NAME = 'VUE MUSIC' 15 | export const types = { 16 | ALBUM: 10002, 17 | CD: 10014, 18 | JUMP: 3002 19 | } 20 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_access.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_cells_access { 4 | .weui_cell:not(.no_access) { 5 | // 在cell_access和其它类型的cell混着用的场景下,其它cell要加no_access,避免有点击态 6 | .setTapColor; 7 | &:active { 8 | background-color: #ECECEC; 9 | } 10 | } 11 | a.weui_cell { 12 | color: inherit; 13 | } 14 | .weui_cell_ft { 15 | &:after { 16 | content: " "; 17 | .setArrow_Wap(right, 6px, #C8C8CD, 2px); 18 | top: -1px; 19 | margin-left:.3em; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/lib/libs/router.js: -------------------------------------------------------------------------------- 1 | export function go (url, $router) { 2 | if (/^javas/.test(url) || !url) return 3 | const useRouter = typeof url === 'object' || ($router && typeof url === 'string' && !/http/.test(url)) 4 | if (useRouter) { 5 | $router.go(url) 6 | } else { 7 | window.location.href = url 8 | } 9 | } 10 | 11 | export function getUrl (url, $router) { 12 | // Make sure the href is right in hash mode 13 | if ($router && !$router._history && typeof url === 'string' && !/http/.test(url)) { 14 | return `#!${url}` 15 | } 16 | return url && typeof url !== 'object' ? url : 'javascript:void(0);' 17 | } 18 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 8 | extends: 'standard', 9 | // required to lint *.vue files 10 | plugins: [ 11 | 'html' 12 | ], 13 | // add your custom rules here 14 | 'rules': { 15 | // allow paren-less arrow functions 16 | 'arrow-parens': 0, 17 | // allow async-await 18 | 'generator-star-spacing': 0, 19 | // allow debugger during development 20 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/lib/styles/transition.less: -------------------------------------------------------------------------------- 1 | .vux-fade-transition { 2 | opacity: 1; 3 | transition: opacity linear 0.2s 4 | } 5 | 6 | .vux-fade-enter, .vux-fade-leave { 7 | opacity: 0; 8 | } 9 | 10 | .vux-dialog-transition { 11 | opacity: 1; 12 | transition-duration: .4s; 13 | transform: translate(-50%, -50%) scale(1)!important; 14 | transition-property: transform, opacity!important; 15 | } 16 | 17 | .vux-dialog-enter, .vux-dialog-leave { 18 | opacity: 0; 19 | } 20 | 21 | .vux-dialog-enter { 22 | transform: translate(-50%, -50%) scale(1.185)!important; 23 | } 24 | 25 | .vux-dialog-leave { 26 | transform: translate(-50%, -50%) scale(1)!important; 27 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/weui_button.less: -------------------------------------------------------------------------------- 1 | @weuiBtnDefaultGap:15px; 2 | @weuiBtnHeight:42px; 3 | @weuiBtnMiniHeight:1.9; 4 | @weuiBtnFontSize:18px; 5 | @weuiBtnFontColor:#FFFFFF; 6 | @weuiBtnDisabledFontColor:rgba(255,255,255,.6); 7 | @weuiBtnActiveFontColor:rgba(255,255,255,.4); 8 | @weuiBtnMiniFontSize:14px; 9 | @weuiBtnBorderRadius:5px; 10 | 11 | @weuiBtnDefaultBg:#F7F7F7; 12 | @weuiBtnDefaultActiveBg:#DEDEDE; 13 | @weuiBtnDefaultFontColor:#454545; 14 | @weuiBtnDefaultDisabledFontColor:#C9C9C9; 15 | @weuiBtnDefaultActiveFontColor:#A1A1A1; 16 | 17 | @weuiBtnPrimaryBg:#04BE02; 18 | @weuiBtnPrimaryActiveBg:#039702; 19 | 20 | @weuiBtnWarnBg:@button-warn-bg-color; 21 | @weuiBtnWarnActiveBg:@button-warn-active-color; 22 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_btn_plain.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_btn_plain_primary { 4 | color: @weuiBtnPrimaryBg; 5 | border: 1px solid @weuiBtnPrimaryBg; 6 | button&, input& { 7 | border-width: 1px; 8 | background-color: transparent; 9 | } 10 | &:active { 11 | border-color: @weuiBtnPrimaryActiveBg; 12 | } 13 | &:after { 14 | border-width: 0; 15 | } 16 | } 17 | 18 | .weui_btn_plain_default { 19 | color: #5A5A5A; 20 | border: 1px solid #5A5A5A; 21 | button&, input& { 22 | border-width: 1px; 23 | background-color: transparent; 24 | } 25 | &:after { 26 | border-width: 0; 27 | } 28 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_check/weui_radio.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | 3 | // method2 accessbility 4 | .weui_cells_radio{ 5 | .weui_cell_ft { 6 | padding-left: @weuiCellInnerGapH; 7 | } 8 | .weui_cell { 9 | &:active { 10 | background-color: #ECECEC; 11 | } 12 | } 13 | } 14 | .weui_check { 15 | // radio 16 | .weui_cells_radio & { 17 | &:checked { 18 | & + .weui_icon_checked { 19 | &:before { 20 | display: block; 21 | content: '\EA08'; 22 | color: #09BB07; 23 | font-size: 16px; 24 | } 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/lib/styles/close.less: -------------------------------------------------------------------------------- 1 | .vux-close { 2 | position: relative; 3 | display: inline-block; 4 | vertical-align: middle; 5 | width: 24px; 6 | height: 24px; 7 | overflow: hidden; 8 | color: #ccc; 9 | &::before, 10 | &::after { 11 | content: ''; 12 | position: absolute; 13 | height: 1px; 14 | width: 100%; 15 | top: 50%; 16 | left: 0; 17 | background: #98979d; 18 | } 19 | &::before { 20 | transform: rotate(45deg); 21 | } 22 | &::after { 23 | transform: rotate(-45deg); 24 | } 25 | } 26 | 27 | /** 28 | --------custom line width and color---------- 29 | .vux-close-2px{ 30 | &::before, 31 | &::after { 32 | height: 2px; 33 | margin-top: -1px; 34 | background-color: green; 35 | } 36 | } 37 | */ -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_page/weui_article.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_article { 4 | padding: 20px 15px; 5 | font-size: 15px; 6 | section { 7 | margin-bottom: 1.5em; 8 | } 9 | h1 { 10 | font-size: 17px; 11 | font-weight:400; 12 | margin-bottom: .75em; 13 | } 14 | h2 { 15 | font-size: 16px; 16 | font-weight:400; 17 | margin-bottom: .3em; 18 | } 19 | h3 { 20 | font-weight:400; 21 | font-size: 15px; 22 | } 23 | * { 24 | max-width: 100%; 25 | -webkit-box-sizing: border-box; 26 | box-sizing: border-box; 27 | word-wrap: break-word; 28 | } 29 | p { 30 | margin: 10px 0; 31 | } 32 | } -------------------------------------------------------------------------------- /src/style/weui_mask.less: -------------------------------------------------------------------------------- 1 | @dialog-mask-background: rgba(0, 0, 0, .6); 2 | 3 | .weui_mask { 4 | position: fixed; 5 | z-index: 1000; 6 | width: 100%; 7 | height: 100%; 8 | top: 0; 9 | left: 0; 10 | background: @dialog-mask-background; 11 | } 12 | 13 | .weui_mask_transparent { 14 | position: fixed; 15 | z-index: 5001; 16 | width: 100%; 17 | height: 100%; 18 | top: 0; 19 | left: 0; 20 | } 21 | 22 | .weui_mask_transition { 23 | display: none; 24 | position: fixed; 25 | z-index: 1000; 26 | width: 100%; 27 | height: 100%; 28 | top: 0; 29 | left: 0; 30 | background: rgba(0,0,0,0); 31 | transition:background .3s; 32 | } 33 | 34 | .weui_fade_toggle { 35 | background: rgba(0,0,0,.6); 36 | } 37 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tips/weui_mask.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_mask { 4 | position: fixed; 5 | z-index: 1000; 6 | width: 100%; 7 | height: 100%; 8 | top: 0; 9 | left: 0; 10 | background: @dialog-mask-background; 11 | } 12 | 13 | .weui_mask_transparent { 14 | position: fixed; 15 | z-index: 5001; 16 | width: 100%; 17 | height: 100%; 18 | top: 0; 19 | left: 0; 20 | } 21 | 22 | .weui_mask_transition { 23 | display: none; 24 | position: fixed; 25 | z-index: 1000; 26 | width: 100%; 27 | height: 100%; 28 | top: 0; 29 | left: 0; 30 | background: rgba(0,0,0,0); 31 | transition:background .3s; 32 | } 33 | 34 | .weui_fade_toggle { 35 | background: rgba(0,0,0,.6); 36 | } -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/29 0029. 3 | */ 4 | import Vue from 'vue' 5 | import VueRouter from 'vue-router' 6 | import Album from './components/Album.vue' 7 | import Singer from './components/Singer.vue' 8 | import RankPage from './components/RankPage.vue' 9 | import Cd from './components/Cd.vue' 10 | 11 | Vue.use(VueRouter) 12 | 13 | const routes = [ 14 | { path: '/singer/:id',name:'singer', component: Singer }, 15 | { path: '/album/:id',name:'album', component: Album }, 16 | { path: '/rank/:id',name:'rank', component: RankPage }, 17 | { path: '/cd/:id',name:'cd', component: Cd } 18 | ] 19 | 20 | export default new VueRouter({ 21 | routes, 22 | //只在history模式下有用 23 | scrollBehavior (to, from, savedPosition) { 24 | return { x: 0, y: 0 } 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /src/lib/styles/reddot.less: -------------------------------------------------------------------------------- 1 | .vux-reddot,.vux-reddot-border,.vux-reddot-s { 2 | position: relative; 3 | } 4 | 5 | .vux-reddot:after,.vux-reddot-border:after,.vux-reddot-s:after { 6 | content: ''; 7 | position: absolute; 8 | display: block; 9 | width: 8px; 10 | height: 8px; 11 | background-color: #f74c31; 12 | border-radius: 5px; 13 | right: -3px; 14 | top: -3px; 15 | background-clip: padding-box; 16 | } 17 | 18 | .vux-reddot-border:before { 19 | content: ''; 20 | position: absolute; 21 | display: block; 22 | width: 8px; 23 | height: 8px; 24 | background-color: #fff; 25 | border-radius: 5px; 26 | right: -4px; 27 | top: -4px; 28 | background-clip: padding-box; 29 | padding: 1px; 30 | } 31 | 32 | .vux-reddot-s:after { 33 | width: 6px; 34 | height: 6px; 35 | top: -5px; 36 | right: -5px; 37 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_form/weui_select_before.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | @import "./weui_select"; 3 | 4 | .weui_select_before { 5 | padding-right:@weuiCellGapH; 6 | .weui_select { 7 | width:@weuiCellLabelWidth; 8 | box-sizing: border-box; 9 | } 10 | .weui_cell_hd { 11 | position:relative; 12 | &:after { 13 | .setRightLine(@weuiCellBorderColor); 14 | } 15 | &:before{ 16 | content: " "; 17 | .setArrow_Wap(right, 6px, #C8C8CD, 2px); 18 | 19 | position: absolute; 20 | top: 50%; 21 | right: @weuiCellGapH; 22 | margin-top: -3px; 23 | } 24 | } 25 | .weui_cell_bd { 26 | padding-left:@weuiCellGapH; 27 | &:after{ 28 | display:none; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_check/weui_checkbox.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | 3 | .weui_cells_checkbox { 4 | .weui_cell_hd { 5 | padding-right: @weuiCellInnerGapH; 6 | } 7 | .weui_cell { 8 | &:active { 9 | background-color: #ECECEC; 10 | } 11 | } 12 | .weui_icon_checked { 13 | &:before { 14 | content: '\EA01'; 15 | color: #C9C9C9; 16 | font-size: 23px; 17 | display: block; 18 | } 19 | } 20 | } 21 | 22 | // method2 accessbility 23 | .weui_check { 24 | // checkbox 25 | .weui_cells_checkbox & { 26 | &:checked { 27 | & + .weui_icon_checked { 28 | &:before { 29 | content: '\EA06'; 30 | color: @checkbox-icon-color-checked; 31 | } 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/base/variable/global.less: -------------------------------------------------------------------------------- 1 | // font family 2 | @sansFont:"Helvetica Neue",Helvetica,Arial,sans-serif; 3 | @serifFont:Georgia, "Times New Roman",Times,serif; 4 | @wpFont:"Microsoft YaHei",sans-serif; 5 | @bizFont:"Helvetica Neue",Helvetica,"Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 6 | @globalFont:@sansFont; 7 | @globalFontSize:14px; 8 | 9 | // font color 10 | @globalLinkColor: #61749B; 11 | @globalDescColor: #B2B2B2; 12 | @globalWarnColor: #E64340; 13 | @globalNickNameColor: #576B95; 14 | @globalTextColor: #888; 15 | @globalTitleColor: #000; 16 | 17 | //border 18 | @globalBorderColor: #BCBAB6; 19 | 20 | //arrow 21 | @globalArrowColor: #C7C7CC; 22 | 23 | //component 24 | @itemActiveColor: #E4E4E4; 25 | 26 | //page 27 | @pageDefaultBackgroundColor:#EFEFF4; 28 | 29 | // gap 30 | @gap5:5px; 31 | @gap10:10px; 32 | @gap15:15px; 33 | 34 | // vux theme 35 | @import "../../../variable.less"; -------------------------------------------------------------------------------- /src/lib/components/actionsheet/metas.yml: -------------------------------------------------------------------------------- 1 | props: 2 | show: 3 | en: if show the component 4 | zh-CN: 是否显示 5 | show-cancel: 6 | en: if show the cancel menu 7 | zh-CN: 是否显示取消菜单 8 | cancel-text: 9 | en: text of cancel menu 10 | zh-CN: 取消菜单文字 11 | menus: 12 | en: "menu items, for example: `{menu1: 'some text'}`, menu name with `.noop` will not trigger click events" 13 | zh-CN: "菜单项列表,举例:`{menu1: '删除'}`,如果名字上带有`.noop`表明这是纯文本展示,不会触发事件,用于展示描述" 14 | events: 15 | on-click-menu: 16 | en: triggers when clicking on the menu 17 | zh-CN: 点击菜单时触发,参数为当前菜单项对象 18 | on-click-menu-{menuName}: 19 | en: shortcut event for easily listening, you can listen on `on-click-menu-delete` if you have a menu named `delete` 20 | zh-CN: 点击事件的快捷方式, 如果你有一个菜单名字为`delete`, 那么你可以监听 `on-click-menu-delete` 21 | on-click-menu-cancel: 22 | en: triggers when click on cancel menu 23 | zh-CN: 点击取消菜单时触发 24 | -------------------------------------------------------------------------------- /src/lib/libs/base.js: -------------------------------------------------------------------------------- 1 | import uuidMixin from './mixin_uuid' 2 | 3 | export default { 4 | mixins: [uuidMixin], 5 | props: { 6 | required: { 7 | type: Boolean, 8 | default: true 9 | } 10 | }, 11 | created () { 12 | this.handleChangeEvent = false 13 | }, 14 | computed: { 15 | dirty () { 16 | return !this.prisine 17 | }, 18 | invalid () { 19 | return !this.valid 20 | } 21 | }, 22 | methods: { 23 | setTouched () { 24 | this.touched = true 25 | } 26 | }, 27 | watch: { 28 | value (newVal) { 29 | if (this.prisine === true) { 30 | this.prisine = false 31 | } 32 | if (!this.handleChangeEvent) { 33 | this.$emit('on-change', newVal) 34 | } 35 | } 36 | }, 37 | data () { 38 | return { 39 | errors: {}, 40 | prisine: true, 41 | touched: false, 42 | valid: true 43 | } 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_form/weui_select.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | 3 | .weui_cell_select { 4 | padding-top: 0!important; 5 | padding-bottom: 0!important; 6 | .weui_select { 7 | padding-right: 30px; 8 | } 9 | .weui_access_icon { 10 | 11 | } 12 | .weui_cell_bd{ 13 | &:after{ 14 | content: " "; 15 | .setArrow_Wap(right, 6px, #C8C8CD, 2px); 16 | 17 | position: absolute; 18 | top: 50%; 19 | right: @weuiCellGapH; 20 | margin-top: -3px; 21 | } 22 | } 23 | } 24 | 25 | .weui_select { 26 | -webkit-appearance: none; 27 | border: 0; 28 | outline: 0; 29 | background-color: transparent; 30 | width: 100%; 31 | font-size: inherit; 32 | height: @weuiCellHeight; 33 | line-height: @weuiCellHeight; 34 | position: relative; 35 | z-index: 1; 36 | padding-left: @weuiCellGapH; 37 | } 38 | -------------------------------------------------------------------------------- /src/assets/icon-back.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icon-back-white.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tab/navbar.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_navbar { 4 | display: flex; 5 | position: absolute; 6 | z-index: 500; 7 | top: 0; 8 | width: 100%; 9 | background-color: #fafafa; 10 | 11 | &:after { 12 | .setBottomLine(@globalBorderColor); 13 | } 14 | 15 | & + .weui_tab_bd { 16 | padding-top: 50px; 17 | padding-bottom: 0; 18 | } 19 | } 20 | 21 | .weui_navbar_item { 22 | position: relative; 23 | display: block; 24 | flex: 1; 25 | padding: 13px 0; 26 | text-align: center; 27 | font-size: 15px; 28 | -webkit-tap-highlight-color: transparent; 29 | 30 | &:active { 31 | background-color: #ededed; 32 | } 33 | 34 | &.weui_bar_item_on { 35 | background-color: #eaeaea; 36 | } 37 | 38 | &:after { 39 | .setRightLine(#cccccc); 40 | } 41 | 42 | &:last-child { 43 | &:after { 44 | display: none; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tab/tabbar.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_tabbar { 4 | display: flex; 5 | position: absolute; 6 | z-index: @tabbar-index; 7 | bottom: 0; 8 | width: 100%; 9 | background-color: #f7f7fa; 10 | 11 | &:before { 12 | .setTopLine(#979797); 13 | } 14 | } 15 | 16 | .weui_tabbar_item { 17 | display: block; 18 | flex: 1; 19 | padding: 7px 0 0; 20 | -webkit-tap-highlight-color: transparent; 21 | 22 | &.weui_bar_item_on { 23 | .weui_tabbar_label { 24 | color: @tabbar-text-color-active; 25 | } 26 | } 27 | } 28 | 29 | .weui_tabbar_icon { 30 | margin: 0 auto; 31 | width: 24px; 32 | height: 24px; 33 | 34 | img { 35 | display: block; 36 | width: 100%; 37 | height: 100%; 38 | } 39 | 40 | & + .weui_tabbar_label { 41 | margin-top: 5px; 42 | } 43 | } 44 | 45 | .weui_tabbar_label { 46 | text-align: center; 47 | color: @globalTextColor; 48 | font-size: 12px; 49 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_btn_global.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_btn { 4 | position: relative; 5 | display: block; 6 | margin-left: auto; 7 | margin-right: auto; 8 | padding-left: 14px; 9 | padding-right: 14px; 10 | box-sizing: border-box; 11 | font-size: @weuiBtnFontSize; 12 | text-align: center; 13 | text-decoration: none; 14 | color: @weuiBtnFontColor; 15 | line-height: unit(@weuiBtnHeight/@weuiBtnFontSize); 16 | border-radius: @weuiBtnBorderRadius; 17 | .setTapColor(); 18 | overflow: hidden; 19 | &:after { 20 | content: " "; 21 | width: 200%; 22 | height: 200%; 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | border: 1px solid rgba(0, 0, 0, .2); 27 | transform: scale(.5); 28 | transform-origin: 0 0; 29 | box-sizing: border-box; 30 | border-radius: @weuiBtnBorderRadius*2; 31 | } 32 | 33 | &.weui_btn_inline { 34 | display: inline-block; 35 | } 36 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_page/weui_msg.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | @import "../weui_button/weui_button"; 3 | 4 | .weui_msg { 5 | padding-top: @weuiMsgPaddingTop; 6 | text-align: center; 7 | 8 | .weui_icon_area { 9 | margin-bottom: @weuiMsgIconGap; 10 | } 11 | 12 | .weui_text_area { 13 | margin-bottom: @weuiMsgTextGap; 14 | padding:0 20px; 15 | } 16 | .weui_msg_title { 17 | margin-bottom: @weuiMsgTitleGap; 18 | font-weight: 400; 19 | font-size: 20px; 20 | } 21 | .weui_msg_desc { 22 | font-size: 14px; 23 | color: @globalTextColor; 24 | } 25 | 26 | .weui_opr_area { 27 | margin-bottom: @weuiMsgOprGap; 28 | } 29 | 30 | .weui_extra_area { 31 | margin-bottom: @weuiMsgExtraAreaGap; 32 | font-size: 14px; 33 | color: @globalTextColor; 34 | a{color: @globalLinkColor;} 35 | } 36 | } 37 | 38 | @media screen and (min-height: @weuiMsgExtraAreaOfMinHeight) { 39 | .weui_extra_area { 40 | position: fixed; 41 | left: 0; 42 | bottom: 0; 43 | width: 100%; 44 | text-align: center; 45 | } 46 | } -------------------------------------------------------------------------------- /src/assets/icon-mvcount.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/mixin/setOnepx.less: -------------------------------------------------------------------------------- 1 | 2 | .setTopLine(@c: #C7C7C7) { 3 | content: " "; 4 | position: absolute; 5 | left: 0; 6 | top: 0; 7 | width: 100%; 8 | height: 1px; 9 | border-top: 1px solid @c; 10 | color: @c; 11 | transform-origin: 0 0; 12 | transform: scaleY(0.5); 13 | } 14 | 15 | .setBottomLine(@c: #C7C7C7) { 16 | content: " "; 17 | position: absolute; 18 | left: 0; 19 | bottom: 0; 20 | width: 100%; 21 | height: 1px; 22 | border-bottom: 1px solid @c; 23 | color: @c; 24 | transform-origin: 0 100%; 25 | transform: scaleY(0.5); 26 | } 27 | 28 | .setLeftLine(@c: #C7C7C7) { 29 | content: " "; 30 | position: absolute; 31 | left: 0; 32 | top: 0; 33 | width: 1px; 34 | height: 100%; 35 | border-left: 1px solid @c; 36 | color: @c; 37 | transform-origin: 0 0; 38 | transform: scaleX(0.5); 39 | } 40 | 41 | .setRightLine(@c: #C7C7C7) { 42 | content: " "; 43 | position: absolute; 44 | right: 0; 45 | top: 0; 46 | width: 1px; 47 | height: 100%; 48 | border-right: 1px solid @c; 49 | color: @c; 50 | transform-origin: 100% 0; 51 | transform: scaleX(0.5); 52 | } -------------------------------------------------------------------------------- /src/store/ApiService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/25 0025. 3 | */ 4 | import Vue from 'vue' 5 | 6 | import API from '../config/api' 7 | 8 | function apiFactory(api) { 9 | return (id = null) => Vue.http.jsonp( 10 | api.url, 11 | { 12 | params: api.params(id), 13 | jsonp: api.jsonp 14 | } 15 | ) 16 | } 17 | 18 | export default { 19 | actions: { 20 | getRankSongs({}, id){ 21 | return apiFactory(API.rank_songs)(id) 22 | }, 23 | getRankList({}){ 24 | return apiFactory(API.rank_list)() 25 | }, 26 | getAlbum({}, id){ 27 | return apiFactory(API.album)(id) 28 | }, 29 | getSingerInfo({}, id){ 30 | return apiFactory(API.singer_info)(id) 31 | }, 32 | search({}, key){ 33 | return apiFactory(API.search)(key) 34 | }, 35 | getHotKey({}){ 36 | return apiFactory(API.hotkey)() 37 | }, 38 | getRecommands({}){ 39 | return apiFactory(API.first_page_data)() 40 | }, 41 | getCdList({},id){ 42 | return apiFactory(API.cd)(id) 43 | }, 44 | getLyric({},id){ 45 | return Vue.http.jsonp('https://api.darlin.me/music/lyric/'+id+'/',{ 46 | jsonp:'callback' 47 | }) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/lib/styles/weui/weui.less: -------------------------------------------------------------------------------- 1 | @import "./base/reset"; 2 | 3 | // icon font 4 | @import "./icon/weui_icon_font"; 5 | 6 | 7 | // button 8 | @import "./widget/weui_button/weui_button"; 9 | 10 | // cell 11 | @import "./widget/weui_cell/weui_cell_global"; 12 | 13 | @import "./widget/weui_cell/weui_access"; 14 | @import "./widget/weui_cell/weui_check"; 15 | @import "./widget/weui_cell/weui_form"; 16 | @import "./widget/weui_cell/weui_switch"; 17 | @import "./widget/weui_cell/weui_uploader"; 18 | 19 | // msg 20 | @import "./widget/weui_page/weui_msg"; 21 | 22 | // article 23 | @import "./widget/weui_page/weui_article"; 24 | 25 | // tab 26 | @import "./widget/weui_tab/weui_tab"; 27 | 28 | // progress 29 | @import "./widget/weui_progress/weui_progress"; 30 | 31 | // card 32 | @import "./widget/weui_panel/weui_panel"; 33 | 34 | // media box 35 | @import "./widget/weui_media_box/weui_media_box"; 36 | 37 | // grid 38 | @import "./widget/weui_grid/weui_grid"; 39 | 40 | // tips 41 | @import "./widget/weui_tips/weui_dialog"; 42 | @import "./widget/weui_tips/weui_toast"; 43 | @import "./widget/weui_tips/weui_mask"; 44 | 45 | //action sheet 46 | @import "./widget/weui_tips/weui_actionsheet"; 47 | 48 | //searchbar 49 | @import "./widget/weui_searchbar/weui_searchbar"; -------------------------------------------------------------------------------- /src/store/NotifyService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/29 0029. 3 | */ 4 | import Rx from 'rxjs/Rx' 5 | 6 | export default { 7 | state: { 8 | actionSheet: { 9 | show: false, 10 | menus: {}, 11 | subject: null 12 | }, 13 | playingList:{ 14 | show:false 15 | } 16 | }, 17 | actions: { 18 | notifyActionSheet({commit, state}, options){ 19 | state.actionSheet.subject = new Rx.AsyncSubject() 20 | state.actionSheet.subject.subscribe({ 21 | next: (v) => options.handler[v](), 22 | complete: () => commit('closeActionSheet') 23 | }) 24 | commit('showActionSheet', options.menus) 25 | }, 26 | responceFromActionSheet({state}, menu){ 27 | state.actionSheet.subject.next(menu) 28 | state.actionSheet.subject.complete() 29 | } 30 | }, 31 | mutations: { 32 | showActionSheet(state, menus){ 33 | state.actionSheet.menus = menus 34 | state.actionSheet.show = true 35 | }, 36 | closeActionSheet(state){ 37 | state.actionSheet.show = false 38 | }, 39 | showPlayingList(state){ 40 | state.playingList.show=true 41 | }, 42 | closePlayingList(state){ 43 | state.playingList.show=false 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: './', 11 | productionSourceMap: false, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'] 18 | }, 19 | dev: { 20 | env: require('./dev.env'), 21 | port: 8080, 22 | assetsSubDirectory: 'static', 23 | assetsPublicPath: '/', 24 | proxyTable: {}, 25 | // CSS Sourcemaps off by default because relative paths are "buggy" 26 | // with this option, according to the CSS-Loader README 27 | // (https://github.com/webpack/css-loader#sourcemaps) 28 | // In our experience, they generally work as expected, 29 | // just be aware of this issue when enabling this option. 30 | cssSourceMap: false 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/assets/icon-playing.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icon-erji.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/style/weui_actionsheet.less: -------------------------------------------------------------------------------- 1 | @pageDefaultBackgroundColor:#EFEFF4; 2 | @weuiCellBorderColor:#D9D9D9; 3 | @bgColor:#ECECEC; 4 | .setTopLine(@c: #C7C7C7) { 5 | content: " "; 6 | position: absolute; 7 | left: 0; 8 | top: 0; 9 | width: 100%; 10 | height: 1px; 11 | border-top: 1px solid @c; 12 | color: @c; 13 | transform-origin: 0 0; 14 | transform: scaleY(0.5); 15 | } 16 | .weui_actionsheet { 17 | position: fixed; 18 | left: 0; 19 | bottom: 0; 20 | transform: translate(0, 100%); 21 | backface-visibility: hidden; 22 | z-index: 5000; 23 | width: 100%; 24 | background-color: @pageDefaultBackgroundColor; 25 | //slide up animation 26 | transition: transform .3s; 27 | } 28 | .weui_actionsheet_menu{ 29 | background-color: #FFFFFF; 30 | } 31 | .weui_actionsheet_action { 32 | margin-top: 6px; 33 | background-color: #FFFFFF; 34 | } 35 | .weui_actionsheet_cell { 36 | position: relative; 37 | padding: 10px 0; 38 | text-align: center; 39 | font-size: 18px; 40 | &:before { 41 | .setTopLine(@weuiCellBorderColor); 42 | } 43 | &:active{ 44 | background-color: @bgColor; 45 | } 46 | &:first-child{ 47 | &:before{ 48 | display: none; 49 | } 50 | } 51 | } 52 | 53 | //actionSheet aniamtion 54 | .weui_actionsheet_toggle{ 55 | transform: translate(0, 0); 56 | } 57 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tips/weui_actionsheet.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | @bgColor: #ECECEC; 4 | .weui_actionsheet { 5 | position: fixed; 6 | left: 0; 7 | bottom: 0; 8 | transform: translate(0, 100%); 9 | backface-visibility: hidden; 10 | z-index: 5000; 11 | width: 100%; 12 | height: 100%; 13 | //slide up animation 14 | transition: transform .3s; 15 | } 16 | 17 | .weui_actionsheet_menu { 18 | background-color: #FFFFFF; 19 | position: fixed; 20 | left: 0; 21 | bottom: 0; 22 | transform: translate(0, 100%); 23 | backface-visibility: hidden; 24 | z-index: 5000; 25 | width: 100%; 26 | //slide up animation 27 | transition: transform .3s; 28 | } 29 | 30 | .weui_actionsheet_action { 31 | margin-top: 6px; 32 | background-color: #FFFFFF; 33 | } 34 | 35 | .weui_actionsheet_cell { 36 | position: relative; 37 | display: flex; 38 | flex-direction: column; 39 | align-items: center; 40 | justify-content: center; 41 | min-height: 25px; 42 | padding:10px 0; 43 | text-align: center; 44 | font-size: 18px; 45 | cursor: pointer; 46 | &:before { 47 | .setTopLine(@weuiCellBorderColor); 48 | } 49 | &:active { 50 | background-color: @bgColor; 51 | } 52 | &:first-child { 53 | &:before { 54 | display: none; 55 | } 56 | } 57 | } 58 | 59 | //actionSheet aniamtion 60 | .weui_actionsheet_toggle { 61 | transform: translate(0, 0); 62 | } 63 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_panel/weui_panel.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | @lineColor: #E5E5E5; 4 | @grayColor: #999999; 5 | 6 | .weui_panel { 7 | background-color: #FFFFFF; 8 | margin-top: 10px; 9 | &:first-child { 10 | margin-top: 0; 11 | } 12 | 13 | position: relative; 14 | overflow: hidden; 15 | &:before { 16 | .setTopLine(@lineColor); 17 | } 18 | &:after { 19 | .setBottomLine(@lineColor); 20 | } 21 | } 22 | 23 | .weui_panel_hd { 24 | padding: 14px 15px 10px; 25 | color: @grayColor; 26 | font-size: 13px; 27 | position: relative; 28 | &:after { 29 | .setBottomLine(@lineColor); 30 | left: 15px; 31 | } 32 | } 33 | 34 | .weui_panel_ft { 35 | padding: 10px 15px 12px; 36 | color: @grayColor; 37 | font-size: 14px; 38 | position: relative; 39 | &:before { 40 | .setTopLine(@lineColor); 41 | left: 15px; 42 | } 43 | .weui_panel_access & { 44 | display: block; 45 | color: #586C94; 46 | .setTapColor; 47 | &:active{ 48 | background-color:#ECECEC; 49 | } 50 | &:after { 51 | content: " "; 52 | .setArrow_Wap(right, 6px, #C7C7CC, 2px); 53 | position: absolute; 54 | right: 15px; 55 | top: 50%; 56 | margin-top: -4px; 57 | } 58 | } 59 | } 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_switch.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | @weuiSwitchHeight: 32px; 3 | .weui_cell.weui_cell_switch{ 4 | padding-top: (@weuiCellHeight - @weuiSwitchHeight) / 2; 5 | padding-bottom: (@weuiCellHeight - @weuiSwitchHeight) / 2; 6 | } 7 | .weui_switch{ 8 | appearance: none; 9 | position: relative; 10 | width: 52px; 11 | height: @weuiSwitchHeight; 12 | border: 1px solid #DFDFDF; 13 | outline: 0; 14 | border-radius: 16px; 15 | box-sizing: border-box; 16 | background: #DFDFDF; 17 | &:before{ 18 | content: " "; 19 | position: absolute; 20 | top: 0; 21 | left: 0; 22 | width: 50px; 23 | height: @weuiSwitchHeight - 2; 24 | border-radius: 15px; 25 | background-color: #FDFDFD; 26 | transition:transform .3s; 27 | } 28 | &:after{ 29 | content: " "; 30 | position: absolute; 31 | top: 0; 32 | left: 0; 33 | width: @weuiSwitchHeight - 2; 34 | height: @weuiSwitchHeight - 2; 35 | border-radius: 15px; 36 | background-color: #FFFFFF; 37 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); 38 | transition:transform .3s; 39 | } 40 | 41 | &:checked{ 42 | border-color: @switch-checked-border-color; 43 | background-color: @switch-checked-bg-color; 44 | &:before{ 45 | transform: scale(0); 46 | } 47 | &:after{ 48 | transform: translateX(20px); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/assets/error.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_button/weui_button.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | // 存在样式优先级的问题,故这里对其他weui_btn的引用放在底部 3 | // 主要是button.weui_btn在weui_btn_plain下重写border-width 4 | 5 | .weui_btn { 6 | &.weui_btn_mini { 7 | line-height: @weuiBtnMiniHeight; 8 | font-size: @weuiBtnMiniFontSize; 9 | padding: 0 .75em; 10 | display: inline-block; 11 | } 12 | } 13 | 14 | button, input { 15 | &.weui_btn { 16 | width: 100%; 17 | border-width: 0; 18 | outline: 0; 19 | -webkit-appearance: none; 20 | &:focus { 21 | outline: 0; 22 | } 23 | } 24 | &.weui_btn_inline,&.weui_btn_mini { 25 | width: auto; 26 | } 27 | } 28 | 29 | /*gap between btn*/ 30 | .weui_btn + .weui_btn { 31 | margin-top: @weuiBtnDefaultGap; 32 | } 33 | 34 | .weui_btn.weui_btn_inline + .weui_btn.weui_btn_inline { 35 | margin-top: auto; 36 | margin-left: @weuiBtnDefaultGap; 37 | } 38 | 39 | .weui_btn_area { 40 | margin: @weuiCellsMarginTop @weuiBtnDefaultGap .3em; 41 | &.weui_btn_area_inline { 42 | display: flex; 43 | .weui_btn { 44 | margin-top: auto; 45 | margin-right: @weuiBtnDefaultGap; 46 | width: 100%; 47 | flex: 1; 48 | &:last-child { 49 | margin-right: 0; 50 | } 51 | } 52 | } 53 | } 54 | 55 | @import "weui_btn_global"; 56 | @import "weui_btn_default"; 57 | @import "weui_btn_primary"; 58 | @import "weui_btn_warn"; 59 | @import "weui_btn_disabled"; 60 | @import "weui_btn_plain"; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-music", 3 | "version": "1.0.1", 4 | "description": "A mobile web player", 5 | "author": "Sioxas ", 6 | "private": false, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js", 10 | "lint": "eslint --ext .js,.vue src" 11 | }, 12 | "dependencies": { 13 | "rxjs": "^5.0.2", 14 | "vue": "^2.0.1", 15 | "vue-awesome-swiper": "^2.2.6", 16 | "vue-lazyload": "1.0.0-rc12", 17 | "vue-resource": "^1.0.3", 18 | "vue-router": "^2.1.1", 19 | "vuex": "^2.0.0" 20 | }, 21 | "devDependencies": { 22 | "autoprefixer": "^6.4.0", 23 | "babel-core": "^6.0.0", 24 | "babel-eslint": "^7.0.0", 25 | "babel-loader": "^6.0.0", 26 | "babel-plugin-transform-runtime": "^6.0.0", 27 | "babel-preset-es2015": "^6.0.0", 28 | "babel-preset-stage-2": "^6.0.0", 29 | "babel-register": "^6.0.0", 30 | "connect-history-api-fallback": "^1.1.0", 31 | "css-loader": "^0.25.0", 32 | "eslint-friendly-formatter": "^2.0.5", 33 | "eventsource-polyfill": "^0.9.6", 34 | "express": "^4.13.3", 35 | "extract-text-webpack-plugin": "^1.0.1", 36 | "file-loader": "^0.9.0", 37 | "function-bind": "^1.0.2", 38 | "html-webpack-plugin": "^2.8.1", 39 | "http-proxy-middleware": "^0.17.2", 40 | "json-loader": "^0.5.4", 41 | "less": "^2.7.1", 42 | "less-loader": "^2.2.3", 43 | "opn": "^4.0.2", 44 | "ora": "^0.3.0", 45 | "shelljs": "^0.7.4", 46 | "url-loader": "^0.5.7", 47 | "vue-loader": "^9.4.0", 48 | "vue-style-loader": "^1.0.0", 49 | "webpack": "^1.13.2", 50 | "webpack-dev-middleware": "^1.8.3", 51 | "webpack-hot-middleware": "^2.12.2", 52 | "webpack-merge": "^0.14.1" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_grid/weui_grid.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_grids { 4 | position: relative; 5 | overflow: hidden; 6 | 7 | &:before { 8 | content: ''; 9 | position: absolute; 10 | box-sizing: border-box; 11 | width: 200%; 12 | height: 200%; 13 | left: 0; 14 | top: 0; 15 | border: 1px solid @weuiGridBorderColor; 16 | transform-origin: 0 0; 17 | transform: scale(.5); 18 | } 19 | } 20 | 21 | .weui_grid { 22 | position: relative; 23 | float: left; 24 | padding: 20px 10px; 25 | width: 100% / @weuiGridColumnCount; 26 | box-sizing: border-box; 27 | 28 | &:before { 29 | content: ''; 30 | position: absolute; 31 | box-sizing: border-box; 32 | width: 200%; 33 | height: 200%; 34 | left: 0; 35 | top: 0; 36 | border-bottom: 1px solid @weuiGridBorderColor; 37 | border-right: 1px solid @weuiGridBorderColor; 38 | transform-origin: 0 0; 39 | transform: scale(.5); 40 | } 41 | 42 | &:nth-child(3n) { 43 | &:before { 44 | border-right-width: 0; 45 | } 46 | } 47 | 48 | &:active { 49 | background-color: @itemActiveColor; 50 | } 51 | } 52 | 53 | .weui_grid_icon { 54 | width: @weuiGridIconSize; 55 | height: @weuiGridIconSize; 56 | margin: 0 auto; 57 | 58 | img { 59 | display: block; 60 | width: 100%; 61 | height: 100%; 62 | } 63 | 64 | & + .weui_grid_label { 65 | margin-top: 5px; 66 | } 67 | } 68 | 69 | .weui_grid_label { 70 | display: block; 71 | text-align: center; 72 | color: @globalTitleColor; 73 | font-size: @weuiGridFontSize; 74 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_cell_global.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_cell { 4 | // onepx 5 | position: relative; 6 | &:before { 7 | .setTopLine(@weuiCellBorderColor); 8 | left: @weuiCellGapH; 9 | } 10 | &:first-child { 11 | &:before { 12 | display: none; 13 | } 14 | } 15 | } 16 | 17 | .weui_cells { 18 | margin-top: @weuiCellsMarginTop; 19 | background-color: @weuiCellBg; 20 | line-height: @weuiCellLineHeight; 21 | font-size: @weuiCellFontSize; //cell中间有效高度23px,跟客户端默认图标尺寸一致 22 | 23 | overflow: hidden; //因为每个cell的border使用before元素left搞的,ie下伪元素的containing block估计跟标准不同,在cell上用oh不生效 24 | 25 | // onepx 26 | position: relative; 27 | &:before { 28 | .setTopLine(@weuiCellBorderColor); 29 | } 30 | &:after { 31 | .setBottomLine(@weuiCellBorderColor); 32 | } 33 | } 34 | 35 | .weui_cells_title { 36 | margin-top: .77em; // 15px - 行高 37 | margin-bottom: .3em; // 8px - 行高 38 | padding-left: @weuiCellGapH; 39 | padding-right: @weuiCellGapH; 40 | color: @globalTextColor; 41 | font-size: @weuiCellTipsFontSize; 42 | 43 | & + .weui_cells { 44 | margin-top: 0; 45 | } 46 | } 47 | 48 | .weui_cells_tips { 49 | margin-top: .3em; // 8px - 行高 50 | color: @globalTextColor; 51 | padding-left: @weuiCellGapH; 52 | padding-right: @weuiCellGapH; 53 | font-size: @weuiCellTipsFontSize; 54 | } 55 | 56 | .weui_cell { 57 | padding: @weuiCellGapV @weuiCellGapH; 58 | position: relative; //这个是为了兼容cells容器onepx方案被before挡住而做的 59 | display: flex; 60 | align-items: center; 61 | } 62 | 63 | .weui_cell_ft { 64 | text-align: right; 65 | color: @globalTextColor; 66 | } 67 | 68 | .weui_cell_primary { 69 | flex: 1; 70 | } -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_form/weui_form_common.less: -------------------------------------------------------------------------------- 1 | @import "../../../base/fn"; 2 | 3 | .weui_label{ 4 | color: @cell-label-color; 5 | display:block; 6 | width:@weuiCellLabelWidth; 7 | .text_wrap(); 8 | } 9 | .weui_input { 10 | width: 100%; 11 | border: 0; 12 | outline: 0; 13 | -webkit-appearance: none; 14 | background-color: transparent; 15 | font-size: inherit; 16 | color: inherit; 17 | height: unit(@weuiCellLineHeight, em); 18 | line-height: @weuiCellLineHeight; 19 | 20 | // hides the spin-button 21 | &::-webkit-outer-spin-button, &::-webkit-inner-spin-button{ 22 | -webkit-appearance: none; 23 | margin: 0; 24 | } 25 | } 26 | .weui_textarea { 27 | display: block; 28 | border: 0; 29 | resize: none; 30 | width: 100%; 31 | color: inherit; 32 | font-size: 1em; 33 | line-height: inherit; 34 | outline: 0; 35 | } 36 | 37 | .weui_textarea_counter{ 38 | color: @globalDescColor; 39 | text-align: right; 40 | .weui_cell_warn &{ 41 | color: @globalWarnColor; 42 | } 43 | } 44 | 45 | .weui_toptips { 46 | display:none; 47 | position: fixed; 48 | -webkit-transform: translateZ(0); 49 | width: 100%; 50 | top: 0; 51 | line-height: 2.3; 52 | font-size:14px; 53 | text-align: center; 54 | color: #FFF; 55 | z-index: 50000; 56 | &.weui_warn { 57 | background-color: @globalWarnColor; 58 | } 59 | } 60 | .weui_cells_form { 61 | .weui_cell_warn{ 62 | color:@globalWarnColor; 63 | .weui_icon_warn{display:inline-block;} 64 | } 65 | .weui_cell_ft{font-size:0;} 66 | .weui_icon_warn{ 67 | display:none; 68 | } 69 | input, textarea, label[for]{ 70 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/lib/mixins/multi-items.js: -------------------------------------------------------------------------------- 1 | const parentMixin = { 2 | ready () { 3 | this.updateIndex() 4 | }, 5 | methods: { 6 | updateIndex () { 7 | if (!this.$children) return 8 | this.number = this.$children.length 9 | let children = this.$children 10 | for (let i = 0; i < children.length; i++) { 11 | children[i].index = i 12 | if (children[i].selected) { 13 | this.index = i 14 | } 15 | } 16 | } 17 | }, 18 | props: { 19 | index: { 20 | type: Number, 21 | default: -1 22 | } 23 | }, 24 | watch: { 25 | index (val, oldVal) { 26 | oldVal > -1 && this.$children[oldVal] && (this.$children[oldVal].selected = false) 27 | val > -1 && (this.$children[val].selected = true) 28 | } 29 | }, 30 | data () { 31 | return { 32 | number: this.$children.length 33 | } 34 | } 35 | } 36 | 37 | const childMixin = { 38 | props: { 39 | selected: { 40 | type: Boolean, 41 | default: false 42 | } 43 | }, 44 | ready () { 45 | this.$parent.updateIndex() 46 | }, 47 | beforeDestroy () { 48 | const $parent = this.$parent 49 | this.$nextTick(() => { 50 | $parent.updateIndex() 51 | }) 52 | }, 53 | methods: { 54 | onItemClick () { 55 | if (typeof this.disabled === 'undefined' || this.disabled === false) { 56 | this.selected = true 57 | this.$parent.index = this.index 58 | this.$emit('on-item-click') 59 | } 60 | } 61 | }, 62 | watch: { 63 | selected (val) { 64 | if (val) { 65 | this.$parent.index = this.index 66 | } else { 67 | this.$parent.index = -1 68 | } 69 | } 70 | }, 71 | data () { 72 | return { 73 | index: -1 74 | } 75 | } 76 | } 77 | 78 | export { 79 | parentMixin, 80 | childMixin 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/lib/styles/weui/icon/weui_icon_font.less: -------------------------------------------------------------------------------- 1 | @import "weui_font"; 2 | 3 | [class^="weui_icon_"]:before, [class*=" weui_icon_"]:before { 4 | margin: 0; 5 | } 6 | 7 | :before { 8 | .weui_icon_success& { 9 | font-size: 23px; 10 | color: #09BB07; 11 | } 12 | .weui_icon_waiting& { 13 | font-size: 23px; 14 | color: #10AEFF; 15 | } 16 | .weui_icon_warn& { 17 | font-size: 23px; 18 | color: #F43530; 19 | } 20 | .weui_icon_info& { 21 | font-size: 23px; 22 | color: #10AEFF; 23 | } 24 | 25 | .weui_icon_success_circle& { 26 | font-size: 23px; 27 | color: #09BB07; 28 | } 29 | .weui_icon_success_no_circle& { 30 | font-size: 23px; 31 | color: #09BB07; 32 | } 33 | .weui_icon_waiting_circle& { 34 | font-size: 23px; 35 | color: #10AEFF; 36 | } 37 | .weui_icon_circle& { 38 | font-size: 23px; 39 | color: #C9C9C9; 40 | } 41 | .weui_icon_download& { 42 | font-size: 23px; 43 | color: #09BB07; 44 | } 45 | 46 | .weui_icon_info_circle& { 47 | font-size: 23px; 48 | color: #09BB07; 49 | } 50 | 51 | .weui_icon_safe_success& { 52 | color: #09BB07; 53 | } 54 | .weui_icon_safe_warn& { 55 | color: #FFBE00; 56 | } 57 | 58 | .weui_icon_cancel& { 59 | color: #F43530; 60 | font-size: 22px; 61 | } 62 | 63 | .weui_icon_search& { 64 | color: #B2B2B2; 65 | font-size: 14px; 66 | } 67 | 68 | .weui_icon_clear& { 69 | color: #B2B2B2; 70 | font-size: 14px; 71 | } 72 | } 73 | 74 | :before { 75 | .weui_icon_msg& { 76 | font-size: 104px; 77 | .weui_icon_warn& { 78 | color: #F76260; 79 | } 80 | } 81 | } 82 | 83 | :before { 84 | .weui_icon_safe& { 85 | font-size: 104px; 86 | } 87 | } -------------------------------------------------------------------------------- /src/lib/styles/variable.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Before v1.0, the variable names may change anytime. 3 | */ 4 | @namespace: vux; 5 | 6 | @color-wechat-green: #04BE02; 7 | 8 | @theme-color: #04BE02; 9 | @opacity-disabled: 0.5; 10 | 11 | /** 12 | * tabbar 13 | */ 14 | @tabbar-text-color-active: #09BB07; 15 | 16 | /** 17 | * dialog 18 | */ 19 | @dialog-button-text-primary-color: #0BB20C; 20 | @dialog-button-text-default-color: #353535; 21 | 22 | /** 23 | * x-number 24 | */ 25 | @x-number-button-color: #3cc51f; 26 | @x-number-number-color: #666; 27 | 28 | /** 29 | * checkbox 30 | */ 31 | @checkbox-icon-color-checked: #09BB07; 32 | 33 | /** 34 | * check-icon 35 | */ 36 | @check-icon-color-checked: @checkbox-icon-color-checked; 37 | 38 | /** 39 | * Cell 40 | */ 41 | @cell-label-color: #000; 42 | 43 | /** 44 | * Mask 45 | */ 46 | @dialog-mask-background: rgba(0, 0, 0, .6); 47 | 48 | /** 49 | * Range 50 | */ 51 | @range-opacity-disabled: @opacity-disabled; 52 | @range-color-bar-default: #a9acb1; 53 | @range-color-bar-active: @theme-color; 54 | 55 | /** 56 | * Tabbar 57 | */ 58 | @tabbar-index: 100; 59 | 60 | /** 61 | * XHeader 62 | */ 63 | @x-header-background-color: #35495e; 64 | @x-header-title-color: #fff; 65 | @x-header-text-color: #ccc; 66 | @x-header-arrow-color: #ccc; 67 | 68 | /** 69 | * Timeline 70 | */ 71 | @timeline-item-bg-color: @theme-color; 72 | 73 | /** 74 | * Switch 75 | */ 76 | @switch-checked-bg-color: @theme-color; 77 | @switch-checked-border-color: @theme-color; 78 | 79 | /** 80 | * Button 81 | */ 82 | @button-warn-bg-color: #EF4F4F; 83 | @button-warn-active-color: #C13E3E; 84 | 85 | /** 86 | * Cell 87 | */ 88 | @cell-body-label-color: #000; 89 | 90 | /** 91 | * Badge 92 | */ 93 | @badge-bg-color: #f74c31; 94 | 95 | /** 96 | * Popover 97 | */ 98 | @popover-bg-color: #35495e; 99 | @popover-font-color: #fff; 100 | @popover-border-radius: 3px; 101 | @popover-border-width: 5px; 102 | -------------------------------------------------------------------------------- /src/assets/icon-SINGLE.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/components/actionsheet/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 52 | 53 | 73 | -------------------------------------------------------------------------------- /src/lib/components/mvitem.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 40 | 41 | 42 | 84 | -------------------------------------------------------------------------------- /src/components/ActionSheet.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 51 | 52 | 72 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tips/weui_dialog.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | @weuiDialogBackgroundColor: #FAFAFC; 4 | @weuiDialogLineColor: #D5D5D6; 5 | @weuiDialogLinkColor: #3CC51F; 6 | @weuiDialogLinkActiveBc: #EEEEEE; 7 | 8 | .weui_dialog { 9 | position: fixed; 10 | z-index: 5000; 11 | width: 85%; 12 | top: 50%; 13 | left: 50%; 14 | transform: translate(-50%, -50%); 15 | 16 | background-color: @weuiDialogBackgroundColor; 17 | text-align: center; 18 | border-radius: 3px; 19 | overflow: hidden; 20 | .weui_dialog_confirm & { 21 | .weui_dialog_hd { 22 | padding: 1.2em 20px .5em; 23 | } 24 | .weui_dialog_bd { 25 | text-align: left; 26 | } 27 | } 28 | } 29 | 30 | .weui_dialog_hd { 31 | padding: 1.2em 0 .5em; 32 | } 33 | 34 | .weui_dialog_title { 35 | font-weight: 400; 36 | font-size: 17px; 37 | } 38 | 39 | .weui_dialog_bd { 40 | padding: 0 20px; 41 | font-size: 15px; 42 | color: @globalTextColor; 43 | word-wrap: break-word; 44 | word-break: break-all; 45 | } 46 | 47 | .weui_dialog_ft { 48 | position: relative; 49 | line-height: 42px; 50 | margin-top: 20px; 51 | font-size: 17px; 52 | display: flex; 53 | a { 54 | display: block; 55 | flex: 1; 56 | color: @weuiDialogLinkColor; 57 | text-decoration: none; 58 | .setTapColor; 59 | &:active { 60 | background-color: @weuiDialogLinkActiveBc; 61 | } 62 | } 63 | &:after { 64 | content: " "; 65 | .setTopLine(@weuiDialogLineColor); 66 | } 67 | .weui_dialog_confirm & { 68 | a { 69 | position: relative; 70 | &:after { 71 | content: " "; 72 | .setLeftLine(@weuiDialogLineColor); 73 | } 74 | &:first-child { 75 | &:after { 76 | display: none; 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | .weui_btn_dialog { 84 | &.default { 85 | color: @dialog-button-text-default-color; 86 | } 87 | &.primary { 88 | color: @dialog-button-text-primary-color; 89 | } 90 | } 91 | 92 | @media screen and (min-width: 1024px) { 93 | .weui_dialog { 94 | width: 35%; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_media_box/weui_media_box.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | @lineColor: #E5E5E5; 4 | @grayColor: #999999; 5 | 6 | .weui_media_box { 7 | padding: 15px; 8 | position: relative; 9 | &:before { 10 | .setTopLine(@lineColor); 11 | left: 15px; 12 | } 13 | &:first-child { 14 | &:before { 15 | display: none 16 | } 17 | } 18 | 19 | a&{ 20 | color:#000000; 21 | .setTapColor; 22 | &:active{ 23 | background-color:#ECECEC; 24 | } 25 | } 26 | 27 | .weui_media_title { 28 | font-weight: 400; 29 | font-size: 17px; 30 | .ellipsis(); 31 | word-wrap: break-word; 32 | word-break: break-all; 33 | } 34 | .weui_media_desc { 35 | color: @grayColor; 36 | font-size: 13px; 37 | line-height: 1.2; 38 | .ellipsisLn(2); 39 | } 40 | 41 | &.weui_media_text { 42 | .weui_media_title { 43 | margin-bottom: 8px; 44 | } 45 | .weui_media_info { 46 | margin-top: 15px; 47 | padding-bottom: 5px; 48 | font-size: 13px; 49 | color: #CECECE; 50 | line-height: 1em; 51 | list-style: none; 52 | overflow: hidden; 53 | } 54 | .weui_media_info_meta { 55 | float: left; 56 | padding-right: 1em; 57 | &.weui_media_info_meta_extra { 58 | padding-left: 1em; 59 | border-left: 1px solid #CECECE; 60 | } 61 | } 62 | 63 | } 64 | &.weui_media_appmsg { 65 | display: flex; 66 | align-items: center; 67 | .weui_media_hd { 68 | margin-right: .8em; 69 | width: 60px; 70 | height: 60px; 71 | line-height: 60px; 72 | text-align: center; 73 | } 74 | .weui_media_appmsg_thumb { 75 | width: 100%; 76 | max-height: 100%; 77 | vertical-align: top; 78 | } 79 | .weui_media_bd { 80 | flex: 1; 81 | min-width: 0; 82 | } 83 | } 84 | &.weui_media_small_appmsg { 85 | padding: 0; 86 | .weui_cells { 87 | margin-top: 0; 88 | &:before { 89 | display: none; 90 | } 91 | } 92 | .weui_cells_access { 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /src/components/Lyric.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 65 | 66 | 67 | 90 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_cell/weui_uploader.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | @weuiUploaderBorderColor:#D9D9D9; 4 | @weuiUploaderActiveBorderColor:#999999; 5 | @weuiUploaderFileSpacing: 9px; 6 | @weuiUploaderSize: 79px; 7 | @weuiUploaderBorderWidth: 1px; 8 | 9 | .weui_uploader{} 10 | .weui_uploader_hd{ 11 | padding-top: 0; 12 | padding-right: 0; 13 | padding-left: 0; 14 | .weui_cell_ft{ 15 | font-size: 1em; 16 | } 17 | } 18 | .weui_uploader_bd{ 19 | margin-bottom: @weuiCellGapH - (@weuiCellGapV + @weuiUploaderFileSpacing); 20 | margin-right: -@weuiUploaderFileSpacing; 21 | overflow: hidden; 22 | } 23 | 24 | .weui_uploader_files{ 25 | list-style: none; 26 | } 27 | .weui_uploader_file{ 28 | float: left; 29 | margin-right: @weuiUploaderFileSpacing; 30 | margin-bottom: @weuiUploaderFileSpacing; 31 | width: @weuiUploaderSize; 32 | height: @weuiUploaderSize; 33 | background: no-repeat center center; 34 | background-size: cover; 35 | } 36 | .weui_uploader_status{ 37 | position: relative; 38 | &:before{ 39 | content: " "; 40 | position: absolute; 41 | top: 0; 42 | right: 0; 43 | bottom: 0; 44 | left: 0; 45 | background-color: rgba(0, 0, 0, .5); 46 | } 47 | .weui_uploader_status_content{ 48 | position: absolute; 49 | top: 50%; 50 | left: 50%; 51 | transform: translate(-50%, -50%); 52 | color: #FFFFFF; 53 | } 54 | .weui_icon_warn{ 55 | display: block; 56 | } 57 | } 58 | 59 | .weui_uploader_input_wrp{ 60 | float:left; 61 | position: relative; 62 | margin-right: @weuiUploaderFileSpacing; 63 | margin-bottom: @weuiUploaderFileSpacing; 64 | width: @weuiUploaderSize - @weuiUploaderBorderWidth * 2; 65 | height: @weuiUploaderSize - @weuiUploaderBorderWidth * 2; 66 | border: @weuiUploaderBorderWidth solid @weuiUploaderBorderColor; 67 | &:before, &:after{ 68 | content: " "; 69 | position: absolute; 70 | top: 50%; 71 | left: 50%; 72 | transform: translate(-50%, -50%); 73 | background-color: @weuiUploaderBorderColor; 74 | } 75 | &:before{ 76 | width: @weuiUploaderBorderWidth + 1; 77 | height: @weuiUploaderSize / 2; 78 | } 79 | &:after{ 80 | width: @weuiUploaderSize / 2; 81 | height: @weuiUploaderBorderWidth + 1; 82 | } 83 | &:active{ 84 | border-color: @weuiUploaderActiveBorderColor; 85 | &:before, &:after{ 86 | background-color: @weuiUploaderActiveBorderColor; 87 | } 88 | } 89 | } 90 | .weui_uploader_input{ 91 | position: absolute; 92 | z-index: 1; 93 | top: 0; 94 | left: 0; 95 | width: 100%; 96 | height: 100%; 97 | opacity: 0; 98 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 99 | } -------------------------------------------------------------------------------- /src/assets/loading.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_searchbar/weui_searchbar.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | .weui_search_bar { 3 | position: relative; 4 | padding: 8px 10px; 5 | display: flex; 6 | box-sizing: border-box; 7 | background-color: #EFEFF4; 8 | &:before { 9 | .setTopLine(); 10 | } 11 | &:after { 12 | .setBottomLine(); 13 | } 14 | &.weui_search_focusing{ 15 | .weui_search_cancel{ 16 | display: block; 17 | } 18 | .weui_search_text{ 19 | display: none; 20 | } 21 | } 22 | } 23 | .weui_search_outer { 24 | position: relative; 25 | flex: auto; 26 | background-color: #EFEFF4; 27 | &:after{ 28 | content: ''; 29 | position: absolute; 30 | left: 0; 31 | top:0; 32 | width: 200%; 33 | height: 200%; 34 | transform: scale(.5); 35 | transform-origin: 0 0; 36 | border-radius: 10px; 37 | border: 1px solid #E6E6EA; 38 | box-sizing: border-box; 39 | background: #FFFFFF; 40 | } 41 | } 42 | .weui_search_inner { 43 | position: relative; 44 | padding-left: 30px; 45 | padding-right: 30px; 46 | height: 100%; 47 | width: 100%; 48 | box-sizing: border-box; 49 | z-index: 1; 50 | .weui_search_input { 51 | padding: 4px 0; 52 | width: 100%; 53 | height: 20/14em; 54 | border: 0; 55 | font-size: 14px; 56 | line-height: 20/14em; 57 | box-sizing: content-box; 58 | background: transparent; 59 | &:focus { 60 | outline: none; 61 | } 62 | } 63 | .weui_icon_search { 64 | position: absolute; 65 | left: 10px; 66 | top: -2px; 67 | line-height: 28px; 68 | } 69 | .weui_icon_clear { 70 | position: absolute; 71 | top: -2px; 72 | right: 0; 73 | padding: 0 10px; 74 | line-height: 28px; 75 | } 76 | } 77 | .weui_search_text { 78 | position: absolute; 79 | top: 1px; 80 | right: 1px; 81 | bottom: 1px; 82 | left: 1px; 83 | z-index: 2; 84 | border-radius: 3px; 85 | text-align: center; 86 | color: #9B9B9B; 87 | background: #FFFFFF; 88 | span { 89 | display: inline-block; 90 | font-size: 14px; 91 | vertical-align: middle; 92 | } 93 | .weui_icon_search { 94 | margin-right: 5px; 95 | } 96 | } 97 | .weui_search_cancel { 98 | display: none; 99 | margin-left: 10px; 100 | line-height: 28px; 101 | white-space: nowrap; 102 | color: #09BB07; 103 | } 104 | .weui_search_input:not(:valid) ~ .weui_icon_clear { 105 | display: none; 106 | } 107 | 108 | //干掉input[search]默认的clear button 109 | input[type="search"]::-webkit-search-decoration, 110 | input[type="search"]::-webkit-search-cancel-button, 111 | input[type="search"]::-webkit-search-results-button, 112 | input[type="search"]::-webkit-search-results-decoration { 113 | display: none; 114 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

Vue 音乐搜索、播放 Demo,资源来自QQ音乐

3 |

4 | Vue 5 | vue-cli 6 | Vue 7 | vue-resource 8 | vue-router 9 | vuex 10 | vue-awesome-swiper 11 | rxjs 12 | vue-lazyload 13 |

14 |

查看Demo:http://sioxas.github.io/,在手机上效果更好,扫一扫体验

15 |

vue-music

16 | 17 | 18 | ### 实现的功能 19 | 1. 音乐播放、暂停、上一曲、下一曲 20 | 2. 播放列表、添加到播放列表、做为下一首播放 21 | 3. 搜索单曲、歌手、专辑、MV 22 | 4. 查看歌手页面、专辑页面、MV 23 | 5. 热门搜索 24 | 6. 搜索历史记录 25 | 7. 排行榜 26 | 8. 切换播放模式 27 | 9. 歌词 28 | 29 | ### 未实现的功能 30 | * 我喜欢 31 | * 下载 32 | 33 | ## Build Setup 34 | 35 | ``` bash 36 | # 下载或克隆下来,然后安装依赖 37 | npm install 38 | 39 | # 开发预览 40 | npm run dev 41 | 42 | # 打包发布,生成的文件在dist文件夹中 43 | npm run build 44 | ``` 45 | 46 | # 截图 47 | 48 | 49 | ### 推荐 50 | ![推荐](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_2249.PNG) 51 | ### 排行榜 52 | ![排行榜](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1807.PNG) 53 | ![榜单](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1800.PNG) 54 | ### 搜索 55 | ![热门搜索和历史记录](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1808.PNG) 56 | ![搜索结果](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1351.PNG) 57 | ![搜索结果](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1591.PNG) 58 | ### 播放页面 59 | ![播放页面](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1352.PNG) 60 | ### 专辑页面 61 | ![专辑页面](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1587.PNG) 62 | ### 歌手页面 63 | ![歌手页面](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1588.PNG) 64 | ![歌手页面](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1589.PNG) 65 | ### 播放列表 66 | ![播放列表](https://github.com/Sioxas/GitImage/raw/master/screenshot/IMG_1590.PNG) 67 | -------------------------------------------------------------------------------- /src/components/Rank.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 48 | 49 | 50 | 125 | -------------------------------------------------------------------------------- /src/store/PlayService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/25 0025. 3 | */ 4 | import * as def from '../config/def' 5 | 6 | export default { 7 | state: { 8 | playing: false, 9 | currentTime: 0, 10 | duration: 0, 11 | playMode: def.SEQUENTIAL, 12 | index: 0, 13 | song: { 14 | name: def.DEFAULT_SONG_NAME 15 | }, 16 | playList: [] 17 | }, 18 | mutations: { 19 | playIndex (state, index) { 20 | state.index = index 21 | state.song = state.playList[index] 22 | }, 23 | setPlayList (state, playList) { 24 | state.playList = playList.list 25 | state.index = playList.index 26 | state.song = state.playList[state.index] 27 | }, 28 | addToPlayList (state, item) { 29 | state.playList.push(item) 30 | }, 31 | deleteFromPlayList (state, index) { 32 | if (isNaN(index) || index >= state.playList.length) { 33 | return false 34 | } 35 | if (index === state.index) { 36 | if (state.index === 0 && state.playList.length === 1) { 37 | state.song = { 38 | name: def.DEFAULT_SONG_NAME, 39 | singer: '' 40 | } 41 | state.coverImgUrl = def.DEFAULT_IMG 42 | } else { 43 | state.song = state.playList[state.index + 1] 44 | } 45 | } else if (index < state.index) { 46 | state.index-- 47 | } 48 | state.playList.splice(index, 1) 49 | 50 | }, 51 | addToPlayListAsNextPlay (state, item) { 52 | state.playList.splice(state.index + 1, 0, item) 53 | }, 54 | updateCurrentTime (state, time) { 55 | state.currentTime = time 56 | }, 57 | updateDuration (state, time) { 58 | state.duration = time 59 | }, 60 | play (state) { 61 | state.playing = true 62 | }, 63 | pause (state) { 64 | state.playing = false 65 | }, 66 | playFront (state) { 67 | state.index = (state.index - 1 + state.playList.length) % state.playList.length 68 | state.song = state.playList[state.index] 69 | }, 70 | playNext (state) { 71 | state.index = (state.index + 1) % state.playList.length 72 | state.song = state.playList[state.index] 73 | }, 74 | playContinue (state) { 75 | switch (state.playMode) { 76 | case def.SINGLE: 77 | break 78 | case def.SEQUENTIAL: 79 | state.index = (state.index + 1) % state.playList.length 80 | state.song = state.playList[state.index] 81 | break 82 | case def.RANDOM: 83 | state.index = Math.floor(Math.random() * state.playList.length) 84 | state.song = state.playList[state.index] 85 | break 86 | } 87 | }, 88 | changePlayMode (state) { 89 | state.playMode = (state.playMode + 1) % 3 90 | }, 91 | setAlbummid(state,albummid){ 92 | state.song = {...state.song,albummid} 93 | } 94 | }, 95 | getters: { 96 | currentTime: state => 97 | parseInt(state.currentTime / 60) + ':' + (Array(2).join(0) + (state.currentTime % 60)).slice(-2) 98 | , 99 | duration: state => 100 | parseInt(state.duration / 60) + ':' + (Array(2).join(0) + (state.duration % 60)).slice(-2), 101 | coverImgUrl:state => { 102 | if(typeof state.song.albummid === 'undefined') 103 | return def.DEFAULT_IMG 104 | else 105 | return "https://y.gtimg.cn/music/photo_new/T002R500x500M000"+state.song.albummid+".jpg" 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/lib/styles/1px.less: -------------------------------------------------------------------------------- 1 | /** 2 | * https://github.com/frozenui/frozenui/ 3 | * MIT License 4 | */ 5 | 6 | .vux-1px-t { 7 | border-top: 1px solid #e0e0e0; 8 | } 9 | 10 | .vux-1px-b { 11 | border-bottom: 1px solid #e0e0e0; 12 | } 13 | 14 | .vux-1px-tb { 15 | border-top: #e0e0e0 1px solid; 16 | border-bottom: #e0e0e0 1px solid; 17 | background-image: none; 18 | } 19 | 20 | .vux-1px-l { 21 | border-left: 1px solid #e0e0e0; 22 | } 23 | 24 | .vux-1px-r { 25 | border-right: 1px solid #e0e0e0; 26 | } 27 | 28 | .vux-1px { 29 | border: 1px solid #e0e0e0; 30 | } 31 | 32 | .vux-1px-radius { 33 | border: 1px solid #e0e0e0; 34 | border-radius: 4px; 35 | } 36 | 37 | @media screen and (min-device-pixel-ratio: 2) { 38 | .vux-1px-radius { 39 | position: relative; 40 | border: 0; 41 | } 42 | 43 | .vux-1px-radius:before { 44 | content: ""; 45 | width: 200%; 46 | height: 200%; 47 | position: absolute; 48 | top: 0; 49 | left: 0; 50 | border: 1px solid #e0e0e0; 51 | transform: scale(0.5); 52 | transform-origin: 0 0; 53 | padding: 1px; 54 | box-sizing: border-box; 55 | border-radius: 8px; 56 | pointer-events: none; 57 | } 58 | } 59 | 60 | @media screen and (-webkit-min-device-pixel-ratio: 2) { 61 | .vux-1px { 62 | position: relative; 63 | border: 0; 64 | } 65 | 66 | .vux-1px-t, .vux-1px-b, .vux-1px-l, .vux-1px-r, .vux-1px-tb { 67 | border: 0; 68 | } 69 | 70 | .vux-1px-t { 71 | background-position: left top; 72 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)); } 73 | 74 | .vux-1px-b { 75 | background-position: left bottom; 76 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)); } 77 | 78 | .vux-1px-t, 79 | .vux-1px-b, 80 | .vux-1px-tb { 81 | background-repeat: repeat-x; 82 | -webkit-background-size: 100% 1px; 83 | } 84 | 85 | .vux-1px-tb { 86 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)); 87 | background-position: top, bottom; 88 | } 89 | 90 | .vux-1px-l { 91 | background-position: left top; 92 | background-image: -webkit-gradient(linear, right top, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)); } 93 | 94 | .vux-1px-r { 95 | background-position: right top; 96 | background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)); } 97 | 98 | .vux-1px-l, 99 | .vux-1px-r { 100 | background-repeat: repeat-y; 101 | background-size: 1px 100%; 102 | } 103 | 104 | .vux-1px:after { 105 | content: ""; 106 | width: 100%; 107 | height: 100%; 108 | position: absolute; 109 | top: 0; 110 | left: 0; 111 | background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)), -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)), -webkit-gradient(linear, right top, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0)); 112 | background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; 113 | background-repeat: no-repeat; 114 | background-position: top, right, bottom, left; 115 | padding: 1px; 116 | box-sizing: border-box; 117 | z-index: 10; 118 | pointer-events: none; 119 | } 120 | } -------------------------------------------------------------------------------- /src/utils/base64.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/30 0030. 3 | */ 4 | 5 | // //1.加密 6 | // var str = '124中文内容'; 7 | // var base = new Base64(); 8 | // var result = base.encode(str); 9 | // //document.write(result); 10 | // 11 | // //2.解密 12 | // var result2 = base.decode(result); 13 | // document.write(result2); 14 | const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" 15 | 16 | // private method for UTF-8 encoding 17 | function _utf8_encode(string) { 18 | string = string.replace(/\r\n/g, "\n"); 19 | var utftext = ""; 20 | for (var n = 0; n < string.length; n++) { 21 | var c = string.charCodeAt(n); 22 | if (c < 128) { 23 | utftext += String.fromCharCode(c); 24 | } else if ((c > 127) && (c < 2048)) { 25 | utftext += String.fromCharCode((c >> 6) | 192); 26 | utftext += String.fromCharCode((c & 63) | 128); 27 | } else { 28 | utftext += String.fromCharCode((c >> 12) | 224); 29 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 30 | utftext += String.fromCharCode((c & 63) | 128); 31 | } 32 | 33 | } 34 | return utftext; 35 | } 36 | 37 | function _utf8_decode(utftext) { 38 | var string = ""; 39 | var i = 0; 40 | var c = 0; 41 | var c3 = 0; 42 | var c2 = 0; 43 | while (i < utftext.length) { 44 | c = utftext.charCodeAt(i); 45 | if (c < 128) { 46 | string += String.fromCharCode(c); 47 | i++; 48 | } else if ((c > 191) && (c < 224)) { 49 | c2 = utftext.charCodeAt(i + 1); 50 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 51 | i += 2; 52 | } else { 53 | c2 = utftext.charCodeAt(i + 1); 54 | c3 = utftext.charCodeAt(i + 2); 55 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 56 | i += 3; 57 | } 58 | } 59 | return string; 60 | } 61 | 62 | export default { 63 | // public method for encoding 64 | encode: function (input) { 65 | var output = ""; 66 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 67 | var i = 0; 68 | input = _utf8_encode(input); 69 | while (i < input.length) { 70 | chr1 = input.charCodeAt(i++); 71 | chr2 = input.charCodeAt(i++); 72 | chr3 = input.charCodeAt(i++); 73 | enc1 = chr1 >> 2; 74 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 75 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 76 | enc4 = chr3 & 63; 77 | if (isNaN(chr2)) { 78 | enc3 = enc4 = 64; 79 | } else if (isNaN(chr3)) { 80 | enc4 = 64; 81 | } 82 | output = output + 83 | _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + 84 | _keyStr.charAt(enc3) + _keyStr.charAt(enc4); 85 | } 86 | return output; 87 | }, 88 | 89 | // public method for decoding 90 | decode: function (input) { 91 | var output = ""; 92 | var chr1, chr2, chr3; 93 | var enc1, enc2, enc3, enc4; 94 | var i = 0; 95 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 96 | while (i < input.length) { 97 | enc1 = _keyStr.indexOf(input.charAt(i++)); 98 | enc2 = _keyStr.indexOf(input.charAt(i++)); 99 | enc3 = _keyStr.indexOf(input.charAt(i++)); 100 | enc4 = _keyStr.indexOf(input.charAt(i++)); 101 | chr1 = (enc1 << 2) | (enc2 >> 4); 102 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 103 | chr3 = ((enc3 & 3) << 6) | enc4; 104 | output = output + String.fromCharCode(chr1); 105 | if (enc3 != 64) { 106 | output = output + String.fromCharCode(chr2); 107 | } 108 | if (enc4 != 64) { 109 | output = output + String.fromCharCode(chr3); 110 | } 111 | } 112 | output = _utf8_decode(output); 113 | return output; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/lib/styles/weui/base/mixin/setArrow.less: -------------------------------------------------------------------------------- 1 | // css2 arrow 2 | .arrow(@borderWidth, @borderColor) { 3 | .setArrowWidth(@borderWidth); 4 | .setArrowColor(@borderColor); 5 | } 6 | 7 | .setArrowColor(@borderColor) { 8 | &.arrow_t { 9 | border-bottom-color: @borderColor; 10 | } 11 | &.arrow_r { 12 | border-left-color: @borderColor; 13 | } 14 | &.arrow_b { 15 | border-top-color: @borderColor; 16 | } 17 | &.arrow_l { 18 | border-right-color: @borderColor; 19 | } 20 | } 21 | 22 | .setArrowWidth(@borderWidth) { 23 | border-width: @borderWidth; 24 | } 25 | 26 | .setArrow(@direction, @borderWidth, @borderColor) when (@direction = top) { 27 | display: inline-block; 28 | width: 0; 29 | height: 0; 30 | border-width: @borderWidth; 31 | border-style: dashed; 32 | border-color: transparent; 33 | 34 | .arrow_t(@borderColor); 35 | } 36 | 37 | .setArrow(@direction, @borderWidth, @borderColor) when (@direction = right) { 38 | display: inline-block; 39 | width: 0; 40 | height: 0; 41 | border-width: @borderWidth; 42 | border-style: dashed; 43 | border-color: transparent; 44 | .arrow_r(@borderColor); 45 | } 46 | 47 | .setArrow(@direction, @borderWidth, @borderColor) when (@direction = bottom) { 48 | display: inline-block; 49 | width: 0; 50 | height: 0; 51 | border-width: @borderWidth; 52 | border-style: dashed; 53 | border-color: transparent; 54 | .arrow_b(@borderColor); 55 | } 56 | 57 | .setArrow(@direction, @borderWidth, @borderColor) when (@direction = left) { 58 | display: inline-block; 59 | width: 0; 60 | height: 0; 61 | border-width: @borderWidth; 62 | border-style: dashed; 63 | border-color: transparent; 64 | .arrow_l(@borderColor); 65 | } 66 | 67 | .arrow_t(@c) { 68 | border-top-width: 0; 69 | border-bottom-color: @c; 70 | border-bottom-style: solid; 71 | } 72 | 73 | .arrow_r(@c) { 74 | border-right-width: 0; 75 | border-left-color: @c; 76 | border-left-style: solid; 77 | } 78 | 79 | .arrow_b(@c) { 80 | border-bottom-width: 0; 81 | border-top-color: @c; 82 | border-top-style: solid; 83 | } 84 | 85 | .arrow_l(@c) { 86 | border-left-width: 0; 87 | border-right-color: @c; 88 | border-right-style: solid; 89 | } 90 | 91 | // css3 arrow 92 | .setArrowWidth_Wap(@borderWidth) { 93 | border-width: @borderWidth @borderWidth 0 0; 94 | } 95 | 96 | .setArrowSize_Wap(@arrowsize) { 97 | height: @arrowsize; 98 | width: @arrowsize; 99 | } 100 | 101 | .setArrow_Wap(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = top) { 102 | display: inline-block; 103 | .transform(translate(0, 0) rotate(-45deg)); 104 | .setArrowSize_Wap(@arrowsize); 105 | .setArrowWidth_Wap(@borderWidth); 106 | border-color: @borderColor; 107 | border-style: solid; 108 | } 109 | 110 | .setArrow_Wap(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = right) { 111 | display: inline-block; 112 | transform: rotate(45deg); 113 | .setArrowSize_Wap(@arrowsize); 114 | .setArrowWidth_Wap(@borderWidth); 115 | border-color: @borderColor; 116 | border-style: solid; 117 | position: relative; 118 | top: -2px; 119 | } 120 | 121 | .setArrow_Wap(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = down) { 122 | display: inline-block; 123 | transform: rotate(135deg); 124 | .setArrowSize_Wap(@arrowsize); 125 | .setArrowWidth_Wap(@borderWidth); 126 | border-color: @borderColor; 127 | border-style: solid; 128 | 129 | position: relative; 130 | top: -3px; 131 | } 132 | 133 | .setArrow_Wap(@direction, @arrowsize, @borderColor,@borderWidth) when (@direction = left) { 134 | display: inline-block; 135 | transform: rotate(-135deg); 136 | .setArrowSize_Wap(@arrowsize); 137 | .setArrowWidth_Wap(@borderWidth); 138 | border-color: @borderColor; 139 | border-style: solid; 140 | 141 | position: relative; 142 | top: -2px; 143 | } -------------------------------------------------------------------------------- /src/lib/components/index.js: -------------------------------------------------------------------------------- 1 | /* only for building vux.css */ 2 | import Style from '../styles/index.vue' // eslint-disable-line 3 | 4 | import Radio from './radio' 5 | import DevTip from './dev-tip' 6 | import XInput from './x-input' 7 | import XNumber from './x-number' 8 | import Cell from './cell' 9 | import InlineDesc from './inline-desc' 10 | import Checklist from './checklist' 11 | import Switch from './switch' 12 | import XTextarea from './x-textarea' 13 | import Group from './group' 14 | import GroupTitle from './group-title' 15 | import Box from './box' 16 | import Tip from './tip' 17 | import Selector from './selector' 18 | import XButton from './x-button' 19 | import Swiper from './swiper' 20 | import SwiperItem from './swiper-item' 21 | import Sticky from './sticky' 22 | import Picker from './picker' 23 | import Datetime from './datetime' 24 | import Popup from './popup' 25 | import Range from './range' 26 | import Actionsheet from './actionsheet' 27 | import Clocker from './clocker' 28 | import Rater from './rater' 29 | import PopupPicker from './popup-picker' 30 | import Address from './address' 31 | import Toast from './toast' 32 | import Loading from './loading' 33 | import Alert from './alert' 34 | import Confirm from './confirm' 35 | import Progress from './progress' 36 | import XImg from './x-img' 37 | import Spinner from './spinner' 38 | import Calendar from './calendar' 39 | import Icon from './icon' 40 | import Circle from './circle' 41 | import ColorPicker from './color-picker' 42 | import AddressChinaData from './address/list.json' 43 | import Divider from './divider' 44 | import Blur from './blur' 45 | import Countup from './countup' 46 | import Scroller from './scroller' 47 | import Shake from './shake' 48 | import WechatEmotion from './wechat-emotion' 49 | import Search from './search' 50 | import DateFormatter from './datetime/format' 51 | import Masker from './masker' 52 | import Countdown from './countdown' 53 | import FriendlyTime from '../filters/friendly-time' 54 | import XHeader from './x-header' 55 | import Panel from './panel' 56 | import InlineCalendar from './inline-calendar' 57 | import Badge from './badge' 58 | import Dialog from './dialog' 59 | import Card from './card' 60 | import Previewer from './previewer' 61 | import NumberRoller from './number-roller' 62 | import ViewBox from './view-box' 63 | import Popover from './popover' 64 | 65 | import { ButtonTab, ButtonTabItem } from './button-tab' 66 | import { Checker, CheckerItem } from './checker' 67 | import { Flexbox, FlexboxItem } from './flexbox' 68 | import { Step, StepItem } from './step' 69 | import { Timeline, TimelineItem } from './timeline' 70 | import { Tabbar, TabbarItem } from './tabbar' 71 | import { Tab, TabItem } from './tab' 72 | 73 | const vux = { 74 | Radio, 75 | Group, 76 | DevTip, 77 | XInput, 78 | GroupTitle, 79 | XNumber, 80 | Checklist, 81 | Switch, 82 | Box, 83 | Tip, 84 | Selector, 85 | Cell, 86 | InlineDesc, 87 | XButton, 88 | XTextarea, 89 | Flexbox, 90 | FlexboxItem, 91 | Tab, 92 | TabItem, 93 | Swiper, 94 | SwiperItem, 95 | Sticky, 96 | Picker, 97 | Datetime, 98 | Popup, 99 | Range, 100 | Actionsheet, 101 | Clocker, 102 | Rater, 103 | PopupPicker, 104 | Address, 105 | Toast, 106 | Loading, 107 | Alert, 108 | Confirm, 109 | Progress, 110 | XImg, 111 | Spinner, 112 | Calendar, 113 | Icon, 114 | Circle, 115 | ColorPicker, 116 | AddressChinaData, 117 | Divider, 118 | Blur, 119 | Countup, 120 | Scroller, 121 | Shake, 122 | WechatEmotion, 123 | Search, 124 | DateFormatter, 125 | Masker, 126 | Countdown, 127 | FriendlyTime, 128 | XHeader, 129 | Checker, 130 | CheckerItem, 131 | Timeline, 132 | TimelineItem, 133 | Step, 134 | StepItem, 135 | Tabbar, 136 | TabbarItem, 137 | Panel, 138 | ButtonTab, 139 | ButtonTabItem, 140 | InlineCalendar, 141 | Badge, 142 | Dialog, 143 | Card, 144 | Previewer, 145 | NumberRoller, 146 | ViewBox, 147 | Popover 148 | } 149 | 150 | if (DEV) { // eslint-disable-line 151 | const { getMetas } = require('../../build/build-metas') 152 | const metas = getMetas(vux) 153 | if (window.fetch) { 154 | window.fetch(`http://${window.location.hostname}:8899/api/doc`, { 155 | method: 'POST', 156 | body: JSON.stringify(metas), 157 | headers: { 158 | 'Accept': 'application/json', 159 | 'Content-Type': 'application/json' 160 | } 161 | }) 162 | } 163 | } 164 | 165 | module.exports = vux 166 | -------------------------------------------------------------------------------- /src/config/api.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sioxa on 2016/12/25 0025. 3 | */ 4 | export default { 5 | rank_songs: { 6 | url: 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg', 7 | params: (id) => { 8 | return { 9 | g_tk: 5381, 10 | uin: 0, 11 | format: 'json', 12 | inCharset: 'utf-8', 13 | outCharset: 'utf-8', 14 | notice: 0, 15 | platform: 'h5', 16 | needNewCode: 1, 17 | tpl: 3, 18 | page: 'detail', 19 | type: 'top', 20 | topid: id, 21 | _: new Date().getTime() 22 | } 23 | }, 24 | jsonp: 'jsonpCallback' 25 | }, 26 | rank_list: { 27 | url: 'https://c.y.qq.com/v8/fcg-bin/fcg_myqq_toplist.fcg', 28 | params: () => { 29 | return { 30 | format: 'jsonp', 31 | g_tk: 5381, 32 | uin: 0, 33 | inCharset: 'utf-8', 34 | outCharset: 'utf-8', 35 | notice: 0, 36 | platform: 'h5', 37 | needNewCode: 1, 38 | _: new Date().getTime() 39 | } 40 | }, 41 | jsonp: 'jsonpCallback' 42 | }, 43 | album: { 44 | url: 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_album_info_cp.fcg', 45 | params: (id) => { 46 | return { 47 | albummid: id, 48 | g_tk: 5381, 49 | loginUin: 0, 50 | hostUin: 0, 51 | format: 'jsonp', 52 | inCharset: 'utf8', 53 | outCharset: 'utf-8', 54 | notice: 0, 55 | platform: 'yqq', 56 | needNewCode: 0 57 | } 58 | }, 59 | jsonp: 'jsonpCallback' 60 | }, 61 | singer_info: { 62 | url: 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg', 63 | params: (id) => { 64 | return { 65 | order: 'listen', 66 | begin: 0, 67 | num: 8, 68 | singermid: id, 69 | g_tk: 5381, 70 | uin: 0, 71 | format: 'jsonp', 72 | inCharset: 'utf-8', 73 | outCharset: 'utf-8', 74 | notice: 0, 75 | platform: 'h5page', 76 | needNewCode: 1, 77 | from: 'h5', 78 | _: new Date().getTime() 79 | } 80 | }, 81 | jsonp: 'jsonpCallback' 82 | }, 83 | search: { 84 | url: 'https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg', 85 | params: (key) => { 86 | return { 87 | is_xml: 0, 88 | format: 'jsonp', 89 | key: key, 90 | g_tk: 5381, 91 | loginUin: 0, 92 | hostUin: 0, 93 | inCharset: 'utf8', 94 | outCharset: 'utf-8', 95 | notice: 0, 96 | platform: 'yqq', 97 | needNewCode: 0 98 | } 99 | }, 100 | jsonp: 'jsonpCallback' 101 | }, 102 | hotkey: { 103 | url: 'https://c.y.qq.com/splcloud/fcgi-bin/gethotkey.fcg', 104 | params: () => { 105 | return { 106 | g_tk: 5381, 107 | loginUin: 0, 108 | hostUin: 0, 109 | format: 'jsonp', 110 | inCharset: 'utf8', 111 | outCharset: 'utf-8', 112 | notice: 0, 113 | platform: 'yqq', 114 | needNewCode: 0 115 | } 116 | }, 117 | jsonp: 'jsonpCallback' 118 | }, 119 | home_page_data: { 120 | url: 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg', 121 | params: () => { 122 | return { 123 | g_tk: 5381, 124 | uin: 0, 125 | format: 'jsonp', 126 | inCharset: 'utf-8', 127 | outCharset: 'utf-8', 128 | notice: 0, 129 | platform: 'h5', 130 | needNewCode: 1, 131 | _: new Date().getTime() 132 | } 133 | }, 134 | jsonp: 'jsonpCallback' 135 | }, 136 | lyric: { 137 | url: 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg', 138 | params: (id) => { 139 | return { 140 | nobase64:1, 141 | musicid:id, 142 | songtype:0 143 | } 144 | }, 145 | jsonp:'callback' 146 | }, 147 | cd:{ 148 | url:'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg', 149 | params:(id)=>{ 150 | return { 151 | g_tk:5381, 152 | uin:0, 153 | format:'jsonp', 154 | inCharset:'utf-8', 155 | outCharset:'utf-8', 156 | notice:0, 157 | platform:'h5', 158 | needNewCode:1, 159 | new_format:1, 160 | pic:500, 161 | disstid:id, 162 | type:1, 163 | json:1, 164 | utf8:1, 165 | onlysong:0, 166 | nosign:1, 167 | _:new Date().getTime() 168 | } 169 | }, 170 | jsonp: 'jsonpCallback' 171 | }, 172 | first_page_data:{ 173 | url:"https://c.y.qq.com/v8/fcg-bin/fcg_first_yqq.fcg", 174 | params(){ 175 | return{ 176 | format:'jsonp', 177 | tpl:'v12', 178 | page:'other', 179 | rnd:0, 180 | g_tk:new Date().getTime(), 181 | loginUin:0, 182 | hostUin:0, 183 | inCharset:'utf8', 184 | outCharset:'GB2312', 185 | notice:0, 186 | platform:'yqq', 187 | needNewCode:0 188 | } 189 | }, 190 | jsonp: 'jsonpCallback' 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/components/PlayingList.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 100 | 101 | 102 | 209 | -------------------------------------------------------------------------------- /src/lib/styles/weui/widget/weui_tips/weui_toast.less: -------------------------------------------------------------------------------- 1 | @import "../../base/fn"; 2 | 3 | .weui_toast { 4 | position: fixed; 5 | z-index: 50000; 6 | width: 7.6em; 7 | min-height: 7.6em; 8 | top: 180px; 9 | left: 50%; 10 | margin-left: -3.8em; 11 | background: rgba(40, 40, 40, 0.75); 12 | text-align: center; 13 | border-radius: 5px; 14 | color: #FFFFFF; 15 | } 16 | .weui_icon_toast { 17 | margin: 22px 0 0; 18 | display: block; 19 | &:before { 20 | content: '\EA08'; 21 | color: #FFFFFF; 22 | font-size: 55px; 23 | } 24 | } 25 | .weui_toast_content { 26 | margin: 0 0 15px; 27 | } 28 | 29 | // loading toast 30 | .weui_loading_toast{ 31 | .weui_toast_content{ 32 | margin-top:64%; 33 | font-size:14px; 34 | } 35 | } 36 | .weui_loading{ 37 | position: absolute; 38 | width: 0px; 39 | z-index: 1; 40 | left: 50%; 41 | top: 38%; 42 | } 43 | .weui_loading_leaf{ 44 | position: absolute; 45 | top: -1px; 46 | opacity: 0.25; 47 | &:before{ 48 | content:" "; 49 | position: absolute; 50 | width: 8.14px; 51 | height: 3.08px; 52 | background: rgb(209, 209, 213); 53 | box-shadow: rgba(0, 0, 0, 0.0980392) 0px 0px 1px; 54 | border-radius: 1px; 55 | transform-origin: left 50% 0px; 56 | } 57 | &_0{ 58 | animation: opacity-60-25-0-12 1.25s linear infinite; 59 | &:before{ 60 | transform: rotate(0deg) translate(7.92px, 0px); 61 | } 62 | } 63 | &_1{ 64 | animation: opacity-60-25-1-12 1.25s linear infinite; 65 | &:before{ 66 | transform: rotate(30deg) translate(7.92px, 0px); 67 | } 68 | } 69 | &_2{ 70 | animation: opacity-60-25-2-12 1.25s linear infinite; 71 | &:before{ 72 | transform: rotate(60deg) translate(7.92px, 0px); 73 | } 74 | } 75 | &_3{ 76 | animation: opacity-60-25-3-12 1.25s linear infinite; 77 | &:before{ 78 | transform: rotate(90deg) translate(7.92px, 0px); 79 | } 80 | } 81 | &_4{ 82 | animation: opacity-60-25-4-12 1.25s linear infinite; 83 | &:before{ 84 | transform: rotate(120deg) translate(7.92px, 0px); 85 | } 86 | } 87 | &_5{ 88 | animation: opacity-60-25-5-12 1.25s linear infinite; 89 | &:before{ 90 | transform: rotate(150deg) translate(7.92px, 0px); 91 | } 92 | } 93 | &_6{ 94 | animation: opacity-60-25-6-12 1.25s linear infinite; 95 | &:before{ 96 | transform: rotate(180deg) translate(7.92px, 0px); 97 | } 98 | } 99 | &_7{ 100 | animation: opacity-60-25-7-12 1.25s linear infinite; 101 | &:before{ 102 | transform: rotate(210deg) translate(7.92px, 0px); 103 | } 104 | } 105 | &_8{ 106 | animation: opacity-60-25-8-12 1.25s linear infinite; 107 | &:before{ 108 | transform: rotate(240deg) translate(7.92px, 0px); 109 | } 110 | } 111 | &_9{ 112 | animation: opacity-60-25-9-12 1.25s linear infinite; 113 | &:before{ 114 | transform: rotate(270deg) translate(7.92px, 0px); 115 | } 116 | } 117 | &_10{ 118 | animation: opacity-60-25-10-12 1.25s linear infinite; 119 | &:before{ 120 | transform: rotate(300deg) translate(7.92px, 0px); 121 | } 122 | } 123 | &_11{ 124 | animation: opacity-60-25-11-12 1.25s linear infinite; 125 | &:before{ 126 | transform: rotate(330deg) translate(7.92px, 0px); 127 | } 128 | } 129 | } 130 | @-webkit-keyframes opacity-60-25-0-12 { 131 | 0% { opacity: 0.25; } 132 | 0.01% { opacity: 0.25; } 133 | 0.02% { opacity: 1; } 134 | 60.01% { opacity: 0.25; } 135 | 100% { opacity: 0.25; } 136 | }@-webkit-keyframes opacity-60-25-1-12 { 137 | 0% { opacity: 0.25; } 138 | 8.34333% { opacity: 0.25; } 139 | 8.35333% { opacity: 1; } 140 | 68.3433% { opacity: 0.25; } 141 | 100% { opacity: 0.25; } 142 | }@-webkit-keyframes opacity-60-25-2-12 { 143 | 0% { opacity: 0.25; } 144 | 16.6767% { opacity: 0.25; } 145 | 16.6867% { opacity: 1; } 146 | 76.6767% { opacity: 0.25; } 147 | 100% { opacity: 0.25; } 148 | }@-webkit-keyframes opacity-60-25-3-12 { 149 | 0% { opacity: 0.25; } 150 | 25.01% { opacity: 0.25; } 151 | 25.02% { opacity: 1; } 152 | 85.01% { opacity: 0.25; } 153 | 100% { opacity: 0.25; } 154 | }@-webkit-keyframes opacity-60-25-4-12 { 155 | 0% { opacity: 0.25; } 156 | 33.3433% { opacity: 0.25; } 157 | 33.3533% { opacity: 1; } 158 | 93.3433% { opacity: 0.25; } 159 | 100% { opacity: 0.25; } 160 | }@-webkit-keyframes opacity-60-25-5-12 { 161 | 0% { opacity: 0.270958333333333; } 162 | 41.6767% { opacity: 0.25; } 163 | 41.6867% { opacity: 1; } 164 | 1.67667% { opacity: 0.25; } 165 | 100% { opacity: 0.270958333333333; } 166 | }@-webkit-keyframes opacity-60-25-6-12 { 167 | 0% { opacity: 0.375125; } 168 | 50.01% { opacity: 0.25; } 169 | 50.02% { opacity: 1; } 170 | 10.01% { opacity: 0.25; } 171 | 100% { opacity: 0.375125; } 172 | }@-webkit-keyframes opacity-60-25-7-12 { 173 | 0% { opacity: 0.479291666666667; } 174 | 58.3433% { opacity: 0.25; } 175 | 58.3533% { opacity: 1; } 176 | 18.3433% { opacity: 0.25; } 177 | 100% { opacity: 0.479291666666667; } 178 | }@-webkit-keyframes opacity-60-25-8-12 { 179 | 0% { opacity: 0.583458333333333; } 180 | 66.6767% { opacity: 0.25; } 181 | 66.6867% { opacity: 1; } 182 | 26.6767% { opacity: 0.25; } 183 | 100% { opacity: 0.583458333333333; } 184 | }@-webkit-keyframes opacity-60-25-9-12 { 185 | 0% { opacity: 0.687625; } 186 | 75.01% { opacity: 0.25; } 187 | 75.02% { opacity: 1; } 188 | 35.01% { opacity: 0.25; } 189 | 100% { opacity: 0.687625; } 190 | }@-webkit-keyframes opacity-60-25-10-12 { 191 | 0% { opacity: 0.791791666666667; } 192 | 83.3433% { opacity: 0.25; } 193 | 83.3533% { opacity: 1; } 194 | 43.3433% { opacity: 0.25; } 195 | 100% { opacity: 0.791791666666667; } 196 | }@-webkit-keyframes opacity-60-25-11-12 { 197 | 0% { opacity: 0.895958333333333; } 198 | 91.6767% { opacity: 0.25; } 199 | 91.6867% { opacity: 1; } 200 | 51.6767% { opacity: 0.25; } 201 | 100% { opacity: 0.895958333333333; } 202 | } 203 | -------------------------------------------------------------------------------- /src/lib/libs/eventor.js: -------------------------------------------------------------------------------- 1 | // Events 2 | // ----------------- 3 | // Thanks to: 4 | // - https://github.com/documentcloud/backbone/blob/master/backbone.js 5 | // - https://github.com/joyent/node/blob/master/lib/events.js 6 | 7 | // Regular expression used to split event strings 8 | var eventSplitter = /\s+/ 9 | 10 | // A module that can be mixed in to *any object* in order to provide it 11 | // with custom events. You may bind with `on` or remove with `off` callback 12 | // functions to an event; `trigger`-ing an event fires all callbacks in 13 | // succession. 14 | // 15 | // var object = new Events(); 16 | // object.on('expand', function(){ alert('expanded'); }); 17 | // object.trigger('expand'); 18 | // 19 | function Events () { 20 | } 21 | 22 | // Bind one or more space separated events, `events`, to a `callback` 23 | // function. Passing `"all"` will bind the callback to all events fired. 24 | Events.prototype.on = function (events, callback, context) { 25 | var cache, event, list 26 | if (!callback) return this 27 | 28 | cache = this.__events || (this.__events = {}) 29 | events = events.split(eventSplitter) 30 | while (event = events.shift()) { // eslint-disable-line 31 | list = cache[event] || (cache[event] = []) 32 | list.push(callback, context) 33 | } 34 | 35 | return this 36 | } 37 | 38 | Events.prototype.once = function (events, callback, context) { 39 | var that = this 40 | var cb = function () { 41 | that.off(events, cb) 42 | callback.apply(context || that, arguments) 43 | } 44 | return this.on(events, cb, context) 45 | } 46 | 47 | // Remove one or many callbacks. If `context` is null, removes all callbacks 48 | // with that function. If `callback` is null, removes all callbacks for the 49 | // event. If `events` is null, removes all bound callbacks for all events. 50 | Events.prototype.off = function (events, callback, context) { 51 | var cache, event, list, i 52 | 53 | // No events, or removing *all* events. 54 | if (!(cache = this.__events)) return this 55 | if (!(events || callback || context)) { 56 | delete this.__events 57 | return this 58 | } 59 | 60 | events = events ? events.split(eventSplitter) : keys(cache) 61 | 62 | // Loop through the callback list, splicing where appropriate. 63 | while (event = events.shift()) { // eslint-disable-line 64 | list = cache[event] 65 | if (!list) continue 66 | 67 | if (!(callback || context)) { 68 | delete cache[event] 69 | continue 70 | } 71 | 72 | for (i = list.length - 2; i >= 0; i -= 2) { 73 | if (!(callback && list[i] !== callback || 74 | context && list[i + 1] !== context)) { 75 | list.splice(i, 2) 76 | } 77 | } 78 | } 79 | 80 | return this 81 | } 82 | 83 | // Trigger one or many events, firing all bound callbacks. Callbacks are 84 | // passed the same arguments as `trigger` is, apart from the event name 85 | // (unless you're listening on `"all"`, which will cause your callback to 86 | // receive the true name of the event as the first argument). 87 | Events.prototype.trigger = function (events) { 88 | var cache, event, all, list, i, len 89 | var rest = [] 90 | var returned = true 91 | if (!(cache = this.__events)) return this 92 | 93 | events = events.split(eventSplitter) 94 | 95 | // Fill up `rest` with the callback arguments. Since we're only copying 96 | // the tail of `arguments`, a loop is much faster than Array#slice. 97 | for (i = 1, len = arguments.length; i < len; i++) { 98 | rest[i - 1] = arguments[i] 99 | } 100 | 101 | // For each event, walk through the list of callbacks twice, first to 102 | // trigger the event, then to trigger any `"all"` callbacks. 103 | while (event = events.shift()) { // eslint-disable-line 104 | // Copy callback lists to prevent modification. 105 | if (all = cache.all) all = all.slice() // eslint-disable-line 106 | if (list = cache[event]) list = list.slice() // eslint-disable-line 107 | 108 | // Execute event callbacks except one named "all" 109 | if (event !== 'all') { 110 | returned = triggerEvents(list, rest, this) && returned 111 | } 112 | 113 | // Execute "all" callbacks. 114 | returned = triggerEvents(all, [event].concat(rest), this) && returned 115 | } 116 | 117 | return returned 118 | } 119 | 120 | Events.prototype.emit = Events.prototype.trigger 121 | 122 | // Helpers 123 | // ------- 124 | 125 | var keys = Object.keys 126 | 127 | if (!keys) { 128 | keys = function (o) { 129 | var result = [] 130 | 131 | for (var name in o) { 132 | if (o.hasOwnProperty(name)) { 133 | result.push(name) 134 | } 135 | } 136 | return result 137 | } 138 | } 139 | 140 | // Mix `Events` to object instance or Class function. 141 | Events.mixTo = function (receiver) { 142 | var proto = Events.prototype 143 | 144 | if (isFunction(receiver)) { 145 | for (let key in proto) { 146 | if (proto.hasOwnProperty(key)) { 147 | receiver.prototype[key] = proto[key] 148 | } 149 | } 150 | } else { 151 | var event = new Events() 152 | for (let key in proto) { 153 | if (proto.hasOwnProperty(key)) { 154 | copyProto(key) 155 | } 156 | } 157 | } 158 | 159 | function copyProto (key) { 160 | receiver[key] = function () { 161 | proto[key].apply(event, Array.prototype.slice.call(arguments)) 162 | return this 163 | } 164 | } 165 | } 166 | 167 | // Execute callbacks 168 | function triggerEvents (list, args, context) { 169 | var pass = true 170 | 171 | if (list) { 172 | var i = 0 173 | var l = list.length 174 | var a1 = args[0] 175 | var a2 = args[1] 176 | var a3 = args[2] 177 | // call is faster than apply, optimize less than 3 argu 178 | // http://blog.csdn.net/zhengyinhui100/article/details/7837127 179 | switch (args.length) { 180 | case 0: for (; i < l; i += 2) {pass = list[i].call(list[i + 1] || context) !== false && pass} break 181 | case 1: for (; i < l; i += 2) {pass = list[i].call(list[i + 1] || context, a1) !== false && pass} break 182 | case 2: for (; i < l; i += 2) {pass = list[i].call(list[i + 1] || context, a1, a2) !== false && pass} break 183 | case 3: for (; i < l; i += 2) {pass = list[i].call(list[i + 1] || context, a1, a2, a3) !== false && pass} break 184 | default: for (; i < l; i += 2) {pass = list[i].apply(list[i + 1] || context, args) !== false && pass} break 185 | } 186 | } 187 | // trigger will return false if one of the callbacks return false 188 | return pass 189 | } 190 | 191 | function isFunction (func) { 192 | return Object.prototype.toString.call(func) === '[object Function]' 193 | } 194 | 195 | module.exports = Events 196 | -------------------------------------------------------------------------------- /src/lib/styles/weui/icon/weui_font.less: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-weight: normal; 3 | font-style: normal; 4 | font-family: "weui"; 5 | src: url('data:application/octet-stream;base64,AAEAAAALAIAAAwAwR1NVQrD+s+0AAAE4AAAAQk9TLzJAKEx1AAABfAAAAFZjbWFw64JcfgAAAhQAAAI0Z2x5ZvCBJt8AAARsAAAHLGhlYWQIuM5WAAAA4AAAADZoaGVhCC0D+AAAALwAAAAkaG10eDqYAAAAAAHUAAAAQGxvY2EO3AzsAAAESAAAACJtYXhwAR4APgAAARgAAAAgbmFtZeNcHtgAAAuYAAAB5nBvc3RP98ExAAANgAAAANYAAQAAA+gAAABaA+gAAP//A+kAAQAAAAAAAAAAAAAAAAAAABAAAQAAAAEAAKZXmK1fDzz1AAsD6AAAAADS2MTEAAAAANLYxMQAAAAAA+kD6QAAAAgAAgAAAAAAAAABAAAAEAAyAAQAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKAB4ALAABREZMVAAIAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAAAAQOqAZAABQAIAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA6gHqDwPoAAAAWgPpAAAAAAABAAAAAAAAAAAAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAAAAAUAAAADAAAALAAAAAQAAAFwAAEAAAAAAGoAAwABAAAALAADAAoAAAFwAAQAPgAAAAQABAABAADqD///AADqAf//AAAAAQAEAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAMQAAAAAAAAADwAA6gEAAOoBAAAAAQAA6gIAAOoCAAAAAgAA6gMAAOoDAAAAAwAA6gQAAOoEAAAABAAA6gUAAOoFAAAABQAA6gYAAOoGAAAABgAA6gcAAOoHAAAABwAA6ggAAOoIAAAACAAA6gkAAOoJAAAACQAA6goAAOoKAAAACgAA6gsAAOoLAAAACwAA6gwAAOoMAAAADAAA6g0AAOoNAAAADQAA6g4AAOoOAAAADgAA6g8AAOoPAAAADwAAAAAALgBmAKIA3gEaAV4BtgHkAgoCRgKIAtIDFANOA5YAAAACAAAAAAOvA60ACwAXAAABDgEHHgEXPgE3LgEDLgEnPgE3HgEXDgEB9bz5BQX5vLv5BQX5u6zjBQXjrKvjBQXjA60F+by7+gQE+ru8+fy0BOSrq+QEBOSrq+QAAAIAAAAAA7MDswALACEAAAEOAQceARc+ATcuAQMHBiIvASY2OwERNDY7ATIWFREzMhYB7rn7BQX7ucL+BQX+JHYPJg92DgwYXQsHJggKXRgMA7MF/sK5+wUF+7nC/v31mhISmhIaARcICwsI/ukaAAADAAAAAAOtA6sACwAZACIAAAEOAQceARc+ATcuAQMUBisBIiY1ETY3MxYXJy4BNDYyFhQGAfC49gUF9ri++gUF+poKBxwHCgEILAgBHxMZGSYZGQOrBfq+uPYFBfa4vvr9dQcKCgcBGggBAQg5ARklGRklGQAAAAACAAAAAAOSA8IADQAfAAABDgEHERYEFzYkNxEuARMBBi8BJj8BNh8BFjclNh8BFgH0gchUCQEDkZEBAwlUyHr+vwQDlAMCFQMDegMEAScEAxMDA8IePRz+w9TwJCTw1AE9HD3+3f7DAgOZBAMcBANdAgL2AwMTBAADAAAAAAOCA7AADQAZACIAAAEOAQcRHgEXPgE3ES4BBzMWFQcGByMmLwE0EyImNDYyFhQGAfV7wVEJ+YuL+QlRwZIuCQoBBCIEAQogDhISHBISA7AdOxr+z8vnIyPnywExGjv3AQjYBAEBBNgI/rETHBISHBMAAAACAAAAAAO9A70AFwAjAAABLgE/AT4BHwEWMjclNhYXJxYUBwEGJiclJgAnBgAHFgAXNgABIAUCBQMFEAdiBxIGARMHEQYCBgb+0AYQBgIcBf79x77/AAUFAQC+xwEDAccGEQcEBwIFTAQF5QYBBgIGEAb+1QYBBqzHAQMFBf79x77/AAUFAQAABAAAAAADrwOtAAsAFwAtADEAAAEOAQceARc+ATcuAQMuASc+ATceARcOARMFDgEvASYGDwEGFh8BFjI3AT4BJiIXFjEXAfW8+QUF+by7+QUF+bus4wUF46yr4wUF4yv+9gcRBmAGDwUDBQEGfQUQBgElBQELDxQBAQOtBfm8u/oEBPq7vPn8tATkq6vkBATkq6vkAiLdBQEFSQUCBgQHEQaABgUBIQUPCwQBAQAAAAABAAAAAAO7AzoAFwAAEy4BPwE+AR8BFjY3ATYWFycWFAcBBiInPQoGBwUIGQzLDSALAh0MHgsNCgr9uQscCwGzCyEOCw0HCZMJAQoBvgkCCg0LHQv9sQsKAAAAAAIAAAAAA7gDuAALABEAAAEGAgceARc2JDcmABMhETMRMwHuvP0FBf28xQEABQX/ADr+2i35A7gF/wDFvP0FBf28xQEA/d4BTv7fAAAEAAAAAAOvA60AAwAPABsAIQAAARYxFwMOAQceARc+ATcuAQMuASc+ATceARcOAQMjFTM1IwLlAQHyvPkFBfm8u/kFBfm7rOMFBeOsq+MFBePZJP3ZAoMBAQEsBfm8u/oEBPq7vPn8tATkq6vkBATkq6vkAi39JAADAAAAAAPDA8MACwAbACQAAAEGAAcWABc2ADcmAAczMhYVAw4BKwEiJicDNDYTIiY0NjIWFAYB7sD+/AUFAQTAyQEHBQX++d42CAoOAQUEKgQFAQ4KIxMaGiYaGgPDBf75ycD+/AUFAQTAyQEH5woI/tMEBgYEASwIC/4oGicZGScaAAAEAAAAAAPAA8AACAASAB4AKgAAAT4BNCYiBhQWFyMVMxEjFTM1IwMGAAcWBBc+ATcmAgMuASc+ATceARcOAQH0GCEhMCEhUY85Ock6K83++AQEAQjNuf8FBf/Hq+MEBOOrq+MEBOMCoAEgMSAgMSA6Hf7EHBwCsQT++M25/wUF/7nNAQj8pwTjq6vjBATjq6vjAAAAAwAAAAADpwOnAAsAFwAjAAABBycHFwcXNxc3JzcDDgEHHgEXPgE3LgEDLgEnPgE3HgEXDgECjpqaHJqaHJqaHJqatrn1BQX1ubn1BQX1uajfBATfqKjfBATfAqqamhyamhyamhyamgEZBfW5ufUFBfW5ufX8xwTfqKjfBATfqKjfAAAAAwAAAAAD6QPpABEAHQAeAAABDgEjLgEnPgE3HgEXFAYHAQcBPgE3LgEnDgEHHgEXAo41gEmq4gQE4qqq4gQvKwEjOf3giLUDA7WIiLUDBLSIASMrLwTiqqriBATiqkmANP7dOQEZA7WIiLUDA7WIiLUDAAACAAAAAAPoA+gACwAnAAABBgAHFgAXNgA3JgADFg4BIi8BBwYuATQ/AScmPgEyHwE3Nh4BFA8BAfTU/uUFBQEb1NQBGwUF/uUDCgEUGwqiqAobEwqoogoBFBsKoqgKGxMKqAPoBf7l1NT+5QUFARvU1AEb/WgKGxMKqKIKARQbCqKoChsTCqiiCgEUGwqiAAAAABAAxgABAAAAAAABAAQAAAABAAAAAAACAAcABAABAAAAAAADAAQACwABAAAAAAAEAAQADwABAAAAAAAFAAsAEwABAAAAAAAGAAQAHgABAAAAAAAKACsAIgABAAAAAAALABMATQADAAEECQABAAgAYAADAAEECQACAA4AaAADAAEECQADAAgAdgADAAEECQAEAAgAfgADAAEECQAFABYAhgADAAEECQAGAAgAnAADAAEECQAKAFYApAADAAEECQALACYA+ndldWlSZWd1bGFyd2V1aXdldWlWZXJzaW9uIDEuMHdldWlHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQB3AGUAdQBpAFIAZQBnAHUAbABhAHIAdwBlAHUAaQB3AGUAdQBpAFYAZQByAHMAaQBvAG4AIAAxAC4AMAB3AGUAdQBpAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERAAZjaXJjbGUIZG93bmxvYWQEaW5mbwxzYWZlX3N1Y2Nlc3MJc2FmZV93YXJuB3N1Y2Nlc3MOc3VjY2Vzc19jaXJjbGURc3VjY2Vzc19ub19jaXJjbGUHd2FpdGluZw53YWl0aW5nX2NpcmNsZQR3YXJuC2luZm9fY2lyY2xlBmNhbmNlbAZzZWFyY2gFY2xvc2UAAAAA') format('truetype'); 6 | } 7 | 8 | [class^="weui_icon_"]:before, [class*=" weui_icon_"]:before { 9 | font-family: "weui"; 10 | font-style: normal; 11 | font-weight: normal; 12 | speak: none; 13 | 14 | display: inline-block; 15 | vertical-align: middle; 16 | text-decoration: inherit; 17 | width: 1em; 18 | margin-right: .2em; 19 | text-align: center; 20 | /* opacity: .8; */ 21 | 22 | /* For safety - reset parent styles, that can break glyph codes*/ 23 | font-variant: normal; 24 | text-transform: none; 25 | 26 | /* fix buttons height, for twitter bootstrap */ 27 | line-height: 1em; 28 | 29 | /* Animation center compensation - margins should be symmetric */ 30 | /* remove if not needed */ 31 | margin-left: .2em; 32 | 33 | /* you can be more comfortable with increased icons size */ 34 | /* font-size: 120%; */ 35 | 36 | /* Uncomment for 3D effect */ 37 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ 38 | } 39 | 40 | .weui_icon_circle:before { content: "\EA01" } /* '' */ 41 | .weui_icon_download:before { content: "\EA02" } /* '' */ 42 | .weui_icon_info:before { content: "\EA03" } /* '' */ 43 | .weui_icon_safe_success:before { content: "\EA04" } /* '' */ 44 | .weui_icon_safe_warn:before { content: "\EA05" } /* '' */ 45 | .weui_icon_success:before { content: "\EA06" } /* '' */ 46 | .weui_icon_success_circle:before { content: "\EA07" } /* '' */ 47 | .weui_icon_success_no_circle:before { content: "\EA08" } /* '' */ 48 | .weui_icon_waiting:before { content: "\EA09" } /* '' */ 49 | .weui_icon_waiting_circle:before { content: "\EA0A" } /* '' */ 50 | .weui_icon_warn:before { content: "\EA0B" } /* '' */ 51 | .weui_icon_info_circle:before { content: "\EA0C" } /* '' */ 52 | .weui_icon_cancel:before { content: "\EA0D" } /* '' */ 53 | .weui_icon_search:before { content: "\EA0E" } /* '' */ 54 | .weui_icon_clear:before { content: "\EA0F" } /* '' */ -------------------------------------------------------------------------------- /src/components/Recommand.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 136 | 137 | 138 | 227 | -------------------------------------------------------------------------------- /src/components/Play.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 110 | 111 | 371 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 |  52 | 53 | 158 | 159 | 414 | -------------------------------------------------------------------------------- /src/components/Album.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 146 | 147 | 148 | 401 | -------------------------------------------------------------------------------- /src/components/Cd.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 183 | 184 | 185 | 421 | -------------------------------------------------------------------------------- /src/components/Search.vue: -------------------------------------------------------------------------------- 1 | 90 | 91 | 183 | 184 | 444 | --------------------------------------------------------------------------------