博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LiveQing 高性能流媒体服务器前端重构(一):从零开始搭建 webpack + vue + AdminLTE 多页面脚手架
阅读量:4134 次
发布时间:2019-05-25

本文共 8994 字,大约阅读时间需要 29 分钟。

LiveQing 高性能流媒体服务器前端架构概述

LiveQing 高性能流媒体服务器前端部分最初采用的是 AdminLTE + 各方 jQuery 插件的开发方式, 也就是网络上通常讲的 bootstrap + jquery plugins 的方式. 有经验的前端开发者想必都了解这种架构下开发前端页面的痛点. 当一个页面上 UI 组件多起来的时候, 代码组织就容易变得混乱, 各种 $(document).on 穿梭其中. 这样的页面开发好以后, 隔一段时间, 再来二次开发, 我去, 简直了.

为了解决这样的痛点, 我想重构前端, 引入 vue 的组件化开发模式, 借助 element-ui 这样的组件库, 可以用极少的代码, 码出丰富的功能. 这篇博客是 LiveQing 高性能流媒体服务器前端重构系列博客的第一篇: 从零开始搭建 webpack + vue + AdmintLTE 多页脚本架.

安装前端开发脚手架

首先, 从零搭建 webpack 脚手架. 这里不借助 vue-cli 工具来生成脚手架, 而是一步步从 npm install 开始到手写配置脚本. 因为, 我觉得 vue-cli 一下子生成出来那么多的配置文件和目录, 会让初学者眼花缭乱, 抓不住重点.

初始化工程目录

node -vv6.10.0npm -v5.3.0mkdir easydss-web-srccd easydss-web-srcnpm init -y

安装基础包

npm i admin-lte font-awesome vue vuex webpack webpack-dev-server --save-dev

vuex : 用于 vue 组件间的状态同步

font-awesome : 各种图标

安装常用的 webpack loader

npm i file-loader url-loader css-loader less less-loader style-loader vue-loader vue-template-compiler --save-devnpm i babel-core babel-loader babel-preset-es2015 babel-preset-stage-2 babel-polyfill --save-dev

file-loader : 处理资源文件, 比如图片, 字体等

url-loader : 对 file-loader 的封装, 针对小图片资源提供 base64 data blob
css-loader : 处理 css 文件中的 url 等
style-loader : 将 css 插入到页面的 style 标签
less-* : 将 less 转成 css
vue-* : 处理 vue 单文件组件
babel-* : es6 语法支持, 详细说明参考阮一峰的

安装常用的 webpack 插件

npm i clean-webpack-plugin html-webpack-plugin --save-dev

clean-webpack-plugin : 用来清空发布目录

html-webpack-plugin : 用来生成入口页面, 自动引入生成的 js 文件

工程目录结构预览

首先, 看一下最终的工程目录结构和运行效果, 做到心中有数. 后面将介绍这些目录文件是如何一步步创建或生成的.

liveqing-web-src [工程根目录]├── .babelrc [babel全局配置文件]├── dist [发布目录]├── package.json├── package-lock.json├── src [源文件目录]│   ├── about.js│   ├── assets [资源文件目录]│   │   └── images [资源图片]│   ├── components [组件目录]│   │   ├── About.vue│   │   ├── AdminLTE.vue│   │   ├── Index.vue│   │   ├── NaviBar.vue│   │   └── Sider.vue│   ├── index.html│   ├── index.js│   └── store [状态管理]│       └── index.js└── webpack.config.js [webpack 配置文件]

babel 配置

在工程根目录下新建文件 .babelrc , 内容比较少, 如下:

{    "presets": [        "es2015",        "stage-2"    ],    "plugins": []}

webpack 配置

重头戏来了, 在工程根目录下新建文件 webpack.config.js , 内容如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');const CleanWebpackPlugin = require('clean-webpack-plugin');const webpack = require('webpack');const path = require('path');require("babel-polyfill");function resolve(dir) {    return path.resolve(__dirname, dir)}module.exports = {    //定义页面的入口, 因为js中将要使用es6语法, 所以这里需要依赖 babel 垫片    entry: {        index: ['babel-polyfill', './src/index.js'],        about: ['babel-polyfill', './src/about.js']    },    output: {        path: resolve('dist'), // 指示发布目录        filename: 'js/[name].[chunkhash:8].js' //指示生成的页面入口js文件的目录和文件名, 中间包含8位的hash值    },    //下面给一些常用组件和目录取别名, 方便在js中 import    resolve: {        extensions: ['.js', '.vue', '.json'],        alias: {            'vue$': 'vue/dist/vue.common.js',            'jquery$': 'admin-lte/plugins/jQuery/jquery-2.2.3.min.js',            'src': resolve('src'),            'assets': resolve('src/assets'),            'components': resolve('src/components')        }    },    module: {        //配置 webpack 加载资源的规则        rules: [{            test: /\.js$/,            loader: 'babel-loader',            include: [resolve('src')]        }, {            test: /\.vue$/,            loader: 'vue-loader'        }, {            test: /\.css$/,            loader: 'style-loader!css-loader'        },        {            test: /\.less$/,            loader: "less-loader"        },        {            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,            loader: 'url-loader?limit=10000&name=images/[name].[hash:8].[ext]'        },        {            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,            loader: 'url-loader?limit=10000&name=fonts/[name].[hash:8].[ext]'        },        {            test: /\.(swf|mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,            loader: 'url-loader?limit=10000&name=media/[name].[hash:8].[ext]'        }]    },    plugins: [        //引入全局变量        new webpack.ProvidePlugin({            $: 'jquery',            jQuery: 'jquery',            "window.jQuery": 'jquery',            "window.$": 'jquery'        }),        //编译前先清除 dist 发布目录        new CleanWebpackPlugin(['dist']),        //生成视频广场首页, 在这个页面中自动引用入口 index --> dist/js/index.[chunkhash:8].js        //以 src/index.html 这个文件作为模板        new HtmlWebpackPlugin({            filename: 'index.html',            title: '视频广场',            inject: true, // head -> Cannot find element: #app            chunks: ['index'],            template: './src/index.html',            minify: {                removeComments: true,                collapseWhitespace: false            }        }),        //生成版本信息页面, 在这个页面中自动引用入口 about --> dist/js/about.[chunkhash:8].js        //以 src/index.html 这个文件作为模板        new HtmlWebpackPlugin({            filename: 'about.html',            title: '版本信息',            inject: true,            chunks: ['about'],            template: './src/index.html',            minify: {                removeComments: true,                collapseWhitespace: false            }        })    ]};

创建网页模板文件

上面 webpack.config.js 中, 我们声明了需要生成两个页面, 都是以 src/index.html 作为模板文件, 实际上我们最终生成的两个发布页面 dist/index.htmldist/about.html 就是在这个模板文件基础上, 插入 js 入口文件引用生成出来的(HtmlWebpackPlugin 配置项中的 inject).

下面创建这个模板文件:

src/index.html

            <%= htmlWebpackPlugin.options.title %>        

title 部分将会被 HtmlWebpackPlugin 中的 title 替换

声明 #app div 用来挂载 vue 根组件

创建入口 js 文件

有了网页模板文件, 接下来我们要编写入口 js 文件了. 在入口 js 文件里面, 我们创建 vue 根组件, 并将它挂载到模板页面的 #app 上面.

先贴出两个入口 js 内容, 再作说明.

src/index.js

import Vue from 'vue'import store from "./store";import AdminLTE from './components/AdminLTE'import Index from './components/Index'new Vue({  el: '#app',  store,  template: `  
`, components: { AdminLTE, Index },})

src/about.js

import Vue from 'vue'import store from "./store";import AdminLTE from './components/AdminLTE'import About from './components/About'new Vue({  el: '#app',  store,  template: `  
`, components: { AdminLTE, About }, methods: { btnClick(msg){ alert(msg); } }})

两个 vue 根组件, 共同的地方是 :

  1. 都引用了 vuex store 状态管理, 我们用它来保存各个页面或组件之间共用的数据;
  2. 都引用了 AdminLTE 这个子组件; 实际上在这个子组件里面, 我们定义了 AdminLTE 的整体布局, 先是顶部导航和左侧菜单栏占位, 然后预留一个 slot 私有内容区域, 用以展示各个页面不同的内容;
    顺带说一下, about 页面中演示了 父子组件间的数据交互

创建 vuex store

vuex store 中的数据在整个组件树中共享, 只需要在根组件中引用一个 store. 子组件中通过 mapState, mapGetters, mapMutations, mapActions 访问和修改. .

这里, 暂时想到的共享数据仅仅包括 左上角的 logo左侧栏的菜单数据, 所以我们的 store 文件很简单:

store/index.js

import Vue from "vue";import Vuex from "vuex";Vue.use(Vuex);const store = new Vuex.Store({    state: {        logoText: "EasyDSS",        logoMiniText: "DSS",        menus: [            {                path: "/index.html",                icon: "mouse-pointer",                text: "视频广场"            }, {                path: "/about.html",                icon: "support",                text: "版本信息"            }        ]    },    getters : {    },    mutations: {    },    actions : {            }})export default store;

创建子组件

  • AdminLTE.vue

引入 adminlte 样式和脚本文件, 指定界面布局, 预留 slot 内容区

components/AdminLTE.vue

  • NaviBar.vue

顶部导航组件, 主要是 logo 和 菜单栏的 toggle, 数据从 AdminLTE 组件传入

components/NaviBar.vue

  • Sider.vue

左侧菜单栏组件 , 菜单数据从 AdminLTE 组件传入, 通过比较浏览器地址栏 path , 决定 active 菜单项

components/Sider.vue

  • Index.vue

首页内容区

components/Index.vue

  • About.vue

版本信息内容区

components/About.vue

运行和编译

编辑 package.json, 添加运行和编译脚本指令, 留意其中的 scripts > build, start

{  "name": "liveqing-web-src",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "build": "webpack --progress --hide-modules",    "start": "webpack-dev-server --open",    "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [],  "author": "",  "license": "ISC",  "devDependencies": {    "admin-lte": "^2.3.11",    "babel-core": "^6.26.0",    "babel-loader": "^7.1.1",    "babel-polyfill": "^6.26.0",    "babel-preset-es2015": "^6.24.1",    "babel-preset-stage-2": "^6.24.1",    "clean-webpack-plugin": "^0.1.16",    "css-loader": "^0.28.5",    "file-loader": "^0.11.2",    "font-awesome": "^4.7.0",    "html-webpack-plugin": "^2.30.1",    "less": "^2.7.2",    "less-loader": "^4.0.5",    "style-loader": "^0.18.2",    "url-loader": "^0.5.9",    "vue": "^2.4.2",    "vue-loader": "^13.0.4",    "vue-template-compiler": "^2.4.2",    "vuex": "^2.3.1",    "webpack": "^3.5.5",    "webpack-dev-server": "^2.7.1"  }}

命令行执行 :

npm run start #自动打开浏览器, 查看页面效果

npm run build #生成发布文件到 dist 目录

总结

以上, 我们从零开始, 创建了一个 webpack + vue + AdminLTE 多页面工程的脚手架. 在此基础上可以体验 vue 组件化前端开发的简洁和高效了.

WEB: www.liveqing.com

后续博客计划:

转载地址:http://jgvvi.baihongyu.com/

你可能感兴趣的文章
构造型模式
查看>>
svn out of date 无法更新到最新版本
查看>>
java杂记
查看>>
RunTime.getRuntime().exec()
查看>>
Oracle 分组排序函数
查看>>
删除weblogic 域
查看>>
VMware Workstation 14中文破解版下载(附密钥)(笔记)
查看>>
日志框架学习
查看>>
日志框架学习2
查看>>
SVN-无法查看log,提示Want to go offline,时间显示1970问题,error主要是 url中 有一层的中文进行了2次encode
查看>>
NGINX
查看>>
Qt文件夹选择对话框
查看>>
1062 Talent and Virtue (25 分)
查看>>
1061 Dating (20 分)
查看>>
1060 Are They Equal (25 分)
查看>>
83. Remove Duplicates from Sorted List(easy)
查看>>
88. Merge Sorted Array(easy)
查看>>
leetcode刷题191 位1的个数 Number of 1 Bits(简单) Python Java
查看>>
leetcode刷题198 打家劫舍 House Robber(简单) Python Java
查看>>
NG深度学习第一门课作业2 通过一个隐藏层的神经网络来做平面数据的分类
查看>>