Vue的生命周期
- beforeCreat
- created
- beforeCount
- counted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
beforeCreat:vue对象实例化完成,此时实例只有一些生命周期函数以及一些默认事件,data和methods未被初始化。
created:初始化了data和methods,最早可以在这个阶段获取到数据。
beforeMount:模板在内存中编辑完成,但是没有渲染到页面上,也就是说,如果绑定了data中的数据{{msg}}
,在这个阶段打印,仍然是{{msg}}
。
mounted:将模板渲染到了页面上,此时再打印,就是msg真实的数据。
beforeUpdate和updated会在数据发生改变时触发,beforeUpdate是内存中的数据改变了,但是没有同步更新到页面,updated完成了页面的数据更新。
beforeDestroy阶段,vue实例的数据和方法仍然可以正常访问,destroyed之后,就不能访问了。
CSS水平垂直居中的方法(行内元素?)
参考了CSS水平居中+垂直居中+水平/垂直居中的方法总结,这篇文章总结的很清楚。
首先,块级元素:
1.水平居中
(1)margin:0 auto;
,这个方法的前提是必须给元素添加宽度。
(2)子元素设置成行内块,父元素文本居中text-align: center;
(3)定位:子绝父相,子元素设置left:50%;transform:translateX(-50%)
left是让子元素最左边的一条线水平居中,translateX向左移动自身的一半,这就完成了整个子元素的居中。
(4)定位:子绝父相,子元素设置left:50%;margin-left:-自身宽度的一半px;
,这种方法也必须设置子元素的宽度。margin如果按百分值设置的话,默认是基于其父元素的宽度计算的,而不是自身宽度。
(5)flex布局:给要居中的父元素添加display: flex; justify-content: center;
2.垂直居中
(1)定位:子绝父相。子元素:top: 50%; transform: translateY(-50%);
(2)flex布局,父元素:display: flex; align-items: center;
其次,行内元素:
1.水平居中
(1)父元素设置:text-align: center;
,当然,父级必须要是块级元素或者行内块。
2.垂直居中
(1)行内元素(单行):行高等于盒子高度line-height
(2)行内元素(多行):表格布局,让父元素成为表格的单元格,也就是父元素设置display:table-cell;
和vertical-align: middle;
,子元素就会垂直居中。或者,父元素display:table;
,子元素display:table-cell;
vertical-align: middle;
再次,水平垂直居中:
(1)定位:子绝父相。子元素:top: 0; right: 0; bottom: 0; left: 0; margin: auto;
(2)定位:子绝父相。子元素:left: 50%; top: 50%; margin-left: -元素宽度的一半px; margin-top:-元素高度的一半px;
(3)定位:子绝父相。子元素:left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);
使用 transform的好处是,可以不知道子元素的宽高。
(4)flex布局:父元素:justify-content: center; align-items: center;
Vue组件之间的通信
父子组件
父传子:props传递数据,v-bind绑定数据
<body>
<div id="app">
<cpn v-bind:cmovies="movies" :cmessage='message'></cpn>
</div>
<template id="cpn">
<div>
{{cmovies}}
{{cmessage}}
</div>
</template>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//父传子props props写在子组件里
//子组件
const cpn = {
template: '#cpn',
//props: ['cmovies', 'cmessage'],//props有很多种数据类型
props: {
//cmovies:Array,
//cmessage:String//要求必须是string类型
cmessage: {
type: String,
default: 'aaa', //默认值 如果没有传cmessage,就会显示默认值
required: true //true必须传这个值,不传会报错
},
//类型是对象或者数组时,默认值必须是一个函数
cmovies: {
type: Array,
default () {
return []
}
}
},
data() {
return {} //子组件的data必须是一个函数,不然所有子组件的数据都一样了,他们需要有自己的数据
}
}
//这里根组件相当于父组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王', '海贼王', '海尔兄弟']
},
components: {
//属性增强写法
cpn
}
})
</script>
</body>
注意:props在传参的时候,名称必须是小写字母,不要用驼峰命名。因为v-bind在绑定的时候,属性名要求小写。
子传父:自定义事件$emit
1.在子组件中,通过$emit()来触发事件
2.在父组件中,通过v-on来监听子组件事件
<div id="app">
<cpn @itemclick="cpnClick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item.name)">{{item.name}}</button>
</div>
</template>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [{
id: 'aaa',
name: '热门推荐'
},
{
id: 'bbb',
name: '手机数码'
},
{
id: 'ccc',
name: '家用电器'
}
]
}
},
methods: {
btnClick(item) {
//发射事件
this.$emit('itemclick', item)
}
}
}
//父组件
const app = new Vue({
el: '#app',
components: {
cpn
},
methods: {
cpnClick(item) {
console.log('itemclick', item);
}
}
})
</script>
兄弟组件
没有回答出来┗|`O′|┛ 嗷~~
Vuex、EventBus
作用域插槽
父组件替换插槽的标签,但是内容是由子组件来提供的。也就是子组件的数据传到父组件中。
<body>
<div id="app">
<cpn>
<!-- 如果不想以原来li的方式进行展示 -->
<!-- 父组件不能直接访问 pLanguage-->
<template slot-scope="slot">
<!-- 以 - 的方式展示 -->
<span v-for="item in slot.data">{{item}} -</span>
</template>
</cpn>
<cpn></cpn>
<cpn @show='fun'>
{{language}}
</cpn>
</div>
<template id="cpn">
<div>
<slot v-bind:data='pLanguage'>
<ul>
<li v-for="item in pLanguage">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
const cpn={
template: '#cpn',
data() {
return {
pLanguage: ['JS', 'c++', 'c语言', 'Java']
}
},
created(){
this.emit()
},
methods:{
emit(){
this.$emit('show',this.pLanguage);
}
}
}
const app = new Vue({
el: '#app',
data(){
return{
isShow: true,
language:[]
}
},
methods:{
fun(item){
this.language=item
}
},
components: {
cpn
}
})
</script>
</body>
第一个cpn是以作用域插槽的方法使得父组件访问到子组件的数据,并改变了展示方式,第二个cpn是默认展示,不存咋传递数据,就是子组件在访问子组件作用域内的数据,第三个cpn是以$emit的方式让子组件传递数据给父组件,只是以数组的形式展示。
es6语法
- 箭头函数
- const定义常量 let定义变量
- class类的概念
- 解构赋值
- for in 和for of的遍历方式
- Promise
- 。。。。。。
es6中Array的扩展方法
(1)扩展运算符:可以将数组拆分成以逗号分隔的参数序列
let arr=['a','b','c'];
console.log(...arr);// a b c
扩展运算符可以应用于合并数组:
let arr1=[1,2,3];
let arr2=[4,5,6];
let arr3=[...arr1,...arr2];
console.log(arr3)// [1, 2, 3, 4, 5, 6]
或者:
arr1.push(...arr2);//push可以接受多个参数,相当于push(4,5,6)
console.log(arr1);// [1, 2, 3, 4, 5, 6]
利用扩展运算符可以将类数组转换为真正的数组:
var oDivs=document.getElementsByTagName('div');
console.log(oDivs);// oDivs是伪数组,[div, div, div, div]
var arr=[...oDivs];
console.log(arr);// [div, div, div, div]
将伪数组转换成真正的数组之后,它就能调用数组的方法了。
(2)Array.from()方法:将伪数组转换为数组
var arrLike={
'0':'张三',
'1':'李四',
'2':'王五',
'length':3
};
console.log(Array.from(arrLike));
注意:伪数组中必须含有length属性,否则输出为一个空数组。
Array.from()方法可以接收第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,返回处理后的数组。
var arrLike={
'0':'1',
'1':'2',
'2':'3',
'length':3
};
console.log(Array.from(arrLike,item=>{
return item*2;// [2, 4, 6]
}));
(3)Array.find()方法:找出第一个符合条件的数组成员,如果没有找到,返回undefined
let array=[{
id:1,
age:17
},{
id:2,
age:18
},{
id:3,
age:19
}];
let target=array.find((item,index)=>item.id==2);//省略了return
console.log(target);// {id: 2, age: 18}
(3)Array.findIndex()方法:找出第一个符合条件的数组成员位置,如果没有找到,返回-1
let array2=[10,20,30];
let target2=array2.findIndex((item,index)=>item>=20);
console.log(target2)// 1
数组的第二个元素是第一个符合条件的,它的下标是1。
(4)Array.includes():数组是否包含给定的值,返回值是布尔类型
console.log([1,2,3].includes(1))// true
console.log([1,2,3].includes(4))// false