Vue2.0全家桶仿騰訊體育APP(Web版)

Vue2.0全家桶仿騰訊體育APP

一年一度的NBA總決賽,相信球迷用的最多的就是騰訊體育這款APP,恰好上手Vue,當練手就把這個APP仿下來。html

效果預覽

?在線預覽:點我!!!在線預覽,手機瀏覽或切換瀏覽器移動調試

?源碼地址:Github✨✨求你的小星星~

描述

前端部分前端

  • SPA單頁應用,先後端分離,webpack build to distvue

  • 移動設備兼容:使用flexible.js和rem處理兼容問題webpack

  • 路由懶加載:Vue Router 處理路由,結合 Vue 的 異步組件 和 Webpack 的 code splitting feature 實現路由懶加載ios

  • axios作ajax請求git

  • 使用了 Vuex 管理組件間的狀態,實現非父子組件之間的通訊github

  • 使用 Vue-draggable實現移動端拖拽排序web

  • mint-UI完成構建圖片懶加載、下拉刷新、infinite-scroll等組件ajax

  • 大圖片、輪播圖經過 sessionStorage 存儲mongodb

後端部分

  • mock模擬數據

  • express 作靜態資源目錄

待更新的功能

  • 處理數據相關性,讓圈子組件和文章組件對應顯示

  • 改用 express 拋接口

  • 用 express + mongodb 保存用戶狀態

具體功能實現

路由結構

使用了Vue的異步組件和Webpack的code splitting feature實現路由組件的懶加載當打包構建應用時,Javascript包會變得很是大,影響頁面加載。若是咱們能把不一樣路由對應的組件分割成不一樣的代碼塊,而後當路由被訪問的時候才加載對應組件,這樣就更加高效了。這樣剛進去的時候頁面加載時間明顯減短。

routes: [
    {
      path: '/article-video/:id',
      component: resolve => require(['@/page/article/article-video'], resolve)
    },
    {
      path: '/article/:id',
      component: resolve => require(['@/page/article/article'], resolve)
    },
    {
      path: '/',
      name: 'Index',
      component: resolve => require(['@/page/index.vue'], resolve),
      redirect: '/competition/recommend',
      children: [{
        path: '/competition',
        name: 'competition',
        component: resolve => require(['@/page/home/competition'], resolve),
        children: [{
          path: '/competition/recommend',
          name: 'recommend',
          component: resolve => require(['@/components/tunnels/recommend'], resolve)
        }, {
          path: '/competition/video',
          name: 'video',
          component: resolve => require(['@/components/tunnels/video'], resolve)
        }, {
          path: '/competition/nba',
          name: 'nba',
          component: resolve => require(['@/components/tunnels/nba'], resolve),
        }]
      }, {
        path: '/community',
        name: 'community',
        component: resolve => require(['@/page/home/community'], resolve),
        children: [{
          path: '/community/hotpost',
          name: 'hotpost',
          component: resolve => require(['@/components/community/hotpost'], resolve)
        }, {
          path: '/community/mycircle',
          name: 'mycircle',
          component: resolve => require(['@/components/community/mycircle'], resolve)
        }, {
          path: '/community/activies',
          name: 'activies',
          component: resolve => require(['@/components/community/activies'], resolve)
        }, {
          path: '/community/all',
          name: 'communityall',
          component: resolve => require(['@/components/community/all'], resolve)
        }, {
          path: '/community/article/:id',
          component: resolve => require(['@/page/article/article'], resolve),
          redirect: '/article/:id'
        }]
      }, {
        path: '/agenda',
        name: 'agenda',
        component: resolve => require(['@/page/home/agenda'], resolve),
        children: [{
          path: '/agenda/focus',
          name: 'focus',
          component: resolve => require(['@/components/agenda/focus'], resolve)
        }, {
          path: '/agenda/all',
          name: 'agendaall',
          component: resolve => require(['@/components/agenda/all'], resolve)
        }, {
          path: '/agenda/popular',
          name: 'popular',
          component: resolve => require(['@/components/agenda/popular'], resolve)
        }]
      }, {
        path: '/mine',
        name: 'Mine',
        component: resolve => require(['@/page/home/mine'], resolve),
        redirect: '/mine/index',
        children: [{
          path: '/mine/index',
          component: resolve => require(['@/components/mine/index'], resolve)
        }]
      }]
    }
  ]

拖拽排序

衆所皆知,h5原生的drag事件對移動端是無效的,所以,移動端的拖拽實現,依賴於touchstart、touchend和scroll的座標計算,實現起來很是麻煩,Vue-draggable可讓咱們輕鬆實現跟PC端效果同樣的拖拽排序。

?文檔地址:https://github.com/SortableJS...

特性Full support of Sortable.js features:

Supports touch devices
Supports drag handles and selectable text
Smart auto-scrolling
Support drag and drop between different lists
No jQuery dependency
Keeps in sync HTML and view model list
Compatible with Vue.js 2.0 transition-group
Cancellation support
Events reporting any changes when full control is needed

安裝依賴

npm install vuedraggable --save

構造拖拽區域

<draggable v-model="subscribedArr" :move="onMove" :options="dragOptions"@start="isDragging=true" @end="isDragging=false">
    <transition-group>
    </transition-group>
</draggable>

Vuex的使用

須要注意:Action 相似於 mutation,不一樣在於:

  • Action 提交的是 mutation,而不是直接變動狀態。

  • Action 能夠包含任意異步操做。

用到的地方

  • 頻道訂閱的狀態改變對應路由的變化

  • 圈子訂閱的狀態改變對應訂閱列表的雙向顯示

mutation-types

// 未定製增長
export const ADD_NOSUBSCRIBED = 'ADD_NOSUBSCRIBED'
// 未定製減小
export const DELETE_NOSUBSCRIBED = 'DELETE_NOSUBSCRIBED'
// 定製增長
export const ADD_SUBSCRIBED = 'ADD_SUBSCRIBED'
// 定製減小
export const DELETE_SUBSCRIBED = 'DELETE_SUBSCRIBED'
// 更新頁面和數據
export const UPDATE_ALL = 'UPDATE_ALL'
// 社團增長
export const ADD_CLUB = 'ADD_CLUB'
// 社團減小
export const DELETE_CLUB = 'DELETE_CLUB'

mutations

import * as types from './mutation_types'

export default {
  // 添加社團
  [types.ADD_CLUB] (state, obj) {
    if(!state.clubs.includes(obj)) state.clubs.push(obj)
    return
  },
  // 刪除社團
  [types.DELETE_CLUB] (state, obj) {
    let oIndex = state.clubs.findIndex((item) => {
      return item.name == obj.name
    })
    state.clubs.splice(oIndex, 1)
  },
  // 添加未訂閱
  [types.ADD_NOSUBSCRIBED] (state, index) {
    console.log(index)
  },
  // 刪除未訂閱
  [types.DELETE_NOSUBSCRIBED] (state, index) {
    console.log(index)
  },
  // 添加訂閱
  [types.ADD_SUBSCRIBED] (state, index) {
    console.log(index)
    let temp = state.noSubscribed[index]
    state.noSubscribed.splice(index, 1)
    state.subscribed.push(temp)
    state.routes[0].push(temp)
  },
   // 刪除訂閱
  [types.DELETE_SUBSCRIBED] (state, index) {
    // console.log(index)
    let oIndex = parseInt(index) + 2
    let temp = state.subscribed[index]
    state.subscribed.splice(index, 1)
    state.routes[0].splice(oIndex, 1)
    // console.log(state.noSubscribed)
    state.noSubscribed.push(temp)
  },
  // 用數據塊更新
  [types.UPDATE_ALL] (state, obj) {
    // console.log(obj)
    // console.log(obj.temp_NoSubscribedArr)
    // console.log(obj.temp_subscribedArr)
    state.subscribed = obj.temp_subscribedArr
    state.noSubscribed = obj.temp_NoSubscribedArr
    // console.log(state.subscribed)
    // console.log(state.noSubscribed)
    state.routes[0] = [{
      name: '推薦',
      url: '/competition/recommend'
    }, {
      name: '視頻',
      url: '/competition/video'
    }]
    // console.log(state.subscribed)
    state.subscribed.map(item => {
      // console.log(item)
      // console.log(state.routes[0])
      state.routes[0].push(item)
    })
    // console.log(state.routes[0])
  }
}

actions

import * as types from './mutation_types'
export default {
  // 未定製增長
  add_nosubscribed: ({ commit }, index) => {
    commit(types.ADD_NOSUBSCRIBED, index)
  },
  // 未定製減小
  delete_nosubscribed: ({ commit }, index) => {
    commit(types.DELETE_NOSUBSCRIBED, index)
  },
  // 定製增長
  add_subscribed: ({ commit }, index) => {
    commit(types.ADD_SUBSCRIBED, index)
  },
  // 定製減小
  delete_subscribed: ({ commit }, index) => {
    commit(types.DELETE_SUBSCRIBED, index)
  },
  // 更新頁面和數據
  update_all: ({ commit }, obj) => {
    commit(types.UPDATE_ALL, obj)
  },
  // 社團增長
  add_club: ({ commit }, obj) => {
    commit(types.ADD_CLUB, obj)
  },
  // 社團減小
  delete_club: ({ commit }, obj) => {
    commit(types.DELETE_CLUB, obj)
  },
}

作個小廣告

? 小前端求實習:個人簡歷

相關文章
相關標籤/搜索