Vue 组件未在 laravel 项目中实现?
2022-04-03
428
我尝试让我的 vue 组件在 laravel blade 文件中呈现来自数据库的消息,但由于某种原因,它没有呈现。我使用此 Github repo https://github.com/kevilondo/group-chat 作为示例,将其实现到我的项目中。现在它正在提交到数据库,因为我可以看到数据库中的数据,并且它发布得很好,但是消息没有显示。
顺便说一下,我在 vue js 方面的经验非常有限。
我在控制台中收到的错误是 Uncaught TypeError:无法读取未定义的属性(读取“原型”)。
这是我的 app.js 文件的样子:
import Alpine from "alpinejs";
window.Alpine = Alpine;
const { default: axios } = require('axios');
const { default: Echo } = require('laravel-echo');
require('./bootstrap');
Alpine.start();
window.Vue = require('vue');
Vue.prototype.$userId = document.querySelector("meta[name='user-id']").getAttribute('content');
import VueChatScroll from 'vue-chat-scroll'
Vue.use(VueChatScroll)
Vue.component('message', require('./components/message.vue').default);
const app = new Vue({
el: '#app',
mounted(){
//we assign the value of this to this variable in order to access the value of chat inside data inside our http request
var vm = this
//we get the group id in the url
const url = window.location.href;
const groupId = url.split("/").slice(-1)[0];
vm.groupId = groupId;
axios.get('/show_messages/' + groupId)
.then(res => {
//push every message one by one
res.data.messages.map(message => {
vm.chat.push(message)
//console.log(vm);
});
})
.catch(error => {
console.log(error)
})
window.Echo.private('message-channel')
.listen('MessageEvent', (e) => {
vm.chat.push(e.message)
});
},
data: {
message: '',
groupId: null,
chat: [
],
},
methods: {
send_message (event) {
event.preventDefault();
let token = document.head.querySelector('meta[name="csrf-token"]');
axios.post('/send_message/'+ this.groupId, {message: this.message}, {'X-CSRF-TOKEN': token})
.then(res => {
this.message = ''
})
.catch(error => {
console.log(error)
})
}
}
});
这是引导文件的样子:
window._ = require('lodash');
try {
window.Popper = require('popper.js').default;
window.$ = window.jQuery = require('jquery');
require('bootstrap');
} catch (e) {}
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true
});
这是 Message.vue 的样子:
<template>
<div v-if="user_id !== this.$userId" class="container card bg-info mb-4 float-start" style="width: 58%;">
<p>{{message}}</p>
<p> <span class="text-danger">{{name}}</span> <small>{{formatDate}}</small></p>
</div>
<div v-else class="container card bg-default mb-4 float-end" style="width: 58%;">
<p>{{message}}</p>
<p> <span class="text-danger">You</span> <small>{{formatDate}}</small></p>
</div>
</template>
<script>
export default {
props: ['user_id', 'userLoggedIn', 'name', 'message', 'created_at'],
mounted() {
//
},
computed: {
formatDate(){
//we convert the text into a date
let dateAndTime = new Date(this.created_at);
let year = dateAndTime.getFullYear();
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
let month = months[dateAndTime.getMonth()];
let day = dateAndTime.getDate();
let time = dateAndTime.getHours() + ':' + dateAndTime.getMinutes();
return `${day} ${month} ${year} ${time}`
}
}
}
</script>
show.blade.php 的相关部分:
<div class="card-body container">
<div class="message-container mb-5" id="message-container" style="overflow-y: scroll; height:400px;" v-chat-scroll>
<message v-for="(message, id) in chat "
v-bind:key="id"
v-bind:message = "message.message"
v-bind:name = "message.user.name"
v-bind:user_id = "message.user.id"
v-bind:created_at = "message.created_at"
>
</message>
</div>
<form action="/send_message/{{$group->id}}" method="post" v-on:submit='send_message'>
@csrf
<textarea name="message" id="message" v-model="message" class="col-md-12 form-control @error('message') is-invalid @enderror" cols="20" rows="5"></textarea>
@error('message')
<span class="invalid-feedback" role="alert">
<strong>{{$message}}</strong>
</span>
@enderror
<button class="btn btn-primary" type="submit">Send message</button>
</form>
app.blade.php 文件:
<body class="font-sans antialiased">
<div id="app">
<div class="min-h-screen bg-gray-100">
@include('layouts.navigation')
<!-- Page Heading -->
<header class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
</div>
</header>
<!-- Page Content -->
<main>
@yield('content')
</main>
</div>
{{-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>--}}
</div>
<script src="{{asset('js/bootstrap.js')}}"></script>
<script src="{{asset('js/app.js')}}"></script>
</body>
控制器方法
“:
public function show_messages($id)
{
$group = Group::find($id);
$messages = $group->group_messages()->with(['group', 'user'])->get();
$user_loggedIn = auth()->user();
return ['messages' => $messages, 'user_loggedIn' => $user_loggedIn];
}
2个回答
我在控制台上发现了一些错误。您可以执行以下操作来清除它
- 在 app.js 文件中从默认导入 Vue
window.Vue = require('vue').default;
- 在 app.blade.php 上删除导入 bootstrap.js,因为已经在 app.js 上使用
{{-- Remove next line --}}
<script src="{{asset('js/bootstrap.js')}}"></script>
<script src="{{asset('js/app.js')}}"></script>
- 在 MessageController.php 上更新 show_messages 方法为
public function show_messages($id)
{
$group = Group::find($id);
$messages = $group->messages()->with(['group', 'user'])->get();
$user_loggedIn = auth()->user();
return ['messages' => $messages, 'user_loggedIn' => $user_loggedIn];
}
Suhail Kawsara
2022-04-11
我认为 GitHub repo 中的这行代码造成了问题,因为它仅在用户登录时可用。
@if (!Auth::guest())
<meta name="user-id" content="{{ Auth::user()->id }}">
@endif
如果用户并非始终登录,则可以使用可选的类似代码:
<meta name="user-id" content="{{ optional(Auth::user())->id }}">
Shrey
2022-04-07