zoukankan      html  css  js  c++  java
  • 炸鸡音乐,vue,spa项目分析

    项目描述:Web App,QQ音乐界面风格,SPA应用

    技术描述:

    1.fast-click处理移动端点击事件的延迟

    2.create-keyframes-animation处理css动画

    3.jsonp npm封装,跨域获取数据

    4.vue-lazyload实现页面懒加载

    5.loading实现网络加载过程中的界面效果

    6.axios数据请求

    7.webpack+vue-cli自动化构建项目

    8.vue,mixins的运用

    9.vuex状态管理器

    10.mintui,组件实现区域滚动,首页,歌手详情页面的图片轮播效果

    11.webpack实现路由懒加载(异步加载),优化代码,提高首页访问速度

    具体实现,要点分析:

     1 . 文件目录结构

    dist目录: 

    build 打包编译 生成 dist目录(index,js,css,image)vendor文件是打包后的node_modules文件
    线上 gzip 压缩 减少代码量 例如 300kb代码 gzip 后是: --》100kb
    vendor打包后的 hash值不变 ( static/js/vendor.52caf94d568661fbe99f.js.map)
    build打包后dist文件问们可以在启动的node服务器里面进行静态托管(也就是将资源放本地服务器),参照prod.server.js
     
    prod.server.js 文件
     
    import { match } from "./C:/Users/Administrator/AppData/Local/Microsoft/TypeScript/2.6/node_modules/@types/minimatch";
    import { response } from "./C:/Users/Administrator/AppData/Local/Microsoft/TypeScript/2.6/node_modules/@types/spdy
     
    const express = require("express")
    const config = require("./config/index")
    const axios = require("axios")
    const app = express();
    const apiRoutes = express.Router()    // server的路由分发代理

    apiRoutes.get("/getDiscLisc", (req, res) => {
    let url = "https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg"
    axios.get(url, {
    headers: {        // 请求数据的时候 采取了两种:  一种是 jsonp npm封装  一种是node代理这种方式:请求后端发起请求数据服务器,设置headers的referer(请求来源地址)host:来源主机, 绕过同源策略,“欺骗数据服务器”
    referer: "https://c.yy.qq.com/",
    host: "c.y.qq.com"
    },
    params: req.query
    }).then((response) => {
    res.json(response.data)
    }).catch((e) => {
    console.log(e)
    })
    })

    apiRoutes.get("/lyric", (req, res) => {
    const url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg'

    axios.get(url, {
    headers: {
    referer: "https://c.yy,qq.com/",
    host: "c.yy.com"
    },
    params: req.query
    }).then((response) => {
    let ret = response.data
    if (typeof ret === 'string') {
    let reg = /^w+(({[^()]+}))$/
    let matches = ret.match(reg)
    if (matches) {

    }
    }
    })

    // apiRoutes.get("/lyric", (req, res) => {


    // })
    })

    app.use("/api", apiRoutes)          //  /api 作为代理地址,前端请求使用这个来请求后端数据     /api+你的前端路由
    // 直接将静态资源(托管后的dist目录)作为 托管
    app.use(express.static("./dist"))         //这个就是之前说的 将 build 后的静态资源托管,优化,
       // index/.html 里面的img icon 资源 可以放在  托管  static目录下
    let port = process.env.PORT || config.build.port
    module.exports = app.listen(port, (err) => {
    if (err) {
    console.log(err)
    return
    }
    console.log("LIstening at http://localhost:" + port + " ")
    })
     
    main.js:
    import store from './store' // ./store -- > 直接载入我的index.js文件
     
    state.js 定义数据初始值 : 如下
    const state ={
    singer : {},
    playing: false,
    fullScreen:true,
    playList:[],
    sequenceList:[],
    mode:playMode.sequence,
    currentIndex:-1,

    // 这几个test数据
    songs_test:[]
    }
    export default state
     
     
    mutations.js 文件定义对state.js数据的修改函数
    import * as types from "./mutation-type"       // 导入预定义变量 * as 写法:代表以 types 点的方式获取变量
     
    mutation-type文件
    // mutations.js 文件数据: 函数名 在mutations-types 里面配置
    export const SET_SINGER = 'SET_SINGER'
    export const SET_PLAYING_STATE = 'SET_PLAYING_STATE'
    export const SET_FULL_SCREEN = "SET_FULL_SCREEN"
    export const SET_PLAYLIST = "SET_PLAYLIST"
    export const SET_SEQUENCE_LIST = "SET_SEQUENCE_LIST"
    export const SET_PLAY_MODE = "SET_PLAY_MODE"
    export const SET_CURRENT_INDEX = "SET_CURRENT_INDEX"
     

    const mutations = {
    // import * as xx from " " 引入的: 使用的时候 [xx....]
    [types.SET_SINGER](state,singer){
    state.singer = singer
    console.log(state.singer);
    console.log("state.singer!!!");
    } ,
    [types.SET_PLAYING_STATE](state,flag){
    state.playing = flag
    },
    [types.SET_FULL_SCREEN](state,flag){
    state.fullScreen = flag
    },
    [types.SET_PLAYLIST](state,list){
    state.playList = list
    },
    [types.SET_SEQUENCE_LIST](state,list){
    state.sequenceList = list
    },

    [types.SET_PLAY_MODE](state,list){
    state.mode = list
    },
    [types.SET_CURRENT_INDEX](state,index){
    state.currentIndex = index
    },

    // songs_test
    songs_test(state,test){
    state.songs_test = test
    }
    }
    export default mutations
     
    getters.js 文件
     
    // 在getters 中取数据 映射到 state上
    export const singer = state => {
    return state.singer // 返回值必须加 stste => state.singer || (state) =>{ return ...}
    }

    export const playing = state => state.playing
    export const fullScreen = state => state.fullScreen
    export const playList = state => state.playList
    export const sequenceList = state => state.sequenceList
    export const mode = state => state.mode
    export const currentIndex = state => state.currentIndex
    export const currentSong = (state) => {
    return state.playList[state.currentIndex] || {}
    }


    // songs_test 数据
    export const songs_test = state=>state.songs_test
     
     
    actions.js 是作为对mutations的提交
    // 一个动作多次提交修改mutations 封装actions文件
    import * as types from "./mutation-type"

    export const selectPlay = function ({commit,state},{list,index}){
     
    // commit 去改变 mutations -- 从而改变 state  commit第二个参数是传入到了 对应函数的第二个参数位置上
    commit(types.SET_SEQUENCE_LIST,list)
    commit(types.SET_PLAYLIST,list)
    commit(types.SET_CURRENT_INDEX,index)
    commit(types.SET_FULL_SCREEN,true)
    commit(types.SET_PLAYING_STATE,true)

    }
     
     
    router文件 index.js 
    // 路由懒加载: 首页加载速度的优化 !!!!!!
     
    // 路由懒加载 语法:
    const MyRecommend = (resolve) => {
    import('@/components/MyRecommend/MyRecommend').then((module) => {
    resolve(module)
    })
    }
     
    main.js 

    import 'babel-polyfill'
    import Vue from 'vue'
    import App from './App'
    import router from './router' // vue-router
    import store from './store' // vuex

    import '@/common/scss/index.scss'

    // 消除 click 移动浏览器300ms延迟
    import attachFastClick from 'fastclick'
    attachFastClick.attach(document.body)

    // 图片懒加载
    import VueLazyload from 'vue-lazyload'
    Vue.use(VueLazyload, {  // 懒加载
    loading: require('@/common/img/default.png')
    })

    Vue.config.productionTip = false

    new Vue({
    el: '#app',
    router,
    store,
    template: '<App/>', // render: h => h(App)
    components: { App }
    })

  • 相关阅读:
    Java遍历JsonObject对象
    fastjson.JSONObject之对象与JSON转换方法
    Java HotSpot VM中的JIT编译
    JAVA 反射类 捕获异常 method.invoke方法如何捕获异常
    手动调用hibernate的参数校验器和springboot参数校验器 验证
    Netty-Socketio API
    Netty-socketio集成redis,服务端集群推送消息
    mysql 导出csv格式数据解决乱码
    自建dns服务器
    MySQL 8.0 克隆(clone)插件快速搭建主从复制
  • 原文地址:https://www.cnblogs.com/ccnNL/p/9365442.html
Copyright © 2011-2022 走看看