# Vue 填坑之路
# 1. vue中引入json数据
必须创建服务才可以在vue中直接使用json数据;
可参考vue请求本地数据
下面就本次使用再清晰理一遍:
方法一:
在webpack.dev.conf.js中(vue-cli实现的vue项目框架已经加上理express),直接引入json文件,然后在devServer中加上get或者post请求,然后就可以在vue中正常请求此服务上产生的数据了:
var beijingData = require('../beijing.json')
before(app) {
app.get('/api/beijingData', (req, res) => {
res.json({
errno: 0,
data: beijingData
})//接口返回json数据,上面配置的数据seller就赋值给data请求后调用
})
}
2
3
4
5
6
7
8
9
10
方法二:
平时我习惯mock.js产生假数据,所以可以用mock的服务来处理json,同样的在vue中就可以正常请求到了。
var Mock = require('mockjs');
var beijingdata = require('./beijing.json');
var beijingdata1 = require('./beijing2.json');
Mock.mock('/sinotans/order/leftChart', 'get', function (options) {
return {
message: 'success',
data: { orderNum: beijingdata, goodsAmount: beijingdata1 },
statusCode: 200
};
});
2
3
4
5
6
7
8
9
10
11
# 2. vue router-link上添加点击事件。
需要添加.native
<ul v-if="isShow">
<router-link :to="headNavLink[index]"
v-for="(item,index) in headNavList"
:key="index"
tag="li"
@click.native="activeChange(index)">
<div class="nav-icon"></div>
<span class="nav-font">{{item}}</span>
</router-link>
</ul>
2
3
4
5
6
7
8
9
10
# 3. vue中 watch对象或者数组
数组和对象都需要深层次监测:
data () {
return {
orderTotal: {
businessSel: '1',
companySel: '全部',
projectSel: '全部',
customerSel: '全部',
flowFrom: '全部',
flowTo: '全部'
},
}
},
watch: {
orderTotal: {
handler(newValue, oldValue) {
console.log(newValue)
const businessSelectedw = newValue.businessSel;
const companySelectedw = newValue.companySel;
const customerSelectedw = newValue.customerSel;
const projectSelectedw = newValue.projectSel;
// 监听
if (companySelectedw === '全部') {
this.projectDisabled = true;
this.customerDisabled = true;
} else {
this.projectDisabled = false;
this.customerDisabled = false;
}
// 监听
if ((customerSelectedw !== '全部' && Number(businessSelectedw) === 2) || (projectSelectedw !== '全部' && Number(businessSelectedw) === 1)) {
this.flowShowFlag = true;
} else {
this.flowShowFlag = false;
}
},
deep: true
}
},
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
如果想监测具体的属性变化,如pokerHistory变化时,才执行handler函数,则可以利用计算属性computed做中间层。
data() {
return {
bet: {
pokerState: 53,
pokerHistory: 'local'
}
}
},
computed: {
pokerHistory() {
return this.bet.pokerHistory
}
},
watch: {
pokerHistory(newValue, oldValue) {
console.log(newValue)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 4. vue-router多重包含的重定向问题
问题描述:
我的页面结构是这样的。当时的问题是:在点击四个子页面的时候,内容页一那一层的.router-link-active
就没了。后来发现是因为我的内容页和子页面写在同一级别上了(怎么说才对呢————就是我的页面一进入内容页一后我需要直接展示子页面一,而我的内容页一和子页面一的路由写成了一样的,这样就导致子页面和内容页一在同一个里面了。所以就点击子页面时,.router-link-active
就只有一个了。在内容页一二上没有了)。解决办法就是内容页一给一个路由,然后重定向到子页面一上。
同时在的子页面二点击按钮处还分为了子页面21和子页面22
export default new Router({
routes: [
{
path: "/",
redirect: "/index"
},
{
path: "/index",
component: home
},
{
path: "/pages1",
redirect: "/pages/childPage1",
},
{
path: "/pages1",
name: "visualization",
component: visual,
children: [
{
path: "/visual/childPage1",
name: "orderNumAnaly",
component: orderNumAnaly
},
{
path: "/visual/childPage2",
redirect: "/visual/KPI/log",
},
{
path: "/visual/childPage2/childPage21",
name: "KPILog",
component: effectKPILog
},
{
path: "/visual/childPage2/childPage22",
name: "effectKPIWater",
component: effectKPIWater
},
{
path: "/visual/childPage3",
name: "transWrongAnaly",
component: transWrongAnaly
},
{
path: "/visual/childPage4",
name: "visualAbility",
component: visualAbility
}
]
},
{
path: "/pages2",
name: "lot",
component: lot
}
]
});
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
# 5. amcharts 插件在vue中使用
amcharts必须全局引用,必须在main.js中引用:
/* eslint-disable */
import AmCharts from 'amcharts3';
import AmSerial from 'amcharts3/amcharts/serial';
import AmPieChart from 'amcharts3/amcharts/pie';
/* eslint-enable */
2
3
4
5
Using amCharts with Vue.js and Webpack
文章最后面说的图标无法显示的问题,如下添加即可:
# 6. vue中父组件向路由页传递值
一开始没明白过来router-view
上面也可以如同平常组件那样传递props值。所以走了很多弯路。
在此标记:
<router-view :companyOptions="companyOp"></router-view>
# 7. props传过来的值作为初始值,后续怎么改变
需求是不需要改变父组件的,只是在父组件中统一请求到了初始值,每个组件中的初始值相同,但后续会不同。
哎呀这次真的被自己坑了:
一开始的思路是知道props不能直接改变的,那就用computed写一个新变量来接收它,然后在方法中改变它,报错没有setter,设置setter不起作用,要不就报错不能修改props,懵了;
问了同事后,才发现简单问题想复杂了。实际上一开始只需要拿到就行了。
data () {
return {
op: this.propsValue
}
},
props: ['propsValue'],
methods: {
changeOp () {
this.op = '12334';
}
}
2
3
4
5
6
7
8
9
10
11
# 8. 画图实现的对象上的绑定方法操作本页面数据
问题: 画图的代码在另一个js中封装,本vue中引入js,请求之后调用函数生成myChart对象,即图表对象。此时需要在其上绑定事件。
由于请求是异步执行,所以要考虑保证绑定事件在画图之后。
思路一: 如果在本.vue中等待其后绑定,那么就要使画图代码中return 出去
//setChart.js
import echarts from "echarts";
export default function(data, id) {
let myChart = echarts.init(document.getElementById(id));
let option = {};
myChart.setOption(option);
window.onresize = myChart.resize;
return myChart;
};
2
3
4
5
6
7
8
9
10
在.vue页面:
import myChart from '@/charts/setChart';
mounted () {
this.utils.MlTools.reqCharts('/sinotans/order/rightChart', 'myChartInit', this.proDym, this) // 发起请求画图
},
methods: {
myChartInit () {
let data = this.proDym;
let _this = this;
myChart(data, "RightChart").on('click', function (params) {
if (params.componentType === 'series') {
// 点击到了 markPoint 上
if (params.seriesIndex === 1 || params.seriesIndex === 0) {
_this.tabActive = 1;
_this.busCarrier.projectSel = _this.proDym.projectSel;
_this.busCarrier.carrierSel = '全部';
}
}
});
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
思路二:传入回调函数
//setChart.js
import echarts from "echarts";
export default function(data, id, callback) {
let myChart = echarts.init(document.getElementById(id));
let option = {};
myChart.setOption(option);
window.onresize = myChart.resize;
myChart.on('click', function(params){
if (params.componentType === 'series') {
callback();
}
})
};
2
3
4
5
6
7
8
9
10
11
12
13
14
在.vue中:
import myChart from '@/charts/setChart';
mounted () {
this.utils.MlTools.reqCharts('/sinotans/order/rightChart', 'myChartInit', this.proDym, this)//发起请求画图
},
methods: {
myChartInit () {
let data = this.proDym;
myChart(data, "RightChart", this.changeToShip)
},
changeToShip () {
this.tabActive = 1;
this.busCarrier.projectSel = this.proDym.projectSel;
this.busCarrier.carrierSel = '全部';
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 9. 后台接收不到数据之content-type
form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。
当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2...),然后把这个字串追加到url后面,用?分割,加载这个新的url。
当action为post时候,浏览器把form数据封装到http body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。
当action为post且Content-Type类型是multipart/form-data,浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。
原生AJAX的POST请求如果不指定请求头Request Header,默认使用的Content-Type是text/plain;charset=UTF-8,参数出现在Request payload块。
一般json数据格式的话,浏览器处就显示的是
Content-Type:application/json;chartset=UTF-8
vue中的axios传参方式是request payload,参数格式是json,而并非用的是form传参,所以在后台用接收form数据的方式接收参数就接收不到了。
解决办法:
安装 qs : npm install qs --save
import qs from "qs";
axios({
method: "post",
url: param.url,
dataType: "json",
data: qs.stringify(param.data),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
}).then(res => {
}, err => {
});
2
3
4
5
6
7
8
9
10
11
12
13
14
# 10. axios 实现某些请求的拦截, 不是全局统一拦截
生成实例:
static reqCharts(urls, d, datas, _this, loading) {
let instance = axios.create();
// 添加请求拦截器
instance.interceptors.request.use(function(config) {
// 在发送请求之前做些什么
_this[loading] = true;
return config;
}, function(error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function(response) {
// 对响应数据做点什么
_this[loading] = false;
return response;
}, function(error) {
// 对响应错误做点什么
return Promise.reject(error);
});
return new Promise((resolve, reject) => {
instance
.post(urls, datas)
.then(function(res) {
// 处理res
})
.catch (function(err) {
console.log(err.response)
})
})
}
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
# 11. axios设置请求超时,mock服务下需要设置,否则不起作用。
# 12. vue起服务自动用ip
在config/index.js中,添加:
const ip = require('ip').address();
....
host: ip
2
3