基于 Laravel + Swoole + Vue 搭建实时在线聊天室(四):前端资源初始化

正如学院君开篇所说,本实战教程的前端界面将会基于 https://github.com/hua1995116/webchat 这个前端技术栈实现的聊天室项目,以便将重心专注于基于 Swoole 的聊天室功能开发,为了方便介绍,后面统一将其称之为 Vue-Webchat。

不过 Vue-Webchat 前后端都是基于 JavaScript 实现的,前端使用的是 Vue 框架,后端使用的是 Express 框架,数据库使用的是 MongoDB,并且 WebSocket 通信前后端都是基于 Socket.io,而在本实战项目中,我们希望基于 Laravel 框架作为后端,将数据存储在 MySQL 数据库里面,并且 WebSocket 服务器基于 Swoole 实现,此外,我们还希望借助 Laravel 提供的 Laravel Mix 作为前端资源编译工具,取代原生的 Webpack,所以必须要对原来的前端代码进行适当的改造。

注:为了更好的专注于 Swoole 聊天室功能开发,学院君只使用一篇教程的篇幅来介绍前端代码的改造,更多关于 Vue 组件、Vue Router 以及 Vuex 等 Vue 生态系统工具的使用和完整开发流程,可以参考学院君之前发布的前后端分离项目系列教程,这里不再具体展开介绍了。

另外,本项目前端代码已经提交到 Github 仓库:https://github.com/nonfu/webchat

前端目录结构迁移

在 Vue-Webchat 这个项目中,前端资源代码位于 src 目录下:

原项目前端资源目录结构

我们先删除 Laravel 项目 webchatresources/js 目录下的所有文件,然后将 Vue-Webchat 的 src 目录迁移过来:

新项目前端资源目录结构

这里我对部分目录结构做了调整,比如将原项目的 static/css/reset.css 迁移到了 resources/css/reset.css,将原项目的 src/styles 下的样式代码整合到了 resources/sass/app.scss 中,以更好地适配 Laravel 项目的目录结构。另外,我还将原项目 src 目录下的 App.vueBaseTransition.vue 文件移到 resources/js/layout 目录下,将原项目 src 目录下的 view 子目录重命名为 pages,这个只是个人喜好问题,当然,相应的,需要修改所有的引入文件路径。

此外,前端 JavaScript 入口文件由 main.js 重命名为 app.js

前端视图入口文件

原项目的前端视图入口文件位于根目录下的 index.html,本项目的视图入口文件位于 resources/views/index.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />

    <link rel="icon" type="image/x-icon" href="/favicon.ico">

    <title>Laravel学院在线聊天室</title>

    <script type='text/javascript'>
        window.Laravel = <?php echo json_encode(['csrfToken' => csrf_token(),]); ?>
    </script>
</head>
<body>
    <div id="app"></div>
    <script type="text/javascript" src="{{ asset('js/app.js') }}"></script>
</body>
</html>

相应的,需要到 routes/web.php 路由文件中调整默认的首页视图模板:

Route::get('/', function () {
    return view('index');
});

前端代码调整

接下来,重点看下为了适配 Laravel 后端框架和 Swoole WebSocket 服务器而对前端代码所做的修改。

与后端接口的交互

与后端接口的交互都统一封装在 resources/js/api 目录下,在 axios.js 中提供了对 Axios 库的基础封装,然后所有后端接口调用都位于 server.js 中,这里我们需要对 axios.js 进行调整,加入 CSRF Token 请求头:

import axios from 'axios';
const baseURL = '/api/';

const instance = axios.create();

instance.defaults.timeout = 30000; // 所有接口30s超时
instance.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

// 所有请求头设置 CSRF Token
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
    instance.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

...

具体调用后端接口的路由和处理逻辑先不管,后面开发具体功能时再逐一调试。

与 WebSocket 服务器的交互

Vue-Webchat 项目基于 socket.io-client 库作为客户端与 WebSocket 服务器进行通信,这里我们沿用这一客户端方案,但是需要修改连接配置,将后端配置修改为 Swoole WebSocket 服务器,修改 resources/js/socket.js 代码如下:

// 通过 Socket.io 客户端发起 WebSocket 请求
import io from 'socket.io-client'
const socket = io.connect(process.env.APP_URL + ':' + process.env.LARAVELS_LISTEN_PORT + '/ws/')
export default socket

axios 一样,具体调用这个 socket 模块的地方先不管,后面开发到具体功能的时候再逐一调试。

别名路径的调整

Vue-Webchat 项目在引入组件和视图模块时配置了 @ 路径别名,比如这种:

import {queryString} from '@utils/queryString';

本项目取消了这一配置,直接通过相对路径引入:

import {queryString} from './utils/queryString';

所有涉及到 @ 路径引用的地方都要调整,主要是在 pages 子目录下的 Vue 组件中。

前端样式编译的调整

前面已经提到,本项目的 JavaScript 入口文件是 app.js,我将原项目在这里引入的 CSS 资源文件通通移出,整合到 webpack.mix.js 下通过 Laravel Mix 进行编译:

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .styles([
        'resources/css/reset.css',
        'public/css/app.css',
        'node_modules/muse-ui/dist/muse-ui.css'
    ], 'public/css/app.css');

添加前端依赖到 package.json

接下来,我们把前端代码中涉及到的所有新的依赖库添加到项目根目录下的 package.json 中:

"devDependencies": {
    "axios": "^0.18",
    "cross-env": "^5.1",
    "file-loader": "^4.2.0",
    "jquery": "^3.2",
    "laravel-mix": "^4.0.7",
    "lodash": "^4.17.5",
    "muse-ui": "^3.0.2",
    "popper.js": "^1.12",
    "resolve-url-loader": "^2.3.1",
    "sass": "^1.23.1",
    "sass-loader": "7.*",
    "socket.io-client": "^2.3.0",
    "stylus": "^0.54.7",
    "stylus-loader": "^3.0.2",
    "timers": "^0.1.1",
    "url-loader": "^2.2.0",
    "vivus": "^0.4.5",
    "vue": "^2.6.10",
    "vue-cropper": "^0.4.9",
    "vue-picture-preview": "^1.3.0",
    "vue-router": "^3.1.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.6.10",
    "vuex": "^3.1.1",
    "xss-filters-es6": "^1.0.0"
}

然后运行 npm install 安装所有前端依赖库。

当然,以上所有前端代码迁移和调整都已经提交到 Github 仓库,你可以直接从这里下载对应的资源到本地:https://github.com/nonfu/webchat

编译前端资源

最后,在项目根目录下运行 npm run dev 通过 Laravel Mix 来编译上述所有前端资源:

通过 Laravel Mix 编译前端资源

编译成功后,接下来,我们将着手调试前端界面与后端接口的交互,这些放到后续教程去逐一讲解。

上一篇: 基于 Laravel + Swoole + Vue 搭建实时在线聊天室(三):后台 WebSocket 服务器实现

下一篇: 基于 Laravel + Swoole + Vue 搭建实时在线聊天室(五):Homestead 开发环境初始化