通过cooking搭建简易Vue开发环境(入门)的学习,我们对cooking搭建vue项目有了一定的了解,今天就一起来学习一下使用cooking搭建多页Vue应用的例子。
1. 设计配置文件
- 在根目录创建app.json文件,配置如下:
{
"pages":[
{
"entry":"index",
"title":"首页",
"cdn":{}
},{
"entry":"school",
"title":"学校",
"cdn":{}
}
],
"basePath":"./src/pages/",
"cdn": {
"js": [],
"css": []
},
"extetnals":{
"vue":"Vue",
"vuex":"Vuex"
}
}
- 在src/pages目录下创建index和school目录,每个目录下分别创建index.js和app.vue文件。
index.js
import Vue from 'vue'
import App from './app'
new Vue({
el: '#app',
render: h => h(App)
})
app.vue
<template>
<div>
<h1>{{pageName}}页面</h1>
<p>A vue project.</p>
</div>
</template>
<script>
export default {
name:'index',
data() {
return {
pageName: '主页'
}
}
}
</script>
2.配置cooking文件
- 入口文件
打开cooking.conf.js文件,我们要从app.json里读取entry的信息,因为需要做以下处理:
var App = require('./app.json')
var path = require('path')
var entries = function() {
var result = {}
App.pages.forEach(p => {
result[p.entry] = path.resolve(App.basePath, p.entry)
})
return result
}
cooking.set({
entry: entries()
})
- 模板文件
所有的入口页面都是通过index.tpl模板配置,只需要将公用 CDN 和私有 CDN 合并后拼接成 HTML 插入到模板内,同时引入入口文件和 vendor,通过 html-webpack-plugin 的配置选项。
var App = require('./app.json')
var path = require('path')
var merge = function(a, b) {
return {
css: (a.css || []).concat(b.css || []),
js: (a.js || []).concat(b.js || [])
}
}
var templates = function() {
return App.pages.map(p => {
return {
title: p.title,
filename: p.entry + '.html',
template: path.resolve(__dirname, 'index.tpl'),
cdn: merge(App.cdn, p.cdn),
chunks: ['vendor', 'manifest', p.entry]
}
})
}
cooking.set({
template: templates()
})
同时需要将index.html改成index.tpl。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<% for (var i in htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"><% } %>
</head>
<body>
<div id="app"></div>
<% for (var i in htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script><% } %>
</body>
</html>
另外还要将app.json里加入tpl入口。
{
"pages":[
{
"entry":"index",
"title":"首页",
"cdn":{},
"tpl":"index.tpl"
},{
"entry":"school",
"title":"学校",
"cdn":{},
"tpl":"index.tpl"
}
],
"basePath":"./src/pages/",
"cdn": {
"js": [],
"css": []
},
"extetnals":{
"vue":"Vue",
"vuex":"Vuex"
}
}
- 最终的配置文件如下:
// 引入 cooking 依赖
var cooking = require('cooking');
var App = require('./app.json');
var path = require('path');
var entries = function() {
var result = {}
App.pages.forEach(p => {
result[p.entry] = path.resolve(App.basePath, p.entry)
})
return result
}
var merge = function(a, b) {
return {
css: (a.css || []).concat(b.css || []),
js: (a.js || []).concat(b.js || [])
}
}
var templates = function() {
return App.pages.map(p => {
return {
title: p.title,
filename: p.entry + '.html',
template: path.resolve(__dirname, 'index.tpl'),
cdn: merge(App.cdn, p.cdn),
chunks: ['vendor', 'manifest', p.entry]
}
})
}
// 调用 set 方法传入自定义配置
cooking.set({
// entry: './src/index.js', // 指定入口文件
entry: entries(),
dist: './dist', // 设置打包后的文件目录
hash: true, // 打包的文件是否带 hash
sourceMap: true, // 是否带 sourceMap
// template: './index.html', // 加载 index.html 模板
template: templates(),
devServer: { // 开启 webpack-dev-server
port: 9527, // 端口为 9527
publicPath: '/' // 开启 dev-server 时默认打包的资源文件路径是和 index.html 同级的
},
extends: ['vue2'] // 加载 cooking-vue2,自动配置 Vue 2.0 相关内容
});
module.exports = cooking.resolve();
- 然后运行项目,查看页面效果。
npm run dev
3.配置路由
- 首先需要安装vue-router
npm install vue-router
- 在school/subpage文件夹下面创建index.app和detail.vue文件。
index.app
<template>
<div>
<h1 class="title">Welcome To {{message}}</h1>
</template>
<script>
export default {
data(){
return {
message:'学校主页',
}
},
created(){
}
}
</script>
<style>
h1 {
background-color: yellow;
}
</style>
detail.vue
<template>
<div>
<h1 class="title">Welcome To {{message}}</h1>
</template>
<script>
export default {
data(){
return {
message:'学校内页',
}
},
created(){
}
}
</script>
<style module>
h1 {
background-color: #eee;
}
</style>
- 在school文件夹下创建routes.js文件,代码如下:
import Index from './subpage/index.vue';
import Detail from './subpage/detail.vue';
module.exports=[
{
path:'/',
name:'Index',
component:Index
},{
path:'/detail',
name:'Detail',
component:Detail
},
]
- 修改school文件夹下的index.js文件:
import Vue from 'vue'
import App from './app'
import routes from './routes.js';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
routes
});
new Vue({
router,
render:h=>h(App)
}).$mount('#app')
- 修改school文件夹下的app.vue文件:
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'school',
data() {
}
}
</script>
- 重新运行项目
npm run dev
4.配置vuex
- 安装vuex
npm install vuex --save
- 在school文件夹下面创建store.js,配置如下:
export default {
state:{
count:666
},
mutations:{
setState(state,opt) {
if(typeof opt !== 'object') return ;
for(let item in opt) {
if( state[item] !== undefined && opt.hasOwnProperty(item) ) {
state[item] = opt[item];
}
}
},
}
}
- 修改school文件夹下的index.js文件
import Vue from 'vue'
import App from './app'
import routes from './routes.js';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
routes
});
// 配置store
import $store from './store';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store($store);
new Vue({
router,
store,
render:h=>h(App)
}).$mount('#app')
- 修改school/subpage/detail.vue文件:
<template>
<div>
<h1 class="title">Welcome To{{message}}</h1>
<h3>vuex的count值:{{$store.state.count}}</h3>
<button @click="setCount">修改</button>
</div>
</template>
<script>
export default {
data(){
return {
message:'学校内页',
}
},
methods:{
setCount(){
this.$store.commit('setState', {count: this.$store.state.count+1});
}
},
created(){
}
}
</script>
<style module>
h1 {
background-color: #eee;
}
</style>
通过以上的配置,便可以取得store中的值了,通过点击按钮,可以修改store的值:
以上就是vuex的配置。
5.配置axios
- 首先安装axios
npm install axios --save
- 修改school文件夹下的index.js文件
import Vue from 'vue'
import App from './app'
// 配置store
import routes from './routes.js';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
routes
});
// 配置store
import $store from './store';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store($store);
// 配置axios
import axios from 'axios';
Vue.prototype.$http = axios;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
// 添加拦截器
axios.interceptors.request.use((config) => {
if(config.method === 'post') {
if(config.data) {
config.data = config.data + '&_=' + new Date().getTime();
} else {
config.data = '_=' + new Date().getTime();
}
} else if(config.method === 'get') {
if(config.params) {
config.params = Object.assign({},config.params,{_:new Date().getTime()})
} else {
config.params = {_:new Date().getTime()}
}
}
return config;
},(err) => {
console.log(err,'err');
});
new Vue({
router,
store,
render:h=>h(App)
}).$mount('#app')
- 在cooking.conf.js中配置服务器接口的地址信息:
cooking.set({
entry: entries(), // 入口文件
dist: './dist', // 设置打包后的文件目录
clear:true, //每次打包都清理dist目录
hash: true, // 打包的文件是否带 hash
sourceMap: true, // 是否带 sourceMap
template: templates(),
devServer:{
port:8888,
publicPath:'/',
//接口信息
proxy:{
'/webservice/*': {
target: 'http://192.168.10.108',
changeOrigin: true,
},
}
},
alias: {
'src': path.join(__dirname, 'src')
},
publicPath:'/dist', //打包后的资源相对于url的路径
// 插件在这里设置
extends:['vue2','less','sass'] //安装cooking-lint并配置 '.eslintrc' 文件
});
- 在school文件夹下新建api.js文件,如下:
export default {
getSysSetting: 'webservice/sysSettingItem.action',
}
- 在school/subpage/index.vue中请求接口
<template>
<h1 class="title">Welcome To{{message}}</h1>
</template>
<script>
import api from '../api';
export default {
data(){
return {
message:'学校主页',
}
},
methods:{
getSysSetting() {
return this.$http.get(api.getSysSetting).then(res=>{
if(res.data.success) {
let setting = res.data.data; //根据实际接口的格式来取数据
this.info= setting;
}
}).catch(()=>{
alert('message:error happen on system');
});
},
},
created(){
this.getSysSetting();
}
}
</script>
<style>
h1 {
background-color: yellow;
}
</style>
- 重新运行项目
npm run dev
不出意外的话,便可以查看到如下结果
以上只是cooking下的一些实用功能的简易配置,具体的项目可能远比以上配置复杂的多,不断积累,不断学习,愿与君共同进步。