Menu

29. Vue 消息提示

本节说明

  • 对应视频第 29 小节:Flash Messaging With Vue

本节内容

在之前的章节我们已经完成了话题的创建、删除、回复的功能,但是在动作执行成功之后没有消息提示,这样对用户体验不好,本节我们将消息提示显示出来。

安装依赖

我所使用的电脑的操作系统为 Windows 10,采用本站推荐的 开发环境部署 方案,并且可以科学上网。

注:开发人员很有必要使用 Google,探索墙外自由广阔的世界

我们将使用 Yarn 来安装 npm 依赖。依次执行以下命令:

$  yarn config set registry http://registry.cnpmjs.org
$ yarn install --no-bin-links

接下来打开 pakage.json ,去掉四处 cross-env

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  .
  .
}

接着运行以下命令即可:

$ npm run watch-poll

或者运行:

$ npm run dev

watch-poll 会在你的终端里持续运行,监控 resources 文件夹下的资源文件是否有发生改变。在watch-poll 命令运行的情况下,一旦资源文件发生变化,Webpack 会自动重新编译。

注意:在后面的课程中,我们需要保证 npm run watch-poll 一直处在执行状态中。

正常运行的界面应类似:
file

注:如果你学习过本站的进阶教程,并且也是 Windows 10 系统,那么你很有可能在安装依赖这一步遭遇过重重困难。不要害怕,因为遭遇的越多,知道的也会越多!相关讨论见 https://laravel-china.org/topics/7619/resolved-laravel-mix-still-try-installing-heavy-please-help-look-laoniao-thank-you

Vue 消息模板

Laravel 自带了一个 Vue 的example.vue文件,我们将其重命名为Flash.vue,并修改组件内容:
forum\resources\assets\js\components\Flash.vue

<template>
    <div class="alert alert-warning alert-flash" role="alert">
        <strong>Success!</strong>{{ body }}
    </div>
 </template>

<script>
    export default {
        props:['message'],
        data(){
            return {
                body : this.message
            }
        }
    };
</script>

<style>
    .alert-flash{
        position: fixed;
        right: 25px;
        bottom: 25px;
    }
</style>

注册组件:
forum\resources\assets\js\app.js


/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('flash', require('./components/Flash.vue'));

const app = new Vue({
    el: '#app'
});

在应用程序中使用组件,你只需要简单的将其放到你的 HTML 模板之中:
forum\resources\views\layouts\app.blade.php

.
.
<div id="app">
    @include('layouts.nav')

    @yield('content')

    <flash message="Tempory message"></flash>
</div>
.
.

注:每次修改 Vue 组件后都应该运行 npm run dev 命令。或者,你可以使用 npm run watch 命令来监控并在每次文件被修改时自动重新编译组件

现在访问页面:
file

Vue 调试工具

vue-devtools 是一款基于 chrome 游览器的插件,用于调试 vue 应用,这可以极大地提高我们的调试效率。从 chrome 商店直接下载安装:
file
安装完成之后可以在调试模式下找到 Vue 调试工具:
file

完善组件

我们在完成动作后将消息存到Session中,然后在页面显示消息,并且在 3 秒消失。这是我们想要达到的效果。我们首先简单为组件加上show属性,再用 vue-devtools 进行调试:
forum\resources\assets\js\components\Flash.vue

<template>
    <div class="alert alert-success alert-flash" role="alert" v-show="show">
        <strong>Success!</strong>{{ body }}
    </div>
 </template>

<script>
    export default {
        props:['message'],
        data(){
            return {
                body : this.message,
                show:false
            }
        }
    };
</script>

<style>
    .alert-flash{
        position: fixed;
        right: 25px;
        bottom: 25px;
    }
</style>

我们设置了show属性为false,所以再次刷新页面,组件会处于不可见状态:
file
再打开 Chrome 浏览器开发者工具栏的 Vue 调试工具,点击Flash赋予变量:
file
再在控制台输入以下代码,设置组件可见:

$vm0.show=true

file
再次修改组件:
forum\resources\assets\js\components\Flash.vue

<template>
    <div class="alert alert-success alert-flash" role="alert" v-show="show">
        <strong>Success!</strong>{{ body }}
    </div>
 </template>

<script>
    export default {
        props:['message'],
        data(){
            return {
                body : this.message,
                show:false
            }
        },

        created(){
            if(this.message){
                this.body = this.message;
                this.show = true;

                setTimeout(() => {
                    this.show = false;
                },3000);
            }
        }
    };
</script>

<style>
    .alert-flash{
        position: fixed;
        right: 25px;
        bottom: 25px;
    }
</style>

刷新页面,会看到消息区域出现,并且在 3 s后消失。最终的版本如下:
forum\resources\assets\js\components\Flash.vue

<template>
    <div class="alert alert-success alert-flash" role="alert" v-show="show">
        <strong>Success!</strong>{{ body }}
    </div>
 </template>

<script>
    export default {
        props:['message'],

        data(){
            return {
                body : '',
                show:false
            }
        },

        created(){
            if(this.message){
                this.flash(this.message);
            }

            window.events.$on('flash',message => this.flash(message));
        },

        methods:{
            flash(message){
                this.body = message;
                this.show = true;

                this.hide();
            },

            hide(){
                setTimeout( () => {
                   this.show = false;
                },3000);
            }
        }
    };
</script>

<style>
    .alert-flash{
        position: fixed;
        right: 25px;
        bottom: 25px;
    }
</style>

我们将显示和隐藏消息组件封装成flashshow方法,同时我们使用window.events.$on来监听页面发生的事件,以后如果需要其他动作的提示,只需要重写flash就可以再次调用showhide方法,达到出现和消失消息组件的目的。我们传递属性到window.events
forum\resources\assets\js\bootstrap.js

.
.
window.Vue = require('vue');

window.events = new Vue();

window.flash = function (message) {
    window.events.$emit('flash',message);
};

注意:默认情况下window.Vue = require('vue')这行代码会出现在 forum\resources\assets\js\app.js 文件require('./bootstrap')的下面一行。那样我们在加载Vue前就调用了Vue,会出现报错,所以我把它从app.js文件移到了这里。

接下来我们在创建话题跟回复后都在Session中存入提示消息:
forum\app\Http\Controllers\ThreadsController.php

.
.
public function store(Request $request)
{
    $this->validate($request,[
       'title' => 'required',
        'body' => 'required',
        'channel_id' => 'required|exists:channels,id'
    ]);

    $thread = Thread::create([
        'user_id' => auth()->id(),
        'channel_id' => request('channel_id'),
        'title' => request('title'),
        'body' => request('body'),
    ]);

    return redirect($thread->path())
        ->with('flash','Your thread has been published!');
}
.
.

forum\app\Http\Controllers\RepliesController.php

.
.
public function store($channelId,Thread $thread)
{
    $this->validate(request(),['body' => 'required']);

    $thread->addReply([
        'body' => request('body'),
        'user_id' => auth()->id(),
    ]);

    return back()->with('flash','Your reply has been left.');
}
.

在页面取出Session
forum\resources\views\layouts\app.blade.php

.
.
<body>
    <div id="app">
        @include('layouts.nav')

        @yield('content')

        <flash message="{{ session('flash') }}"></flash>
    </div>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
</body>
.

现在所有的工作都完成了,我们在应用中测试一下。首先创建话题:
file
接着创建回复:
file
我们也可以利用 Vue 调试工具进行调试:
file

本文章首发在 Laravel China 社区
上一篇 下一篇
讨论数量: 1
发起讨论


fire
yarn install --no-bin-links 报错
0 个点赞 | 1 个回复 | 问答