vue操作日志

#webpack有4个重点内容:

  • 入口(entry)
  • 输出(output)
  • 加载器(loader)
  • 插件(plugins)

我们的vue项目都是从根目录下的index.html文件开始执行的,因为我们在dev.conf.js文件的plugin配置中设置了起始位置是index.html

在base.conf.js文件的module.exports中,我们配置了入口文件是main.js,所以我们在main.js文件中,配置了vue实例,router对象, 在new一个实例化对象时

1
2
3
4
5
6
new Vue({
el: '#first', 这里的对象就是index.html里面的id选择器
router, 必须配置router才可以进行单页渲染
components: { Page }, 组件引入
template: '<Page/>' 组件模块, 有另外一种写法,使用render函数 render: h => h(App)
})

watch用于异步操作,而computed同步

这二个里面尽量不要去修改,只能去显示,否则会造成无限循环的情况 –> 因为如果是修改的话,就又触发了监听事件。

监听事件,可以监听对象的属性,写法是

1
2
3
4
5
6
7
8
9
watch: {
'firstName.a': { 使用字符串的形式
handler (newName, oldName) {
this.fullName = newName + '12'
}, 监听会先触发handler函数, 可以利用这点实现三层互动,一个区域实现二层互动,不干扰的情况
immediate: true
// deep: true 不用字符串监听属性的话,就必须使用deep,---耗性能
}
},

props组件件传值可以通过type进行控制传值类型

子组件向父组件传递参数

子组件也需要设定参数

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
<template>
<div class="son">
Hi,Every Bady
<p><input type="text" @input="handleInput"></p>
</div>
</template>
<script>
export default {
name: 'son',
props: ['value'], 子组件设定传值信息
methods: {
handleInput (e) {
this.$emit('input', e.target.value) emit函数--一个事件名称,一个要传递的值
}
}
}
还可以这样写
export default {
name: 'son',
model: {
prop: 'value1',
envent: 'input'
},
methods: {
handleInput (e) {
this.$emit('input', e.target.value) emit函数--一个事件名称,一个要传递的值
}
}
}
</script>

父组件也需要在data里面,设置,并在子组件里书写

1
2
<son  v-model="value"></son>  二者等同
<son :value="value" @input = "value = arguments[0]">

ssh操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ssh-key
ssh-keygen.exe -t rsa -C "账号地址"

生成的秘钥在用户的.ssh文件夹里

创建分支
PS D:\work\test> git checkout -b feature
Switched to a new branch 'feature'
PS D:\work\test> git pull origin feature

git pull origin feature

git status
git add .
git commit -m 'xxx'

git push origin feature

git checkout -b product 切换product分支

修改本地数据库后需要执行 php .\artisan config:clear

计算属性

computed:{
  usrInfo(){
    var usrInfo = this.$store.state.usrInfo;
    return usrInfo;
  }
}

computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])

store.state.stateA   拿取state
store.dispatch    触发action里的函数
通过 commit  触发 mutations 里的函数

展开运算符

1
2
3
function test(a,b,c) { }
var args = [0,1,2];
test(...args)

vue的条件判断

1
2
3
4
<div class="app-wrapper" :class="{hideSidebar:!sidebar.opened}">
:class="{hideSidebar: false}" 如果值为false hideSidebar类不会出现,如果为true,则在class添加 hideSidebar类

如果a.b本身不存在, 你在methods更新的时候,需要使用 this.$set(a,b,val)

报错信息

1
2
Duplicate keys detected: 'App'. This may cause an update error.
出现2个相同的key值会报此种错误

判断上传文件类型的写法

1
2
<input type="file" accept="image/*">  可以上传所有文件
或者指定 accept="image/jpg,image/png"

多段判断分析

1
2
3
i==3? 'so' : b==5 ?  '66' : '88'
如果i==3 那么肯定输出3
如果 i!=3 那么判断b是否等于5,如果等于5,输出66,否则输出88

路由守卫使用vuex

路由守卫,当触发路由时,会先执行这个函数,to-到哪里去,from-从哪里来,next,第三个参数

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
beforeRouteEnter(to, from, next) {
这里的record是暴露出去的一个对象,里面 有个get函数
export const record = {
get(data) {
return new Ajax({
url: '/admin/record/getRecordList',
method: 'get',
params: data
})
}
}


record.get(to.query).then(data => {
console.log(data)
next(vm => {
这里的vm就是当前的实例化对象,this
vm.tableData = data.items;
vm.total = parseInt(data.total);
vm.query.page = data.page;
vm.query.pageSize = data.pageSize;
vm.totalAmount = data.extra.sum;
})
})
}

beforeRouteUpdate(to,from,next){
console.log('beforeRouteUpdate')
next()
}

beforeRouteUpdate(to,from,next)

About组件是有二级导航的,在切换二级导航的时候,对应的内容是在变化的;但是about组件是复用的,只会生成一次,切换二级导航的时,如何知道导航在更新呢?

一个组件有二级导航的时候,点击二级导航的时候导航路径更新了,会触发路由钩子函数beforeRouteUpdate。

还有一个beforeRouteLeave(to,from,next)

###

Vue中动态类名的实现

  1. 1
    2
    3
    4
    5
    6
    1. 第一种方式:对象的形式 -->
    <!-- 第一个参数 类名, 第二个参数:boolean值 --> true就显示 :
    2. 第二种方式:三元表达式 注意点:放在数组中,类名要用引号
    <p :class="[ 1 < 2 ? 'p1' : 'p' ]" >三元表示式(文字的颜色)</p>

    在dom元素上添加ref='cc' 后面我们可以通过this.$refs.cc拿到该dom元素

打印报表的实现

引入import { parseTime } from ‘@/utils’
2.tHeader 是props信息 list是数据源
handleDownload() {
import(‘@/vendor/Export2Excel’).then(excel => {
const tHeader = [‘data’, ‘name’, ‘address’, ‘name’]
const filterVal = [‘date’, ‘name’, ‘address’, ‘name’]
const list = this.tableData
const data = this.formatJson(filterVal, list)
const date = new Date();
const filename = date.toLocaleString().split(‘ ‘)[0]+’_’+date.getTime()+’’
excel.export_json_to_excel(tHeader, data, filename)
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if(j === ‘timestamp’) {
return parseTime(v[j])
}else {
return v[j]
}
}))
},

echarts转换base64的方法

1
2
3
4
5
cgImgBase64 = myChart.getDataURL();
setTimeout(() => {
let baseImg = myChart.getDataURL()
this.printSrc = baseImg;
}, 2000)
form表单的提交有个浏览器的默认刷新行为,把form标签改成div就没事了

一个vue页面使用2个style标签!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
### 

<style lang="scss" scoped>
html{font-size: 16px;}
.singleListAd{height: 6rem;}
.listMain{height: 24rem;}
</style>

我使用了2个style标签,一个使用了scoped属性,使其单一页面完成父元素的font-size值赋值,而不修改其他页面的父元素的size值


### 一个dom对象赋予2个事件绑定


@keyup.enter="searchList" @blur="searchList"

function random(len, start, end) {
  var arr = [];
  function _inner(start, end) {
    var span = end - start;
    return parseInt(Math.random() * span + start)
  }
  while (arr.length < len) {
    var num = _inner(start, end);
      if (arr.indexOf(num) == -1) {
        arr.push(num);
      }
    }
    return arr;
  }

var cc = [[1,2],[3,4]]

将多维数组降级到一维数组的方法

1
d2 = Array.prototype.concat.apply([], cc)

组件封装的注意点

1
2
1. 父组件传递给子组件的时候,父组件的data要定义属性,比如''   []  :子组件props = "父组件data"   注意,一定要加双引号
2. 分页数字,在父组件定义要写成nuber形式, 而子组件props里必须要''

vue组件设置样式的方法

​ updataList() {
​ let currentEle = this.$refs.singleList[0].clientHeight;
​ this.$refs.mainHeight.style.height = currentEle * 4.4 + ‘px’;
​ },

this.$nextTick(() => {
  this.updataList();
});
当dom元素渲染完成之后会触发这个方法

判断用户平台

<script type="text/javascript">
var ua = navigator.userAgent.toLowerCase();
var isWeixin = ua.indexOf('micromessenger') != -1;
var isAndroid = ua.indexOf('android') != -1;
var isIos = (ua.indexOf('iphone') != -1) || (ua.indexOf('ipad') != -1);
if (!isWeixin) {
    document.head.innerHTML = '
    <title>抱歉,出错了</title>
    <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
            <link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/0.4.1/weui.css">';
    document.body.innerHTML = '
                <div class="weui_msg">
                    <div class="weui_icon_area">
                        <i class="weui_icon_info weui_icon_msg"></i>
                    </div>
                    <div class="weui_text_area">
                        <h4 class="weui_msg_title">请在微信客户端打开链接</h4>
                    </div>
                </div>';
}

            </script>

封装的echarts组件

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

<template>
<div class="allCountShow" v-show="nowAll">
<div class="showInfo">
<span name="sToday" v-for="(item, key) in showSlot" :key="key">
{{item.explain}} : {{item.today}}
</span>
</div>
<div class="switch">
<span @click="showDataCount">数据统计</span>
<span @click="testFunction" :class="[showActive ? 'active' : '']">图表统计</span>
</div>
<!-- 表格所有 -->
<div class="tableBox" ref='c2' v-show="showData">
<template>
<el-table
:data="tableData"
border
style="width: 98%;text-align:'center';"
:header-cell-style='styleObj'>
<el-table-column v-for = "(item ,index) in tablePropList" :key = "index"
:prop="item.prop"
:label="item.label"
align="center">
</el-table-column>

</el-table>
</template>
<div class="report" style="margin-top:12px;">
<el-button class="no-print" type="success" size="medium" @click="handleDownload">导出excel报表</el-button>
<el-button class="no-print" type="success" @click='pringCharts' size="medium" >打印报表</el-button>
<el-button v-show="freeUpdataTime" type="default" class="updataTimeS" size="medium" ><div>数据统计更新时间: <span>{{updataTime}}</span></div></el-button>
</div>

<!-- 分页 -->
<template>
<div class="block pageNub no-print">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage4"
:page-sizes="[10, 20, 30, 40, 50, 100, 1000]"
:page-size="queryObj.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="allPageSize">
</el-pagination>
</div>
</template>
</div>
<!-- 表格结束 -->
<!-- charts开始 -->
<div class="chartsBox" v-show="!showData">
<div id="main" ref='cc'>

</div>
<el-button v-show="printSrc != ''" @click="pringChartsTwo" type="success" size="medium" >打印图表</el-button>
</div>
</div>
</template>
<script>
import { parseTime } from '@/utils';
import Print from '@/api/print';
import Vue from 'vue';
Vue.use(Print);
var echarts = require('echarts');
export default {
props: {
kenTitle: '',
kenData: '',
kenParams: '',
tableData: '',
allPageSize: '',
queryObj: {},
showSlot: '',
tablePropList: '',
updataTime: '',
freeUpdataTime: ''
},
data() {
return {
printSrc: '',
test: 1,
showData: true,
showActive: 0,
styleObj: {
background: '#bcbcbc'
},
currentPage4: 1,
nowToday: false,
nowAll: true
};
},
methods: {
handleSizeChange(val) {
this.$emit('pageNubShow1', val)
},
handleCurrentChange(val) {
this.currentPage4 = val
this.$emit('currentPageSize', val)
},
handleDownload() {
var tHeaderArrShow = []
var filterValArrShow = []
let loopArrayDown = this.tablePropList
for(let i = 0; i<loopArrayDown.length; i++) {
if(typeof loopArrayDown[i] == 'object') {
tHeaderArrShow.push(loopArrayDown[i].prop)
filterValArrShow.push(loopArrayDown[i].label)
}
}
import('@/vendor/Export2Excel').then(excel => {
const tHeader = tHeaderArrShow;
const filterVal = tHeaderArrShow;
const list = this.tableData;
const data = this.formatJson(filterVal, list);
const date = new Date();
const filename =
date.toLocaleString().split(' ')[0] + '_' + date.getTime() + '';
excel.export_json_to_excel(tHeader, data, filename);
});
},
formatJson(filterVal, jsonData) {
return jsonData.map(v =>
filterVal.map(j => {
if(j === 'timestamp') {
return parseTime(v[j]);
}else {
return v[j];
}
})
);
},
showDataCount() {
this.showActive = 0;
this.showData = true;
},
// 打印报表功能实现
pringCharts() {
this.$print(this.$refs.c2);
},
pringChartsTwo() {
let imgSrcChange = this.printSrc
var imgDom = '<img src=\''+imgSrcChange+'\'>';
document.body.innerHTML = imgDom;
setTimeout(function() {
window.print()
}, 1000)
},
// 修改內容
testFunction() {
console.log(this.kenTitle)
let _this = this
let worldMapContainer = document.getElementById('main')
this.showActive = 1; // 点击图标按钮
this.showData = false; // 展示数据模块
var myChart = echarts.init(this.$refs.cc);
var resizeWorldMapContainer = function() {
worldMapContainer.style.width = window.innerWidth -400 + 'px';
// worldMapContainer.style.height = window.innerHeight + 'px';
worldMapContainer.style.height = 500 + 'px';
}
resizeWorldMapContainer()
// 指定图表的配置项和数据
let seriesData = [] // series的数据集合
let loopData = _this.kenData// 数据集合,数组对象
for(let i= 0; i< loopData.length; i++) {
let a = {}
a.name = _this.kenParams.one[i]
a.type = 'bar'
a.data = loopData[i]
a.itemStyle = {
normal: {
color: _this.kenParams.color[i] || ''
}
}
seriesData.push(a)
}
let echartsOption = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: [
{
type: 'category',
data: _this.kenTitle,
axisPointer: {
type: 'shadow'
},
axisLabel: {
interval: 0
}
}

],
legend: {
data: _this.kenParams.one,
bottom: '0%'
},
yAxis: [
{
type: 'value',
name: '数量',
min: 0,
max: _this.kenParams.interval[0],
interval: _this.kenParams.interval[1]
}
],
series: seriesData
}
myChart.setOption(echartsOption)
myChart.resize();
window.onresize = function() {
// 重置容器高宽
resizeWorldMapContainer();
myChart.resize();
};
setTimeout(() => {
let baseImg = myChart.getDataURL()
this.printSrc = baseImg;
}, 2000)
},
changeLoop() {
this.showActive = 0;
this.showData = true;
}
},
mounted() {
// this.showTable = this.tableData
// this.showSlot = this.slotList
}
};
</script>
<style scoped>
.showInfo{display:flex;}
.showInfo span{width: 14%;}
.el-input__prefix{right:5px}
.el-input__icon{float:right}
.showInfo{display: flex;padding-left:4%;line-height: 100px;border-bottom: 1px solid #ccc}
.showInfo span{margin-right:24px;}
.showInfo span{font-size: 18px;padding-left:12px;}
.switch{padding:0 16px;text-align: center;margin:0 auto;margin-top:10px;width:100%;display: inline-block;margin:20px 0;}
.switch span{display: inline-block;width: 80px;text-align: left;cursor: pointer;}
.switch span:last-child{text-align: center;padding-bottom:12px;}
.tableBox{margin-left:2%;}
.pageNub{text-align: center;margin-top:30px;}
.active{border-bottom: 1px solid #0094ff;}
.chartsBox{padding-left:4%;}
main{width: 600px;height:400px;}
.updataTimeS{cursor: default !important;}
</style>
<style>
.el-date-editor.el-input, .el-date-editor.el-input__inner{width: 156px;}
.el-input__inner{height: 32px;}
</style>








### 高德poi的使用

' ' '
html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>输入提示</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<style>
html,
body,
#container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<div class="info">
<div class="input-item">
<div class="input-item-prepend">
<span class="input-item-text" style="width:8rem;">请输入关键字</span>
</div>
<input id='tipinput' type="text">
</div>
</div>

<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.10&key=0e290c2877e27fab87d0f6a3be962b0e&plugin=AMap.Autocomplete"></script>
<script type="text/javascript" src="https://cache.amap.com/lbs/static/addToolbar.js"></script>
<script type="text/javascript">
var map = new AMap.Map('container');
AMap.plugin('AMap.Autocomplete', function(){
// 实例化Autocomplete
var autoOptions = {
//city 限定城市,默认全国
city: '全国'
}
let input = document.querySelector('#tipinput')
let container1 = document.querySelector('#container')
container1.style.opacity = '0';
input.onkeyup = function(e){
let keyword = input.value
var autoComplete= new AMap.Autocomplete(autoOptions);
autoComplete.search(keyword, function(status, result) {
// 搜索成功时,result即是对应的匹配数据
console.log(result)
})
}
})
</script>
</body>
</html>
注意点: 要使用webjsapi 的key值 而不是web服务的key值

文章目录
  1. 1. 子组件向父组件传递参数
  2. 2. ssh操作
    1. 2.0.1. 展开运算符
    2. 2.0.2. vue的条件判断
    3. 2.0.3. 报错信息
    4. 2.0.4. 判断上传文件类型的写法
    5. 2.0.5. 多段判断分析
    6. 2.0.6. 路由守卫使用vuex
    7. 2.0.7. beforeRouteUpdate(to,from,next)
    8. 2.0.8. Vue中动态类名的实现
    9. 2.0.9. 打印报表的实现
    10. 2.0.10. echarts转换base64的方法
      1. 2.0.10.0.1. form表单的提交有个浏览器的默认刷新行为,把form标签改成div就没事了
  3. 2.0.11. 一个vue页面使用2个style标签!
  4. 2.0.12. 将多维数组降级到一维数组的方法
  5. 2.0.13. 组件封装的注意点
  6. 2.0.14. vue组件设置样式的方法
  7. 2.0.15. 判断用户平台
  • 2.1. 封装的echarts组件
  • |