开发环境:
Homestead + Laravel5.3 + vue2 + vue-resource1 + vue-router2 + vuex2
源码放在 github
上面,源码地址
环境安装就不做介绍了,由于 5.3
自带 vue2
和 vue-resource
,但是需要安装 vue-route
和 vuex
。
在 package.json
中添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
…
“devDependencies”: {
“bootstrap-sass”: “^3.3.7”,
“extract-text-webpack-plugin”: “^2.0.0-beta.4”,
“gulp”: “^3.9.1”,
“jquery”: “^3.1.0”,
“laravel-elixir”: “^6.0.0-9”,
“laravel-elixir-vue-2”: “^0.2.0”,
“laravel-elixir-webpack-official”: “^1.0.2”,
“lodash”: “^4.16.2”,
“vue”: “^2.0.1”,
“vue-resource”: “^1.0.3”,
// 添加
“vue-router”: “^2.0.1”,
“vuex”: “^2.0.0”
}
…
执行 npm install 安装
|
介绍下开发的需求,主要有三个页面:
- 首页展示推荐新闻
- 新闻列表
- 新闻详情
入口文件 app.js
resources/asserts/js/app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import Vue from ‘vue’;
import VueResource from ‘vue-resource’;
Vue.use(VueResource);
import VueRouter from ‘vue-router’;
Vue.use(VueRouter);
import store from ‘./store/’; // vuex 数据存储所需对象
import routes from ‘routes’; // 路由配置文件
// 实例化路由
const router = new VueRouter({
routes
});
// 实例化 Vue
var vm = new Vue({
store,
router
}).$mount(‘#app’);
|
数据vuex
vuex 我们使用多模块的开发模式,这在项目中设计十分有必要的,如果把所有的数据一个实例上面,管理显得还是十分的混乱。
resources/asserts/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
|
import Vue from ‘vue’;
import Vuex from ‘vuex’;
import news from ‘./news’;
Vue.use(Vuex);
export default new Vuex.Store({
// 可以设置多个模块
modules: {
news
}
});
|
书写 news
模块代码
resources/asserts/store/news.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
import api from ‘../api’; // 主要是异步调用接口文件,下面有介绍
export default{
state: {
recommend: [], // 存储推荐列表
lists: [], // 存储列表
detail: {} // 存储详情
},
mutations: {
// 注意,这里可以设置 state 属性,但是不能异步调用,异步操作写到 actions 中
SETRECOMMEND(state, recommend) {
state.recommend = recommend;
},
SETLISTS(state, lists) {
state.lists = lists;
},
SETDETAIL(state, detail) {
state.detail = detail;
}
},
actions: {
GETDETAIL({commit}, id) {
// 获取详情,并调用 mutations 设置 detail
api.getNewsDetail(id).then(function(res) {
commit(‘SETDETAIL’, res.data);
document.body.scrollTop = 0;
});
},
GETRECOMMEND({commit}) {
// 获取推荐,并调用 mutations 设置 recommend
api.getNewsRecommend().then(function(res) {
commit(‘SETRECOMMEND’, res.data);
});
},
GETLISTS({commit}) {
// 获取列表,并调用 mutations 设置 lists
api.getNewsLists().then(function(res) {
commit(‘SETLISTS’, res.data);
});
}
}
};
|
看到上面的代码中引入了 api
,我将接口的请求全部放到 api.js
中,便于管理,其实这里也可以分成模块。
resources/asserts/api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
import Vue from ‘vue’;
import VueResource from ‘vue-resource’;
Vue.use(VueResource);
// 设置 Laravel 的 csrfToken
Vue.http.interceptors.push((request, next) => {
request.headers.set(‘X-CSRF-TOKEN’, Laravel.csrfToken);
next();
});
const API_ROOT = ”; // 可以根据自己的开发环境设置
export default({
// 首页推荐信息
getNewsRecommend: function() {
return Vue.resource(API_ROOT + ‘/news’).get();
},
// 列表信息
getNewsLists: function() {
return Vue.resource(API_ROOT + ‘/newslist’).get();
},
// 详情
getNewsDetail: function(id) {
return Vue.resource(API_ROOT + ‘/newsdetail/’ + id).get();
}
});
|
路由信息 routes.js
resources/asserts/js/routes.js
1
2
3
4
5
6
|
export default[
{ path: ”, redirect: ‘/index’ },
{ path: ‘/index’, component: require(‘./page/App.vue’) },
{ path: ‘/newslist’, component: require(‘./page/List.vue’) },
{ path: ‘/newsdetail/:id’, component: require(‘./page/Detail.vue’) }
];
|
组件 App.vue
resources/asserts/js/page/App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<template>
<div>
<h3>首页推荐</h3>
<ul class=“list-group”>
<li class=“list-group-item”
v-for=“row in recommend”>
<router-link :to=“{path:’/newsdetail/’ + row.id}”>
{{ row.title }}
</router-link>
<li class=“list-group-item”>
<router-link to=“/newslist”>更多</router-link>
</li>
</li>
</ul>
</div>
</template>
<script>
import { mapState, mapActions } from ‘vuex’;
export default({
// 映射 vuex 上面的属性
computed: mapState({
recommend: state => state.news.recommend
}),
created() {
// 获取推荐列表
this.GETRECOMMEND();
},
methods: {
// 映射 vuex 对象上的方法
…mapActions([
‘GETRECOMMEND’
])
}
});
</script>
|
组件 List.vue
resources/asserts/js/page/List.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<template>
<div>
<h3>列表信息</h3>
<ul class=“list-group”>
<li class=“list-group-item”
v-for=“row in lists”>
<router-link :to=“{path:’/newsdetail/’ + row.id}”>
{{ row.title }}
</router-link>
</li>
</ul>
</div>
</template>
<script>
import { mapState, mapActions } from ‘vuex’;
export default({
computed: mapState({
lists: state => state.news.lists
}),
created() {
this.GETLISTS();
},
methods: {
…mapActions([
‘GETLISTS’
])
}
});
</script>
|
组件 Detail.vue
resources/asserts/js/page/Detail.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<template>
<div>
<table class=“table table-bordered”>
<tr>
<td width=“20%”>ID</td>
<td>{{ detail.id }}</td>
</tr>
<tr>
<td width=“20%”>标题</td>
<td>{{ detail.title }}</td>
</tr>
<tr>
<td width=“20%”>内容</td>
<td>{{ detail.content }}</td>
</tr>
<tr>
<td width=“20%”>创建时间</td>
<td>{{ detail.created_at }}</td>
</tr>
</table>
</div>
</template>
<script>
import { mapState, mapActions } from ‘vuex’;
export default({
computed: mapState({
detail: state => state.news.detail
}),
created() {
// 获取路由参数id
// js 中用 this.$route 获取当前路由,用 this.$router 获路由对象,全部路由信息
// 在模板中用 $router 和 $router 直接调用
var id = this.$route.params.id;
this.GETDETAIL(id);
},
methods: {
…mapActions([
‘GETDETAIL’
])
}
});
</script>
|
模板文件
resources/views/welcome.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<html lang=“en”>
<head>
<meta charset=“utf-8”>
<meta http-equiv=“X-UA-Compatible” content=“IE=edge”>
<meta name=“viewport” content=“width=device-width, initial-scale=1”>
<link rel=“stylesheet” href=“/css/bootstrap.min.css”>
<title>Laravel</title>
</head>
<body>
<div id=“app” class=“container”><router-view class=“view”></router-view>
</div>
</body>
<script type=“text/javascript”>
var Laravel = {
// 设置 csrfToken
csrfToken: ‘{{ csrf_token() }}’
};
</script>
<script src=“/js/app.js”></script>
</html>
|
服务端 API
服务端的 api
只是一个数据的模拟,没有做深入的开发
routes/web.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
Route::get(‘/news’, function() {
return [
[‘id’ => 1, ‘title’ => ‘new1’],
[‘id’ => 2, ‘title’ => ‘new2’],
[‘id’ => 3, ‘title’ => ‘new3’],
[‘id’ => 4, ‘title’ => ‘new4’],
];
});
Route::get(‘/newslist’, function() {
return [
[‘id’ => 1, ‘title’ => ‘new1’],
[‘id’ => 2, ‘title’ => ‘new2’],
[‘id’ => 3, ‘title’ => ‘new3’],
[‘id’ => 4, ‘title’ => ‘new4’],
];
});
Route::get(‘/newsdetail/{id}’, function($id) {
return [
‘id’ => 1,
‘title’ => ‘news’,
‘content’ => ‘content’,
‘created_at’ => date(‘Y-m-d H:i:s’)
];
});
|
运行
1
2
|
php artisan serve // 开启 web
gulp // 打包前端资源,开发的时候用 gulp watch 监听实时浏览
|
打开浏览器,访问 http://localhost:8000 查看效果。
这个例子只是简单的使用了 Laravel
和 vue
,详细开发请查看官方文档。