cooking搭建多页Vue开发环境(进阶)

     通过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.appdetail.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下的一些实用功能的简易配置,具体的项目可能远比以上配置复杂的多,不断积累,不断学习,愿与君共同进步。

猜你喜欢

转载自blog.csdn.net/peacekang/article/details/86657642