Vue-JS

Vue初始化函数created()和mounted()的区别

1、created 在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图

在这一步,实例已完成以下的配置:

  • 数据观测 (data observer),
  • property 和方法的运算,
  • watch/event 事件回调。
  • 然而,挂载阶段还没开始,$el property 目前尚不可用

2、mounted在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。


过滤函数filter()

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意:

  1. filter() 不会对空数组进行检测。
  2. filter() 不会改变原始数组。

语法:

1
array.filter(function(currentValue,index,arr), thisValue)

array数组的元素依次指向currentValue进行判断,符合条件即function返回true,则此元素被添加到新数组,否则不被添加。

返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。

例如:

1
2
3
4
5
6
7
8
9
10
11
<script>
var ages = [32, 33, 12, 40];

function checkAdult(age) {
return age >= 18;
}

function myFunction() {
return ages.filter(checkAdult);
}
</script>

返回一个年龄大于等于18的数组。

如果出现函数多重嵌套:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
var ages = [32, 33, 12, 40];

function checkAdult(a) {
return age => {
return age >= a;
}
}

function myFunction() {
var a = 18;
return ages.filter(checkAdult(a));
}
</script>

此时,ages数组中的元素依次指向的是age而不是a


Vue Events

事件名称 说明 回调参数
blur 在 Input 失去焦点时触发 (event: Event)
focus 在 Input 获得焦点时触发 (event: Event)
change 在 Input 值改变时触发 (value: string | number)
clear 在点击由 clearable 属性生成的清空按钮时触发
select(Autocomplete Events) 点击选中建议项时触发 选中建议项

Message消息提示

常用于主动操作后的反馈提示。

1
2
3
4
this.$message.info("");
this.$message.success("");
this.$message.warning("");
this.$message.error("");

MessageBox弹框

模拟系统的消息提示框而实现的一套模态对话框组件,用于消息提示、确认消息和提交内容。

从场景上说,MessageBox 的作用是美化系统自带的 alert、confirm 和 prompt,因此适合展示较为简单的内容。如果需要弹出较为复杂的内容,请使用 Dialog。

消息提示

调用$alert方法即可打开消息提示,它模拟了系统的 alert,无法通过按下 ESC 或点击框外关闭。此例中接收了两个参数,messagetitle。值得一提的是,窗口被关闭后,它默认会返回一个Promise对象便于进行后续操作的处理。若不确定浏览器是否支持Promise,可自行引入第三方 polyfill 或像本例一样使用回调进行后续处理。

1
2
3
4
5
6
7
8
9
this.$alert('这是一段内容', '标题名称', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'info',
message: `action: ${ action }`
});
}
});
确认消息

调用$confirm方法即可打开消息提示,它模拟了系统的 confirm。Message Box 组件也拥有极高的定制性,我们可以传入options作为第三个参数,它是一个字面量对象。type字段表明消息类型,可以为successerrorinfowarning,无效的设置将会被忽略。注意,第二个参数title必须定义为String类型,如果是Object,会被理解为options。在这里我们用了 Promise 来处理后续响应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});

说明:then()函数为用户点击“确定”之后进行的操作,catch()函数是用户点击”取消之后进行的操作。

提交内容

调用$prompt方法即可打开消息提示,它模拟了系统的 prompt。可以用inputPattern字段自己规定匹配模式,或者用inputValidator规定校验函数,可以返回BooleanString,返回false或字符串时均表示校验未通过,同时返回的字符串相当于定义了inputErrorMessage字段。此外,可以用inputPlaceholder字段来定义输入框的占位符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
this.$prompt('请输入邮箱', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
inputErrorMessage: '邮箱格式不正确',
inputPlaceholder: "email"
}).then(({ value }) => {
this.$message({
type: 'success',
message: '你的邮箱是: ' + value
});
}).catch(() => {
this.$message({
type: 'info',
message: '取消输入'
});
});

说明:{value}是从提示框中输入的值。


Notification通知

悬浮出现在页面角落,显示全局的通知提醒消息。

Notification 组件提供通知功能,Element 注册了$notify方法,接收一个options字面量参数,在最简单的情况下,你可以设置title字段和message字段,用于设置通知的标题和正文。默认情况下,经过一段时间后 Notification 组件会自动关闭,但是通过设置duration,可以控制关闭的时间间隔,特别的是,如果设置为0,则不会自动关闭。注意:duration接收一个Number,单位为毫秒,默认为4500

Element 为 Notification 组件准备了四种通知类型:success, warning, info, error。通过type字段来设置。

1
2
3
4
5
6
7
const h = this.$createElement;
this.$notify({
title: '标题名称',
message: h('i', { style: 'color: teal; font-size: 13px'}, '这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案'),
type: 'success'
duration: 0
});

注意:这里的h用于定义样式。


父子组件之间传值

1、父组件可以使用 props 把数据传给子组件
子组件

在子组件中定义props,用于接收父组件传来的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//子组件
props: {
data: String,
required: true
},
//或者
props:['data']

// 父组件
<chlid :data='message'></chlid>

data() {
return {
message: 'hellow world'
}
}

prop的类型

String、Number、Boolean、Array、Object

prop类型检测

default、required、自定义验证

2、子组件可以使用 $emit 触发父组件的自定义事件
$emit方法
1
2
3
this.$emit( event, arg ) //触发当前实例上的事件

this.$on( event, fn );//监听event事件后运行 fn;

evevt是父组件定义的事件,arg是子组件向父组件传的值。

注意:子组件中包含$emit方法的事件一旦触发,则父组件中的event事件自动触发。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//子组件
<button @click="change">click</button>

change(){
this.$emit('showchange', 'hellow');
}

//父组件
<child @showchange="getvalue">{{ value }}</child>

data(){
return {
value: ''
}
},
methods: {
getvalue(val){
this.value = val;
}
}

父子组件传值的其他方式

provide/inject

父组件中通过provide来提供变量, 然后在子组件中通过inject来注入变量。这里不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据。

注:provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

$refs

通过 ref 为子组件赋予一个 ID 引用:

1
2
//子组件
<base-input ref="usernameInput"></base-input>

父组件通过this.$refs.usernameInput获取到 DOM 元素和子组件实例。

$parent/$children

在子组件中使用$parent获取父组件中的数据,在父组件中使用$children[i](可能有多个子组件)获取子组件中的数据。

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
// 父组件
<template>
<Childone></Childone>
<Childtwo></Childtwo>
<button @click="getChildMsg()"></button>
</template>

<script>
import Childone from './childone'
import Childtwo from './childtwo'
export default{
components:{Childone, Childtwo},
data(){
return{
msgFromChild:'',
parentMsg:'123456'
}
}
methods:{
getChildMsg(){
this.msgFromChild = this.$children[1].child2Msg;
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 子组件
<template>
<P>{{msgFromParent}}</P>
<button @click="getParentMsg()"></button>
</template>

<script>
export default{
data(){
return{
child2Msg:'abc',
msgFromParent:''
}
}
methods:{
getParentMsg(){
this.msgFromParent = this.$parent.parentMsg;
}
}
}
</script>
vuex

在state里定义数据和属性,在 mutations里定义函数fn,在页面通过this.$store.commit('fn',params)来触发函数。

eventBus

在main.js里注册全局事件对象:

1
window.eventBus = new Vue();

在一个组件中传值:

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<span >{{ item }}</span>
<button @click="down(item)">下载</button>
</template>

<script>
methods:{
down(name){
eventBus.$emit('eventBusName', name);
}
}
</script>

在另一组件中监听:

1
2
3
eventBus.$on('eventBusName', function(name){
console.log(name);
});

Vue中img的src属性绑定问题

当我们希望从js的data中获取img的src的值时,应使用:src属性来绑定data中的值。

例如:

1
2
3
4
<img :src="imgUrl" alt="">

//data中的值
imgUrl: '../../../src/stalic/font/arrow0.png'

但是浏览器并没有渲染出来我的图片。原因:这里使用的是本地路径

解决方法

1、Vue项目中提供了一个static静态文件夹,用于我们存放一些静态文件,浏览器可直接渲染。所以,可以将图片放在static文件夹中。

1
imgUrl: ./stalic/arrow0.png,

2、Common写法,在路径前加上require

1
imgUrl: require('../../../src/stalic/font/arrow0.png')

3、把图片放在cdn上,把网络地址存在imgUrl里,然后直接<img :src="imgUrl">去展示。


ECharts

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

安装
1
npm install echarts -s
导入
1
const echarts = require('echarts');

我这里使用import echarts from 'echarts'无效。

使用
创建一个div并初始化图表
1
2
3
<div id="main"></div>

const myChart = echarts.init(document.getElementById('main'));
创建option选项
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
const option = {
// 图表标题
title: {text: '用户来源'},

// 鼠标停留在图表中时显示的提示信息
tooltip: {
trigger: 'axis',
axisPointer: {
// 触发提示信息的方法
type: 'cross',
label: {
backgroundColor: '#a0a0a0'
}
}
},

// 图例文字
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
// 设置文字竖直排列。默认为水平
orient: 'vertical',
x:'right', //可设定图例在左、右、居中
y:'center', //可设定图例在上、下、居中
padding:[0,50,0,0], //可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
},

// 网格布局
grid: {
// 距离边框的距离
left: '3%',
right: '4%',
bottom: '3%',
// grid 区域是否包含坐标轴的刻度标签,默认不包含(false)
containLabel: true,

},

// 横轴
xAxis: {
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},

// 纵轴
yAxis: {type: 'value'},

// 指明图表类型以及数据
series: [
{
name: '邮件营销',
type: 'line',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'line',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'line',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '直接访问',
type: 'line',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: '搜索引擎',
type: 'line',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
};
使用option
1
myChart.setOption(option);

在mounted中获取不到created中的值

问题描述

1.在created生命周期内进行异步数据的请求,且将获取到的数据赋值给this.data
2.此时如果在mounted生命周期里获取this.data是获取不到的

问题分析

因为异步加载需要时间,如果延迟时间是可以获取到数据的,但是问题是不知道需要延迟多久,况且这个方法也不是很好。

解决方法

data里面进行数据定义:

1
2
3
4
5
data(){
return {
dataList: ''
};
}

使用watch方法进行数据监听:

1
2
3
4
5
6
7
watch:{
dataList(){
this.$nextTick(()=>{
//此时就可以获取到在created赋值后的dataList了
})
}
}

eval

eval(“‘“ + data + “‘“)返回string类型

data 可以是任何类型,包括 unicode。

1
2
var str = "\\u6211\\u662Funicode\\u7F16\\u7801"; 
str = eval("'" + str + "'"); // string类型
eval(“(“ + data + “)”)返回object类型

原因:加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语句(statement)来执行。

当我们从后端接收到返回的json对象(data)时,会发现 data.messageundefined,我们可以将 data 转化为一个object 类型来解决。

1
2
var obj = eval("(" + data + ")");
console.log(typeof(obj)); // object

js定时器

setTimeout

为setTimeout 设置一个时间,等待时间到达的时候只执行一次,但是执行完以后定时器还在,只是不再运行。

1
const timer = setTimeout(function, time)

setTimeout是异步执行,第一个参数是待执行函数,第二个参数是等待时间。

通过执行clearTimeout()来取消定时器。

setInterval

setInterval是循环定时器,即设置一个时间间隔,每过一段时间都会循环执行这个方法,直到这个定时器被销毁掉。

1
const timer = setInterval(function, time)

setInterval也是异步执行,第一个参数是待执行函数,第二个参数是等待时间。

必须使用clearInterval()来销毁定时器,否则会无限循环。


vue 动态加载背景图片

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<tepmlate>
<div :style="style"></div>
</template>

<script>
data() {
return {
style: {
backgroundImage: 'url(' + require('../asserts/1.png') + ')',
backgroundRepeat: 'no-repeat'
}
}
}
</script>

注意:data 中不允许短横线命名,所以我们这里使用驼峰式命名。此外,图片地址需用 require 方法解析,否则渲染不出来。

如果我们把图片地址存放在一个变量或常量中时,直接用 require 方法解析这个变量或常量会报错,可以这样写:

1
2
3
4
5
6
7
8
9
data() {
return {
src: 'asserts/1.png',
style: {
backgroundImage: 'url(' + require("@/" + this.src) + ')',
backgroundRepeat: 'no-repeat'
}
}
}

至少应该有一个 @/


async 和 await

async

它作为一个关键字放到函数前面,用于表示函数是一个异步函数。我们写一个 async 函数:

1
2
3
async function f() {
  return 'hello world';
}

现在来调用它:

1
2
3
4
5
async function f() {
return 'hello world'
}
f();
console.log('虽然在后面,但是我先执行');

打开控制台会发现只输出了 “虽然在后面,但是我先执行”。但不应该第二行输出 “hello world” 吗?我们先看一下 f() 是什么:

1
console.log(f());

输出如下:

1
> Promise {<resolved>: "hello world"}

原来,async 函数返回的是一个 promise 对象,那么要想获取到 promise 的返回值,应该用 then 方法。修改代码如下:

1
2
3
4
f().then(result => {
console.log(result);
})
console.log('虽然在后面,但是我先执行');

控制台输出为:

1
2
虽然在后面,但是我先执行
hello world

因为 Promise 的 then 方法是异步的,所以先执行 console.log('虽然在后面,但是我先执行');

注意:如果 async 函数中有返回值 ,当调用该函数时,内部会调用Promise.resolve() 方法把它转化成一个 promise 对象作为返回,但如果函数内部抛出错误呢? 那么就会调用 Promise.reject() 返回一个promise 对象。

await

await 关键字只能放到 async 修饰的函数里面,它后面可以放任何表达式,不过我们更多的是放一个返回 promise 对象的表达式。

await 是等待的意思,那么它等待什么呢?它后面跟着什么呢?然我们来一探究竟。

看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function f(x) {
return new Promise((reslove, reject) => {
if (x >= 0) {
setTimeout(() => {
reslove("success");
}, 2000);
} else {
setTimeout(() => {
reslove("failed");
}, 2000);
}
})
}

async function fn() {
let res = await f(1);
console.log(res);
}

调用 fn() 函数,两秒之后,输出 “success”。

现在我们看看代码的执行过程:调用 fn 函数,它里面遇到了await,await 表示等一下,代码就暂停到这里,不再向下执行了,它等什么呢?等后面的 promise 对象执行完毕,然后拿到 promise resolve 的值并进行返回,返回值拿到之后,它继续向下执行。

所以,await 的作用就是将异步变为同步。然而由于 async 的作用,整个过程依旧是异步执行的,因此,async/await 的作用就是将异步编程风格变为同步编程风格,使代码更易读和调试。

使用 await 只会得到 resolve 的值,那怎么得到 reject 的值呢?可以使用 try…catch。

1
2
3
4
5
6
7
8
async function fn() {
try {
let res = await f(1);
console.log(res);
} catch (err) {
consloe.log(err);
}
}

js 获取屏幕分辨率和视口大小

屏幕分辨率
1
2
3
获取屏幕宽度:window.screen.width * window.devicePixelRatio

获取屏幕高度:window.screen.height * window.devicePixelRatio
视口大小
1
2
document.documentElement.clientWidth
document.documentElement.clientHeight