Laravel UI 推出之前,其主要功能之一就是预支持defi晚上 Vue.js 从 Laravel v5.3 到 v6。 Vue 是用于构建用户界面的现代 JavaScript 前端框架。
以下是使用 Laravel 和 Vue 为您的项目创建完整工作流的一些主要好处:
源代码合并到一个项目中,而不是后端和前端单独的项目
安装配置简单
一个发行版可以同时管理两个框架
一 单页申请 (简称SPA)从网络服务器动态加载新数据到网页中,而无需刷新整个页面。
使用 SPA 的热门网站示例包括 gmail.com 和 youtube.com——换句话说,SPA 在很大程度上无处不在。 您可能每天使用的大多数管理仪表板都是使用 SPA 构建的。
SPA的优势:
用户体验更灵活
在浏览器中缓存数据
快速加载时间
SPA的缺点:
可能会损害 SEO(搜索引擎优化)
潜在的安全问题
消耗大量浏览器资源
这篇文章将演示如何开发一个允许用户注册帐户和添加任务的待办事项应用程序。
本教程使用 Laravel 9,需要 PHP 8.1 和 Vue 3; 我们还需要安装 PHP 和 NGINX。
我们从以下命令开始:
composer create-project --prefer-dist laravel/laravel laravel-vue-combo
接下来,我们将安装 JavaScript 依赖项。
npm install
在我们将 Vue 添加到我们的项目之前,我们需要安装一些包。
此外,必须安装 plugin-vue,因为 Laravel 9 附带了 Vite,而不是 webpack-mix,后者是以前的 Laravel JavaScript 捆绑器。 让我们现在就开始做吧:
npm install vue@next vue-loader@next @vitejs/plugin-vue
打开名为的文件 vite.config.js
并添加 vue()
配置:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue(),
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
编辑 Vue 3 应用程序的 app.js 文件和引导代码片段:
require('./bootstrap');
import {createApp} from 'vue'
import App from './App.vue'
createApp(App).mount("#app")
创建一个名为 App.vue
并添加以下内容:
<template>
<h1> Hello, Vuejs with Laravel </h1>
</template>
<script>
export default {
setup() {
}
}
</script>
最后,打开文件 welcome.blade.php
位于文件夹中 resources/views
并添加以下内容:
<!DOCTYPE html>
<html>
<head>
....
@vite('resources/css/app.css')
</head>
<body>
<div id="app"></div>
@vite('resources/js/app.js')
</body>
</html>
要预览我们的应用程序,我们需要在两个不同的终端/命令行上启动我们的 Vue 应用程序和 Laravel 服务器:
npm run dev
php artisan serve
要创建我们的待办事项应用程序,我们需要创建其他文件。 vue会创建多个页面,主要有:
要与 Laravel 端点通信,我们需要安装 Axios:
npm install axios
使用包 vue-router
,有多种路由策略可以在Vue中使用; 这些策略也被称为 history models
.
当用户请求 route
比如 http://localhost:8000/home,它会在页面刷新时返回 404 错误,我们可以依靠 Laravel 检测任何回退路由,然后提供包含我们应用程序的 Blade 文件。
为此,我们将使用 HTML5 模式:
Route::get('/{vue_capture?}', function() {
return view('welcome');
})->where('vue_capture', '[\/\w\.-]*');
import {createRouter, createWebHistory} from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: () => import('./pages/Login.vue')
},
{
path: '/register',
component: () => import('./pages/Register.vue')
},
{
path: '/home',
component: () => import('./pages/Home.vue')
}
],
})
在这个例子中,我们使用 Laravel 圣殿,然后将令牌保存在本地存储中。
对于成功的其他请求,令牌被合并到标头中,这将允许发出请求的用户被 Laravel 识别。
以下是两者的相关代码块:
<!--Login.vue-->
<template>
<div class="mx-auto w-4/12 mt-10 bg-blue-200 p-4 rounded-lg">
<div
class="bg-white shadow-lg rounded-lg px-8 pt-6 pb-8 mb-2 flex flex-col"
>
<h1 class="text-gray-600 py-5 font-bold text-3xl"> Login </h1>
<ul class="list-disc text-red-400" v-for="(value, index) in errors" :key="index" v-if="typeof errors === 'object'">
<li>{{value[0]}}</li>
</ul>
<p class="list-disc text-red-400" v-if="typeof errors === 'string'">{{errors}}</p>
<form method="post" @submit.prevent="handleLogin">
<div class="mb-4">
<label
class="block text-grey-darker text-sm font-bold mb-2"
for="username"
>
Email Address
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
id="username"
type="text"
v-model="form.email"
required
/>
</div>
<div class="mb-4">
<label
class="block text-grey-darker text-sm font-bold mb-2"
for="password"
>
Password
</label>
<input
class="shadow appearance-none border border-red rounded w-full py-2 px-3 text-grey-darker mb-3"
id="password"
type="password"
v-model="form.password"
required
/>
</div>
<div class="flex items-center justify-between">
<button
class="bg-blue-500 hover:bg-blue-900 text-white font-bold py-2 px-4 rounded"
type="submit"
>
Sign In
</button>
<router-link
class="inline-block align-baseline font-bold text-sm text-blue hover:text-blue-darker"
to="register"
>
Sign Up
</router-link>
</div>
</form>
</div>
</div>
</template>
export default {
setup() {
const errors = ref()
const router = useRouter();
const form = reactive({
email: '',
password: '',
})
const handleLogin = async () => {
try {
const result = await axios.post('/api/auth/login', form)
if (result.status === 200 && result.data && result.data.token) {
localStorage.setItem('APP_DEMO_USER_TOKEN', result.data.token)
await router.push('home')
}
} catch (e) {
if(e && e.response.data && e.response.data.errors) {
errors.value = Object.values(e.response.data.errors)
} else {
errors.value = e.response.data.message || ""
}
}
}
return {
form,
errors,
handleLogin,
}
}
}
Ercole Palmeri
你也可能对此有兴趣 ...