整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          HTML5+js開發(fā)自己的音樂播放器,千萬粉絲圍觀!

          HTML5+js開發(fā)自己的音樂播放器,千萬粉絲圍觀!

          天小編我博客時,看到了一位大神分享的自己的音樂播放器,小編我也COPY了一份分享給頭條上的小伙伴,能搞定這個音樂播放器找份工作還是沒壓力的,畢竟這個項目還是挺好的,正在學(xué)習(xí)web前端網(wǎng)頁制作的伙伴們福利來了,小編我我項目整理了一下,順便寫下這篇文章(項目地址文末有)

          做完的項目如圖所示:

          實現(xiàn)的功能

          1、首頁

          2、底部播放控件

          3、播放頁面

          4、播放列表

          5、排行榜

          6、音樂搜索

          輸入搜索關(guān)鍵詞,點擊放大鏡圖標

          7、側(cè)邊欄

          API

          感謝作者把api整理的這么好(點個贊)

          https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=%e6%90%9c%e7%b4%a2%e9%9f%b3%e4%b9%90

          目錄結(jié)構(gòu)

          1、輪播圖

          首先感謝作者ShanaMaid/vue-image-scroll開源的代碼,我把代碼copy下來自己進行了一點修改(沒有手指滑動效果),因為這是移動端,少不了的手指滑動切換,所以添加了vue-touch(偷偷告訴你,vue-touch的next分支還是支持vue2.0的)。

          2、歌曲操作(喜歡,分享,加入播放列表)動畫、播放列表展開與刪除歌曲動畫

          transition-group

          一組過度動畫,這里有個小坑的,之前看官網(wǎng)列表過渡的栗子,給每一項設(shè)置唯一的key值,一般都會用index。所以在做的時候就把index傳給key,結(jié)果過渡老是不對,后來換成對應(yīng)的item

          就正常了(生無可戀臉)。

          3、直線進度條、弧形進度條

          西班牙建筑大師曾說過:“直線屬于人類,曲線則歸于上帝”。在這里我大膽的使用了弧形來作為進度條,(幾大熱門音樂APP貌似還沒有弧形進度條)。

          這里我用到了Vue的綁定內(nèi)聯(lián)樣式

          5、圖片懶加載

          使用了vue-lazyload插件

          用法:

          6、歌詞滾動與高亮

          因為api提供的歌詞包括時間,如:

          [03:57.280]原諒我這一生不羈放縱愛自由

          所以首先要進行字符串切割:

          然后在播放的監(jiān)聽事件中與播放的當前做對比:

          到這就ok了

          7、vuex狀態(tài)管理

          推薦官方調(diào)試工具 devtools extension

          想進一步理解vuex,可以看這篇博客vuex學(xué)習(xí)實踐筆記

          之前看到好多人寫的vuex,把整個項目的數(shù)據(jù)放到了一個state里,導(dǎo)致應(yīng)用的所有狀態(tài)集中到一個很大的對象。但是,當應(yīng)用變得很大時,store 對象會變得臃腫不堪。

          所以我建議(個人見解,輕噴):將 store 分割到模塊(module)。每個模塊擁有自己的 state、mutation、action、getters。這樣方便管理與后期的維護。

          車已到站??。

          入門只是學(xué)習(xí)的開始,這時你可以運用你的技能,實現(xiàn)各種需求。 在實現(xiàn)各種需求時,你會遇到更多各種各樣的問題。有些問題可能已經(jīng)不是單純寫JS代碼能很好解決的了。 你可能需要配合一些框架,或一些工具,或一些設(shè)計模式, 或一些業(yè)務(wù)知識。

          隨著解決更多問題, 你也會積累更多的知識。之后會是漫長的積累過程, 通過項目經(jīng)驗、看書、看博客、思考、討論等等,積累你的經(jīng)驗和知識。

          你需要持之以恒和刨根問底。總之,之后就看你自己的了。還是和前提差不多的那句話:你需要主動。

          最后再來提點建議:

          1. 寫JS的最好辦法..是不停的重復(fù)練習(xí)....其實很多人反映...學(xué)JS的時候很難..但是有些人認為..它沒有服務(wù)端的語言難.或者說..根本就不屑的學(xué)這種語言...什么破語言..老出各種各樣的錯誤...瀏覽器還不兼容..但是...學(xué)好JS對你未來的web開發(fā)有至關(guān)重要的作用....我覺得.JS是奠定RIA的基礎(chǔ)...或者說..客戶端的開發(fā)RIA的基礎(chǔ).

          2. 這個音樂播放器項目到這里就算是做完了,想要完整代碼自己學(xué)習(xí)練手的小伙伴進我的群自助領(lǐng)取,已經(jīng)上傳到群文件里了:640633433,歡迎初學(xué)和進階中的小伙伴。

          如果項目有哪些缺陷,歡迎在評論區(qū)指正!

          過閱讀這篇文章,可以學(xué)習(xí)到如何使用DefinePlugin插件使得前端項目更加工程化,說清晰點就是如何使用這個插件,在編譯階段根據(jù)NODE_ENV自動切換配置文件,提升前端開發(fā)效率。

          • DefinePlugin的正確用法
          • 如何使用DefinePlugin添加配置文件,構(gòu)建期間自動檢測環(huán)境變化,也就是如何根據(jù)NODE_ENV引入配置文件?

          DefinePlugin的正確用法

          DefinePlugin中的每個鍵,是一個標識符或者通過.作為多個標識符。

          • 如果value是一個字符串,它將會被當做code片段
          • 如果value不是字符串,它將會被stringify(包括函數(shù))
          • 如果value是一個對象,則所有key的定義方式相同。
          • 如果key有typeof前綴,它只是對typeof 調(diào)用定義的。

          這些值將內(nèi)聯(lián)到代碼中,壓縮減少冗余。

          new webpack.DefinePlugin({
              PRODUCTION: JSON.stringify(true),
              VERSION: JSON.stringify('5fa3b9'),
              BROWSER_SUPPORTS_HTML5: true,
              TWO: '1+1',
              'typeof window': JSON.stringify('object'),
              'process.env': {
                   NODE_ENV: JSON.stringify(process.env.NODE_ENV)
               }
          });
          
          console.log('Running App version' + VERSION);
          

          plugin不是直接的文本值替換,它的值在字符串內(nèi)部必須包括實際引用。典型的情況是用雙引號或者JSON.stringify()進行引用,'"production"',JSON.stringify('production')。

          重點:在vue-cli創(chuàng)建的項目中,凡是src下的文件,都可以訪問到VERSION這個變量,例如main.js,App.vue等等

          我們現(xiàn)在看一下上面的幾種類型的key值,在代碼中的輸出。

          console.log(PRODUCTION, VERSION, BROWSER_SUPPORTS_HTML5, TWO, typeof window, process.env);
          
          PRODUCTION: true,
          VERSION: "5fa3b9",
          BROWSER_SUPPORTS_HTML5: true,
          TWO: 2,
          typeof window: "object",
          process.env: {NODE_ENV: "development"},
          

          在代碼中,我們一般會有以下幾種用途:

          • 根據(jù)process.env.NODE_ENV區(qū)分環(huán)境
          • 引入配置文件
          • 根據(jù)NODE_ENV引入配置文件(這個很重要,后面會講到)

          Feature Flag

          可以控制新特性和實驗特性的開關(guān)。

          new webpack.DefinePlugin({
              'NICE_FEATURE': JSON.stringify(true),
              'EXPERIMENTAL': JSON.stringify(false),
          })
          

          process.env.NODE_ENV的正確配置方式是什么?

          process: {
              env: {
                  NODE_ENV: JSON.stringify('production')
              }
          }
          

          評價:非常不好,會overwrite整個process對象,僅僅保留新的NODE_ENV,破壞進程。 原始的process對象包含如下內(nèi)容 ,包含了當前進程的很多信息。

          process {
            title: 'node',
            version: 'v8.11.2',
            moduleLoadList: 
             [ 'Binding contextify',],
            versions: 
             { http_parser: '2.8.0'},
            arch: 'x64',
            platform: 'darwin',
            release: 
             { name: 'node' },
            argv: [ '/usr/local/bin/node' ],
            execArgv: [],
            env: 
             { TERM: 'xterm-256color'},
            pid: 14027,
            features: 
             { debug: false},
            ppid: 14020,
            execPath: '/usr/local/bin/node',
            debugPort: 9229,
            _startProfilerIdleNotifier: [Function: _startProfilerIdleNotifier],
            _stopProfilerIdleNotifier: [Function: _stopProfilerIdleNotifier],
            _getActiveRequests: [Function: _getActiveRequests],
            _getActiveHandles: [Function: _getActiveHandles],
            reallyExit: [Function: reallyExit],
            abort: [Function: abort],
            chdir: [Function: chdir],
            cwd: [Function: cwd],
            umask: [Function: umask],
            getuid: [Function: getuid],
            geteuid: [Function: geteuid],
            setuid: [Function: setuid],
            seteuid: [Function: seteuid],
            setgid: [Function: setgid],
            setegid: [Function: setegid],
            getgid: [Function: getgid],
            getegid: [Function: getegid],
            getgroups: [Function: getgroups],
            setgroups: [Function: setgroups],
            initgroups: [Function: initgroups],
            _kill: [Function: _kill],
            _debugProcess: [Function: _debugProcess],
            _debugPause: [Function: _debugPause],
            _debugEnd: [Function: _debugEnd],
            hrtime: [Function: hrtime],
            cpuUsage: [Function: cpuUsage],
            dlopen: [Function: dlopen],
            uptime: [Function: uptime],
            memoryUsage: [Function: memoryUsage],
            binding: [Function: binding],
            _linkedBinding: [Function: _linkedBinding],
            _events: 
             { newListener: [Function],
               removeListener: [Function],
               warning: [Function],
               SIGWINCH: [ [Function], [Function] ] },
            _rawDebug: [Function],
            _eventsCount: 4,
            domain: [Getter/Setter],
            _maxListeners: undefined,
            _fatalException: [Function],
            _exiting: false,
            assert: [Function],
            config: {},
            emitWarning: [Function],
            nextTick: [Function: nextTick],
            _tickCallback: [Function: _tickDomainCallback],
            _tickDomainCallback: [Function: _tickDomainCallback],
            stdout: [Getter],
            stderr: [Getter],
            stdin: [Getter],
            openStdin: [Function],
            exit: [Function],
            kill: [Function],
            _immediateCallback: [Function: processImmediate],
            argv0: 'node' }
          
          'process.env': {
              NODE_ENV: JSON.stringify('production')
          }
          

          評價:不好,會overwrite整個process.env對象,破壞進程環(huán)境,導(dǎo)致破壞兼容性。 原始的process.env對象包含如下內(nèi)容 ,包含了當前進程的很多信息。

          { TERM: 'xterm-256color',
            SHELL: '/bin/bash',
            TMPDIR: '/var/folders/lw/rl5nyyrn4lb0rrpspv4szc3c0000gn/T/',
            Apple_PubSub_Socket_Render: '/private/tmp/com.apple.launchd.dEPuHtiDsx/Render',
            USER: 'frank',
            SSH_AUTH_SOCK: '/private/tmp/com.apple.launchd.MRVOOE7lpI/Listeners',
            __CF_USER_TEXT_ENCODING: '0x1F5:0x19:0x34',
            PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Wireshark.app/Contents/MacOS',
            PWD: '/Users/frank/Desktop/corporation/weidian-crm',
            XPC_FLAGS: '0x0',
            XPC_SERVICE_NAME: '0',
            SHLVL: '1',
            HOME: '/Users/frank',
            LOGNAME: 'frank',
            LC_CTYPE: 'zh_CN.UTF-8',
            _: '/usr/local/bin/node' }
          
          'process.env.NODE_ENV': JSON.stringify('production')
          

          評價:好。因為僅僅對NODE_ENV值進行修改,不會破壞完整進程,也不會破壞兼容性。

          如何使用DefinePlugin添加配置文件,構(gòu)建期間自動檢測環(huán)境變化,也就是如何根據(jù)NODE_ENV引入配置文件?

          情景:開發(fā)階段的接口地址往往與生產(chǎn)階段的接口地址是不一致的。例如開發(fā)時是development.foo.com,而生產(chǎn)時是production.foo.com,如果需要打包發(fā)布,那么需要手動去替換域名或者是一個分支維護一個專門的配置文件,這兩種方式是非常笨重的。

          • 手動替換

          文件效率低下,每次在development和production間切換都需要進行配置文件的更新,容易出錯

          • 配置文件

          相對手動替換高級一些,但是不能一次性查看development和production的全部配置信息,需要在分支間切換,效率低下,且不適用于多種環(huán)境的配置

          • webpack.DefinePlugin()

          全局配置文件,自動檢測環(huán)境變化,效率高效。

          webpack的DefinePlugin正是為我們解決這樣一個問題,它維護一個全局的配置文件,在編譯期間會自動檢測process.env.NODE_ENV,根據(jù)當前的環(huán)境變量去替換我們的接口域名。

          下面我將以一個實例來介紹如何正確使用webpack.DefinePlugin。

          /config/api.js

          const NODE_ENV=process.env.NODE_ENV;
          const config={
               production: {
                  FOO_API: 'production.foo.api.com',
                  BAR_API: 'production.bar.api.com',
                  BAZ_API: 'production.baz.api.com',
               },
               development: {
                  FOO_API: 'development.foo.api.com',
                  BAR_API: 'development.bar.api.com',
                  BAZ_API: 'development.baz.api.com',
               },
               test: {
                  FOO_API: 'test.foo.api.com',
                  BAR_API: 'test.bar.api.com',
                  BAZ_API: 'test.baz.api.com',
               }
          }
          module.exports=config[NODE_ENV];
          

          webpack.dev.conf.js/webpack.prod.conf.js/webpack.test.conf.js

          const apiConfig=require('./config/api');
          const webpackConfig={
              plugins: [
                  new webpack.DefinePlugin({
                      API_CONFIG: JSON.stringify(apiConfig);
                  })
              ]
          }
          ...
          

          custom.component.vue

          <template>
          ...
          </template>
          <script>
          // 這里也可以訪問到API_CONFIG
          export default {
              // 這里無論是data函數(shù),methods對象,computed對象,watch對象,都可以訪問到API_CONFIG;
             data() {
                 return {
                     fooApi: API_CONFIG.FOO_API,
                     user:{
                         id: '',
                         name: '',
                     },
                     hash: '',
                  } 
              },
              computed: {
                  userAvator() {
                      return `${API_CONFIG.BAR_API}?id=${user.id}&name=${user.name}`
                  }
              },
              methods: {
                  uploadImage() {
                      api.uploadImage({user: `${API_CONFIG.BAZ}\${hash}`})
                           .then(()=>{})
                           .catch(()=>{})
                  }
              }
          }
          </script>
          

          上述僅僅適用于vue-cli2.0時代,vue-cli3.0引入了webpack-chain,配置方式大大不同,下文將給出示例。

          如何在vue.config.js中,使用使用DefinePlugin添加配置文件,構(gòu)建期間自動檢測環(huán)境變化,也就是如何根據(jù)NODE_ENV引入配置文件?

          vue.config.js

          const apiConfig=require('./config/api');
          
          module.exports={
              chainWebpack: config=> {
                  config
                      .plugin('define')
                      .tap(args=> { 
                          args[0].API_CONFIG=JSON.stringify(apiConfig)
                          return args
                      })
              }
          }
          

          需要注意的是,在vue-cli3.0中,我們不能直接SET NODE_ENV=production或者EXPORT NODE_ENV=production。 因為vue-cli-servive有3種模式,serve默認為development,build為production,若想修改vue-cli-service包中的NODE_ENV,需要通過vue-cli-service serve --mode production進行切換。 就像下面這樣:

          {
            "scripts": {
              "dev": "vue-cli-service serve", // mode默認為development 
              "production": "vue-cli-service serve --mode production", 
            },
          }
          

          注意:我們只能在development, production或者test 3個模式下進行切換,不能引入類似preproduction之類的自定義node環(huán)境,但是實際上這3個環(huán)境已經(jīng)足以滿足大多數(shù)的開發(fā)情況。

          為什么vue-cli 3.0中的DefinePlugin可以用config.plugin('define')修改入?yún)ⅲ?/h1>

          在源碼文件base.js中,有下面的代碼:

              webpackConfig
                .plugin('define')
                  .use(require('webpack/lib/DefinePlugin'), [
                    resolveClientEnv(options)
                  ])
          
          

          這一點很關(guān)鍵!我們在vue.config.js中拿到的config.plugin('define'),實際上時vue-service內(nèi)部創(chuàng)建的webpack.DefinePlugin實例的引用 ! 明確了這一點,我們在以后增強webpack默認插件配置時,需要先到vue-service的源碼中尋找一番,看看有沒有對應(yīng)plugin的引用,若有,必須根據(jù)vue-service定義的名字直接引用,否則會修改失敗。

          期待和大家交流,共同進步,歡迎大家加入我創(chuàng)建的與前端開發(fā)密切相關(guān)的技術(shù)討論小組:

          SegmentFault專欄:趁你還年輕,做個優(yōu)秀的前端工程師

          知乎專欄:趁你還年輕,做個優(yōu)秀的前端工程師

          Github博客: 趁你還年輕233的個人博客

          微信公眾號: 大大大前端 / excellent_developers

          努力成為優(yōu)秀前端工程師!

          sPDF 是一個使用Javascript語言生成PDF的開源庫。你可以在Firefox插件,服務(wù)端腳本或是瀏覽器腳本中使用它。

          瀏覽器兼容性:

          IE 10, Firefox 3+, Chrome, Safari 3+, Opera,未來將兼容 IE 10 以下版本,對于 IE10 以下的版本會使用 Downloadify 來實現(xiàn)文件下載功能。

          支持文件格式:

          • 文本,數(shù)字,圖形,圖片,同時你可以自由的編輯標題或者其它類型元素。
          • 支持互動的內(nèi)容制作,例如,你可以輸入文字或者數(shù)字,然后jsPDF幫助生成最后的PDF內(nèi)容。
          • 支持現(xiàn)代瀏覽器,如果是老式瀏覽器的話,可以很好的使用flash來實現(xiàn)兼容。不過貌似支持Firefox不是很好,如果要查看演示,使用Chrome吧!

          官網(wǎng)地址:http://jspdf.com https://parall.ax/products/jspdf

          項目地址:https://github.com/MrRio/jsPDF


          主站蜘蛛池模板: 精品国产一区二区三区在线观看| 亚洲av无码一区二区乱子伦as| 无码少妇精品一区二区免费动态| 精品国产一区二区三区不卡| 中文字幕一区二区三| 在线观看国产一区二区三区 | 国产精品一区二区久久乐下载 | 精品不卡一区二区| 无人码一区二区三区视频| 亚洲国产精品第一区二区三区 | 亚洲一区二区久久| 久久精品国产一区| 久久99精品国产一区二区三区 | 精品无码人妻一区二区三区品| 精品成人一区二区三区免费视频 | 国产一区二区在线观看app| 加勒比精品久久一区二区三区| 91久久精品无码一区二区毛片| 久久久久人妻精品一区蜜桃| 精品视频一区二区三区免费 | 日本道免费精品一区二区| 无码AV动漫精品一区二区免费| 国产综合视频在线观看一区| 国产精品视频免费一区二区三区| 相泽南亚洲一区二区在线播放| 中文字幕日韩一区二区不卡| 亚洲国产精品无码第一区二区三区| 少妇激情AV一区二区三区| 亚洲av乱码一区二区三区香蕉 | 国产日韩精品一区二区在线观看| 成人在线观看一区| 视频在线一区二区三区| 精品人妻少妇一区二区三区| 丰满少妇内射一区| 一区二区三区观看免费中文视频在线播放| 中文字幕一区二区三区乱码| 久久国产一区二区三区| 亚洲一区二区三区写真| 国模吧一区二区三区精品视频| 福利片福利一区二区三区| 亚洲国产一区视频|