Laravel 5.5 + Vue 开发单页应用

上次我用 laravel5.3 + Vue 开发了一个简单的单页应用,这次我打算将其升级到 laravel5.5,在升级的过程中,做一下记录,其源码放在 github 上面,源码地址

 

开发环境

软件包版本
Laravel5.5
Vue> 2.5.7
axios> 0.17
vue-router> 3.0.1
vuex> 3.0.1
 

安装

# 安装 laravel
composer create-project --prefer-dist laravel/laravel laravel-vue "5.5.*" # 安装前端依赖包 npm install

安装完之后,为了便于开发,使用热更新模式。

# 在 webpack.mix.js 中添加配置
mix.browserSync({ proxy: 'localhost:8000' }); # 执行 `php artisan serve` php artisan serve # 执行 npm run watch npm run watch

打开浏览器访问 http://localhost:3000 就可以看到 laravel 的欢迎页面了

 

目标

开发三个页面,首页,列表,详情,相对应准备 3 个 api 接口

 

migration

php artisan make:migration news --create=news
# database/migrations/create_news.php
Schema::create('news', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('content'); $table->integer('is_recommend')->default(0); $table->timestamps(); });
 

model

这里使用命令生成 model 文件,编辑对应的文件内容。

php artisan make:model News
# app/News.php
namespace App; use Illuminate\Database\Eloquent\Model; class News extends Model { public $fillable = ['title', 'content']; }
 

controller

生成控制器,在控制器中定义三个接口对应的方法。

php artisan make:controller NewsController
# app/Http/Controllers/NewsController
<?php
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\News; class NewsController extends Controller { /** * 推荐列表 */ public function recommend() { $list = News::where('is_recommend', 1)->get(); foreach ($list as $key => $value) { $list[$key]->created = $list[$key]->created_at->diffForHumans(); } return $list; } /** * 新闻列表 */ public function index() { $list = News::get(); foreach ($list as $key => $value) { $list[$key]->created = $list[$key]->created_at->diffForHumans(); } return $list; } /** * 新闻详情 */ public function show($id) { $row = News::findOrFail($id); return $row; } }
 

router

定义 api 的接口路由,在 routes/api.php 文件中定义。

# routes/api.php
Route::get('/news', 'NewsController@index'); Route::get('/news/recommend', 'NewsController@recommend'); Route::get('/news/{id}', 'NewsController@show');
 

Vue单页

到这里我们准备工作已经完毕,接下来正式开发 Vue 的单页应用,在开发单页应用中,对应 Route ApiVuex Components 这些,下面我们就来定义这些。

首先在首页引入对应的 app.css 和 app.js 文件。

# resource/vies/welcome.blade.php
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="csrf-token" content="@{{ csrf_token }}"> <title>Laravel & Vue</title> <link rel="stylesheet" type="text/css" href="/css/app.css"> </head> <body> <div id="app"> <nav class="navbar navbar-inverse"> <div class=" container"> <div class="navbar-header"> <a class="navbar-brand" href="/">LaravelVue</a> </div> </div> </nav> <div class="container main"> <router-view /> </div> </div> <script type="text/javascript" src="/js/app.js"></script> </body> </html>
 

配置启动 app.js

应用对应的入口文件是 app.js,所以在这个入口文件中,我们实例化 Vue 实例,初始化和加载所需的组件。

# resource/assets/js/app.js
require('./bootstrap'); window.Vue = require('vue'); import VueRouter from 'vue-router'; Vue.use(VueRouter); import store from './store/'; // vuex 数据存储所需对象 import routes from './routes'; // 路由配置文件 // 实例化路由 const router = new VueRouter({ routes }) var vm = new Vue({ store, router }).$mount('#app');
 

路由

前端页面主要有 3 个路由,如下

# resource/assets/js/routes.js
export default[ { path: '', redirect: '/index' }, { path: '/index', component: require('./page/App.vue') }, { path: '/list', component: require('./page/List.vue') }, { path: '/detail/:id', component: require('./page/Detail.vue') } ];
 

Vuex

Vuex 集中式存储管理应用的所有组件的状态,这里使用的是多模块方式记录数据。

# resource/assets/js/store/index.js import Vue from 'vue'; import Vuex from 'vuex'; import news from './news'; Vue.use(Vuex); export default new Vuex.Store({ // 可以设置多个模块 modules: { news } }); # resource/assets/js/store/news.js import api from '../api'; export default{ state: { recommend: [], // 推荐 lists: [], // 列表 detail: {} // 详情 }, mutations: { // 注意,这里可以设置 state 属性,但是不能异步调用,异步操作写到 actions 中 SETRECOMMEND(state, lists) { state.recommend = lists; }, SETLISTS(state, lists) { state.lists = lists; }, SETDETAIL(state, detail) { state.detail = detail; } }, actions: { getNewsDetail({commit}, id) { // 获取详情,并调用 mutations 设置 detail api.getNewsDetail(id).then(function(res) { commit('SETDETAIL', res.data); document.body.scrollTop = 0; }); }, getNewsRecommend({commit}) { api.getNewsRecommend().then(function(res) { commit('SETRECOMMEND', res.data); }); }, getNewsLists({commit}) { api.getNewsLists().then(function(res) { commit('SETLISTS', res.data); }); } } }
 

api

我们在这里定义前端请求数据 api,这里使用的是 axios 包来请求数据,具体用法参考文档。

# resource/assets/js/api.js
import axios from 'axios' export default { // 首页推荐接口 getNewsRecommend: function (params) { return axios.get('api/news/recommend', { params: params }) }, // 列表接口 getNewsLists: function (params) { return axios.get('api/news', { params: params }) }, // 详情接口 getNewsDetail: function (id) { return axios.get('api/news/' + id) } }
 

page

我们在这里定义组件页面,将其页面放到 page 目录下面,Vue 定义组件的方式参考文档。
三个页面的具体写法定义如下:

# resource/assets/js/page/App.vue
<template> <div class="panel panel-default"> <div class="panel-heading">新闻推荐 <router-link to="/list" class="pull-right">更多</router-link> </div> <ul class="list-group"> <li class="list-group-item" v-for="row in recommend"> <router-link :to="{path:'/detail/' + row.id}"> {{ row.title }} </router-link> <span class="pull-right">{{ row.created }}</span> </li> </ul> </div> </template> <script> import { mapState, mapActions } from 'vuex'; export default({ // 映射 vuex 上面的属性 computed: mapState({ recommend: state => state.news.recommend }), created() { // 获取推荐列表 this.getNewsRecommend(); }, methods: { // 映射 vuex 对象上的方法 ...mapActions([ 'getNewsRecommend' ]) } }); </script> # resource/assets/js/page/List.vue <template> <div class="panel panel-default"> <div class="panel-heading">新闻列表</div> <ul class="list-group"> <li class="list-group-item" v-for="row in lists"> <router-link :to="{path:'/detail/' + row.id}"> <span class="label label-success" v-if="row.is_recommend">推荐</span

转载于:https://www.cnblogs.com/mouseleo/p/10344695.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值