Laravel进阶系列笔记--(二十一)Laravel 广播-基于Pusher私有频道界面的快速搭建-2

作者: 温新

分类: 【Laravel】

阅读: 1644

时间: 2021-08-31 05:37:37

作者:温新

时间:2021-07-31

hi,我是温新,一名PHPer

本系列采用Laravel8.x演示。

在正式记录之前,请先调整好项目初始化的配置(如配置路由、数据库等),这里不进行记录。

第一步:配置

1)打开广播

// config/app.php
// 取消注释
App\Providers\BroadcastServiceProvider::class,

2)修改广播驱动

// .env
BROADCAST_DRIVER=pusher

3)配置pusher

// .env
PUSHER_APP_ID=你的ID
PUSHER_APP_KEY=你的KEY
PUSHER_APP_SECRET=你的SECRET
PUSHER_APP_CLUSTER=ap3

4)配置广播连接

// config/boradcasting.php
'pusher' => [
    'options' => [
        // 其它不变,新增如下配置
        'curl_options' => [
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
        ]
    ],
],

第一步:创建模型与迁移文件并生成相关表

第一步:创建模型与迁移文件

// 主题模型
php artisan make:model Topic -a
// 主题讨论模型
php artisan make:model Discussion -a
//主题与用户之间的关系表
php artisan make:migration create_topic_user_table --create=topic_user

模型关系理解:

1)用户与主题讨论是一对多关系,一个用户可以发表N次主题讨论的内容;

2)用户于主题是多对多关系;

第二步:修改迁移文

// CreateTopicsTable 主题表迁移文件
Schema::create('topics', function (Blueprint $table) {
    $table->id();
    $table->string('name')->comment('主题名');
    $table->timestamps();
});
// 主题讨论表
Schema::create('discussions', function (Blueprint $table) {
    $table->id();
    $table->unsignedInteger('user_id')->index()->comment('用户ID');
    $table->unsignedInteger('topic_id')->index()->comment('主题ID');
    $table->string('content')->comment('主题讨论内容');
    $table->timestamps();
});
// 用户与主题中间表
Schema::create('topic_user', function (Blueprint $table) {
    $table->id();
    $table->unsignedInteger('user_id')->index()->comment('用户ID');
    $table->unsignedInteger('topic_id')->index()->comment('主题ID');
    $table->timestamps();
});

第三步:生成迁移文件

php artisan migrate

第二步:定义模型间的关系

1)定义模型关系

// Models/User.php

// 用户与主题的关系
public function topics()
{
    return $this->belongsToMany(Topic::class,'topic_user','user_id','topic_id','id','id');
}

// 用户与主题讨论内容的关系
public function discussions()
{
    return $this->hasMany(Discussion::class,'user_id','id');
}
// Discussion.php
protected $guarded = [];

// 一个讨论的内容属于一个用户
public function user()
{
    return $this->belongsTo(User::class,'user_id','id');
}

// 一个主题也是属于一个用户
public function topic()
{
    return $this->belongsTo(Topic::class,'user_id','id');
}
// Topic.php
protected $guarded = [];

// 主题与用户为多对多关系
public function users()
{
    return $this->belongsToMany(User::class,'topic_user','user_id','topic_id','id','id');
}
// 主题与主题讨论的内容为一对多关系
public function discussions()
{
    return $this->hasMany(Discussion::class,'topic_id','id');
}

2)填充数据。为了方便,手动填充数据

// topics表
id		name
1		PHP技术讨论
2		Vue技术讨论

// topic_user表
id	user_id	topic_id
1	1		1
2	1		2
3	2		1
// users表
id	name	password	email
1	李四				lisi@qq.com
2	王五				wangwu@qq.com

第三步:定义路由与控制器方法

1)定义路由

// web.php
Route::get('topic', 'TopicController@index');
Route::get('topic/{topic}', 'TopicController@show');

2)修改控制器方法

// TopicController.php
// 获取主题
public function show(Topic $topic)
{
    return view('topic.show', compact('topic')); 
}

3)修改模型方法

// Models/Topic.php
public function discussions()
{
    return $this->hasMany(Discussion::class,'user_id','id')->with('user');
}

4)新增静态文件

文件:topic/show.blade.php

@extends('layouts.app')

@section('content')
    <topic :topic="{{ $topic }}"></topic>
@endsection

第五步:改造组件

// resources/js/components/TopicComponent.vue

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <h3>{{ topic.name }}</h3>
                <hr>
                <div v-for="dis in this.discussions">
                    <h3>{{  dis.user_id }}</h3>
                    <p>{{ dis.content }}</p>
                </div>
                <hr>
                <form action="#" @submit.prevent="createDis">
                    <textarea v-model="talk" name="" class="form-control" cols="30" rows="6"></textarea>
                    <button type="submit" class="btn btn-primary float-right px-2 m-1">发布</button>
                </form>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    props:['topic'],
    data () {
        return {
            // 主题讨论的内容
            talk:'',
            // 数据库获取主题讨论的内容
            discussions:[],
        }
    },
    mounted() {
        // 对应主题讨论的数据
       this.discussions = this.topic.discussions;
    },
    methods:{
        createDis() {
            this.talk = '';
        }
    }
}
</script>

路由访问方式为域名/topic/1

需要注意的是,通过传入数据$topic只是把该主题数据传入了进来;在mounted中使用了discussions,该属性在$topic中是没有了,只处是通过动态属性的方式获取一对多数据,也就是Topic模型中的discussions方法,以动态属性的方式调用。

由于前面使用的是npm run watch,因此修改vue组件后会自动编译。

我是温新

每天进步一点点,就一点点

请登录后再评论