1. webpack的安装

1 先安装node.js

1
2
3
4
node -v
npm -v
cd webpack-demo(在桌面上新建一个文件夹)
npm init (在新建文件夹下)

image-20190506105853226

2.全局安装webpack (不推荐)

image-20190506110008403

1
npm install webpack webpack-cli -g (g表示全局安装  用手机热点安装 防止被墙)

3 在项目内安装webpack(推荐)

1
2
3
4
cd webpack-demo (在项目内安装)
npm install webpack webpack-cli --save-d (npm install webpack webpack-cli -D) 两者等价
npm webpack -v (6.4.1)
npx webpack -v (4.30.0)

image-20190506110459792

1
2
进入到项目文件夹中
npm install 命令可以将整个文件打包

image-20190506111049312


2 webpack打包项目

webpack main.js build.js (会报错)

1
2
> 使用 npx webpack命令 会报错
>

image-20190510195931712

添加配置文件 webpack.config.js

  • bug
  • ![image-20190510200844289](../../../Users/apple/Library/Application Support/typora-user-images/image-20190510200844289.png)

3webpack 配置文件的编写

1
2


4 webpack-dev-server

image-20190511083348342


使用 webpack-dev-server需要安装webpack、 webpack-dev-server和 html-webpack-plugin三个包。

1
npm install webpack@3.6.0 webpack-dev-server@2.9.1 html-webpack-plugin@2.30.1 --save-dev

安装完成,会发现程序目录出现一个package.json文件

  • 配置webpack-dev-server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在package.json中配置script

"scripts": {
"dev": "webpack‐dev‐server ‐‐inline ‐‐hot ‐‐open ‐‐port 5008"
},

--inline:自动刷新

--hot:热加载

--port:指定端口

--open:自动在默认浏览器打开

--host:可以指定服务器的 ip,不指定则为127.0.0.1,如果对外发布则填写公网ip地址

此时package.json的文件内容如下:
1
2
3
4
5
6
7
8
9
10
{
"scripts": {
"dev": "webpack‐dev‐server ‐‐inline ‐‐hot ‐‐open ‐‐port 5008"
},
"devDependencies": {
"html‐webpack‐plugin": "^2.30.1",
"webpack": "^3.6.0",
"webpack‐dev‐server": "^2.9.1"
}
}
  • 配置webpack.config.js

    在webpack.config.js中配置html-webpack-plugin插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    > var htmlwp = require('html‐webpack‐plugin');
    > module.exports={
    > entry:'./src/main.js', //指定打包的入口文件
    > output:{
    > path : __dirname+'/dist', // 注意:__dirname表示webpack.config.js所在目录的绝对路径
    > filename:'build.js' //输出文件
    > },
    > plugins:[
    > new htmlwp({
    > title: '首页', //生成的页面标题<head><title>首页</title></head>
    > filename: 'index.html', //webpack‐dev‐server在内存中生成的文件名称,自动将build注入到这
    > 个页面底部,才能实现自动刷新功能
    > template: 'vue_02.html' //根据index1.html这个模板来生成(这个文件请程序员自己生成)
    > })
    > ]
    > }
    >
  • 配置模板文件

1
2
将原来的vue_02.html作为模板文件,为了和内存中的index.html文件名区别,注意将vue_02.html中的script标签
去掉
  • 启动 项目

    image-20190511111559369



5 CMS前端工程搭建

  • Vue-cli脚手架的封装 ——xc-ui-pc-sysmanage

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # install dependencies
    npm install

    # serve with hot reload at localhost:8080
    npm run dev

    # build for production with minification
    npm run build

    # build for production and view the bundle analyzer report
    npm run build --report

    # run unit tests
    npm run unit

    # run e2e tests
    npm run e2e

    # run all tests
    npm test

    ⭐️⭐️

    image-20190511164646016 删除node_mo dules 然后执行 npm install 此时会出现卡顿网慢。然后使用cnpm. install 来生成 node_modules 然后。npm run dev

    要使用node-v =8.00

    Cpm run dev

image-20190511165150959


image-20190610174444798

创建页面和定义路由

image-20190511170741329

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div>
<!--编写页面静态部分 即view部分-->
Hello world
</div>
</template>
<script>
// <!--编写页面静态部分 即model vm部分-->
</script>
<!--编写页面样式 非必须-->
<style>
</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import Home from '@/module/home/page/home.vue';
import page_list from '@/module/cms/page/page_list.vue';
export default [{
path: '/',
component: Home,
name: 'CMS',//菜单名称
hidden: false,
children: [
{
path: '/cms/page/list',
name: '页面列表',
component: page_list,
hidden: false
}
]
}/*,
{
path: '/login',
component: Login,
name: 'Login',
hidden: true
}*/
]

image-20190511171017709


image-20190511171038907

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
// 定义路由配置
let routes = []
let concat = (router) => {
routes = routes.concat(router)
}
// // 导入路由规则 base router 中导入路由规则
import HomeRouter from '@/module/home/router'
import CmsRouter from '@/module/cms/router'
// 合并路由规则
concat(HomeRouter)
concat(CmsRouter)
export default routes;

Tabel组建测试

https://element.eleme.cn/#/zh-CN

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<template>
<div>
<el-table
:data="tableData"
stripe
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</div>
</template>

<div> <!‐‐相当于编写html的内容‐‐> <el‐table :data="tableData" stripe style="width: 100%"> <el‐table‐column prop="date" label="日期" width="180"> </el‐table‐column> <el‐table‐column prop="name" label="姓名" width="180"> </el‐table‐column> <el‐table‐column prop="address" label="地址">

</el‐table‐column>

</el‐table> </div>

<script>
// <!--编写页面静态部分 即model vm部分-->
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>

<!--编写页面样式 非必须-->
<style>
</style>

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<template>
<div>
<!--编写页面静态部分,即view部分-->
<el-button type="primary" size="small" v-on:click="query">查询</el-button>
<el-table
:data="list"
stripe
style="width: 100%">
<el-table-column type="index" width="60">
</el-table-column>


<el-table-column prop="pageName" label="页面名称" width="120">
</el-table-column>
<el-table-column prop="pageAliase" label="别名" width="120">
</el-table-column>
<el-table-column prop="pageType" label="页面类型" width="150">
</el-table-column>
<el-table-column prop="pageWebPath" label="访问路径" width="250">
</el-table-column>
<el-table-column prop="pagePhysicalPath" label="物理路径" width="250">
</el-table-column>
<el-table-column prop="pageCreateTime" label="创建时间" width="180">
</el-table-column>
</el-table>
<el-pagination
layout="prev, pager, next"
:total="total"
:page-size="params.size"
:current-page="params.page"
v-on:current-change="changePage"
style="float:right">
</el-pagination>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{
"siteId": "5a751fab6abb5044e0d19ea1",
"pageId": "5a754adf6abb500ad05688d9",
"pageName": "index.html",
"pageAliase": "首页",
"pageWebPath": "/index.html",
"pageParameter": null,
"pagePhysicalPath": "F:\\develop\\xc_portal_static\\",
"pageType": "0",
"pageTemplate": null,
"pageHtml": null,
"pageStatus": null,
"pageCreateTime": "2018-02-03T05:37:53.256+0000",
"templateId": "5a962b52b00ffc514038faf7",
"pageParams": null,
"htmlFileId": "5a7c1c54d019f14d90a1fb23",
"dataUrl": null
},
{
"siteId": "5a751fab6abb5044e0d19ea1",
"pageId": "5a795ac7dd573c04508f3a56",
"pageName": "index_banner.html",
"pageAliase": "轮播图",
"pageWebPath": "/include/index_banner.html",
"pageParameter": null,
"pagePhysicalPath": "F:\\develop\\xc_portal_static\\include\\",
"pageType": "0",
"pageTemplate": null,
"pageHtml": null,
"pageStatus": null,
"pageCreateTime": "2018-02-06T07:34:21.255+0000",
"templateId": "5a962bf8b00ffc514038fafa",
"pageParams": null,
"htmlFileId": "5a795bbcdd573c04508f3a59",
"dataUrl": null
}
]
}
}
}
</script>

分页查询 使用

1
2
3
4
5
6
7
8
9
<el-pagination
:page-size="params.page"
:pager-count="params.size"
layout="prev, pager, next"
:total="total"
style="float:right"
@current-change="changePage"
>
</el-pagination>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
// <!--编写页面静态部分 即model vm部分-->
export default {
data() {
return {
total: 1000,
params: {
page: 20,
size: 11
},
methods: {
query: function () {
alert("qq")
},
changePage: function () {
//调用Query方法 this表示当前实栗对象
this.query();
}
}

image-20190513063245332


Api 调用

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
require('es6-promise').polyfill()
import axios from 'axios'

axios.defaults.withCredentials = true //跨域
axios.defaults.timeout = 10000
axios.defaults.headers.post['Content-Type'] = 'application/x-www=form-urlencoded'
import utils from '../../common/utils'
if(utils.getJwt()){
axios.defaults.headers['Authorization'] = 'Bearer '+utils.getJwt()
}
//axios.defaults.headers['Authorization'] = ''
// 请求之前拦截
/*axios.interceptors.request.use(config => {
// 判断token
//if (localStorage.token) {
config.headers.Authorization = 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MjEwODA4ODYsInVzZXJfbmFtZSI6IjEyMyIsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwianRpIjoiYTNiM2RiYjgtODJkYS00YWI2LWIwZjEtMWMyZDI5ZjM3MjExIiwiY2xpZW50X2lkIjoibWFuYWdlciIsInNjb3BlIjpbIm1hbmFnZXIiXX0.YivH7foaYfSJs9nPBR40TbJ7T0sGXBGaZV2g8Ivktiatdv0Sjkl4PbS3tsjSBtbyqLekYDLoWSojiDLyvgMy5qskeRLefVk4FYpEMzpxfb5JtaxoIRH0o-Re1MC2quq-J7kxRKAL1DUEmr-_GEEmB8zswYJNwYn3vZK0FMQlbsIty4LCfgIwXfH9XnPcUhojUUIBRUDT2W3s8j-qZQ-iKk1y2kesrXloiOtPEL5CljmlOyZ3GED_HNude5b41TqCQyv2VS1baE9DEPo-P0Hb33rSCMILk3rZg-hO7zuDMGfbGWKMQRgY6Fb2uUtqokYa5aLtXyEwW67FKAi2mK2cPA'
//}
return config
},error =>{
alert("参数错误", 'fail')
return Promise.reject(error)
})*/

export default {
//get请求
requestGet (url, params = {}) {
return new Promise((resolve, reject) => {
axios.get(url, params).then(res => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
},
//get请求不带参数
requestQuickGet (url) {
return new Promise((resolve, reject) => {
axios.get(url).then(res => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
},
//post请求
requestPost (url, params = {}) {
return new Promise((resolve, reject) => {
axios.post(url, params).then(res => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
},
//post请求
requestPostForm (url, params = {}) {
return new Promise((resolve, reject) => {
axios.post(url, params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
}).then(res => {
resolve(res.data)//注意res是axios封装的对象,res.data才是服务端返回的信息
}).catch(error => {
reject(error)
})
})
},
//put请求
requestPut (url, params = {}) {
return new Promise((resolve, reject) => {
axios.put(url, params).then(res => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
},
//delete请求
requestDelete (url, params = {}) {
return new Promise((resolve, reject) => {
axios.delete(url, params).then(res => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
}
}
1
2
3
4
5
6
7
8
9
10
11
12
import http from './../../../base/api/public'
import querystring from 'querystring'

let sysConfig = require('@/../config/sysConfig')
let apiUrl = sysConfig.xcApiUrlPre;

//定义方法请求 服务端的页面查询接口
export const page_list = (page, size, params) => {
//请求 服务端的页面查询接口
return http.requestQuickGet(apiUrl+'/cms/page/list/'+page+'/'+size);
// return http.requestGet("apiUrl+'/cms/page/list/'+page+'/'+size);
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
import * as cmsApi from '../api/cms'
// <!--编写页面静态部分 即model vm部分-->
export default {
data() {
return {
total: 1000,
params: {
page: 20,
size: 11
},
list: []
}
},
methods: {
query: function () {
//调用服务端的接口 cms.js 调用
cmsApi.page_list(this.params.page, this.params.size).then((res) => {
this.list = res.queryResult.list;
this.total = res.queryResult.total;
})
},
<script>

Api跨域问题

image-20190514094803403


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
'use strict'
// Template version: 1.2.4
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')
var proxyConfig = require('./proxyConfig')
let sysConfig = require('./sysConfig')
let xcApiUrl = sysConfig.xcApiUrl
module.exports = {
dev: {

// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
//proxyTable: proxyConfig.proxyList,
proxyTable: {
'/banner': {
// target: 'http://localhost:3000/mock/11'
target: 'http://127.0.0.1:7777'

},
//http://localhost:8080/cms/page/list/1/11
'/api/cms': {
target: 'http://localhost:8080',
pathRewrite: {
'^/api': ''
}
//target: 'http://127.0.0.1:50201'

}

1
2
3
4
5
6
7
8
9
10
var sysConfig = {
xcApiUrlPre: '/api',
xcApiUrl: 'http://api.xuecheng.com/',
imgUrl:'http://img.xuecheng.com/',
videoUrl:'http://video.xuecheng.com/',
openAuthenticate:true,
openAuthorize:true
}

module.exports = sysConfig

分页查询 钩子函数

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
<script>
import * as cmsApi from '../api/cms'
// <!--编写页面静态部分 即model vm部分-->
export default {
data() {
return {
total: 1000,
params: {
page: 1,
size: 11
},
list: []
}
},
methods: {
query: function () {
//调用服务端的接口 cms.js 调用
cmsApi.page_list(this.params.page, this.params.size).then((res) => {

this.list = res.queryResult.list;
this.total = res.queryResult.total;

})
},
changePage: function (page) {
alert(page);
this.params.page = page;
this.query();
}

},
//钩子函数
mounted() {
this.query();
}
}
</script>

image-20190514173413017


###