1、Vue 2.5版本的slot slot-scope和2.6版本的v-slot
- slot:插槽(开辟一个空间,给未来的元素使用)
- 用法:在组件中所写的标签解析的时候会被模板覆盖,无法显示,使用slot可以解决这个问题
<template id="hello">
<div>
<h3> 这里是hello组件 </h3>
<slot></slot>
</div>
</template>
//小拓展
new Vue({
el:'#app' //挂载
})
new Vue({
}).$mount('#app') // 手动挂载
- slot-具名插槽
- 用法:指定slot给具体的元素使用,可以改变布局。
<div id="app">
<Hello>
/* 添加 slot属性,属性值等于模板中所设置的name值 */
<header slot="header">头部</header>
<footer>底部</footer>
</Hello>
</div>
<template id="hello">
<div>
/* 给slot设置name值 */
<slot name="header"></slot>
<h3> 这里是hello组件 </h3>
<slot></slot>
</div>
</template>
- slot-scope 作用域插槽
<div id="app">
<Hello>
/* 使用slot-scope接收数据 */
<span slot-scope="data">
{{ data.msg }}
</span>
</Hello>
</div>
<template id="hello">
<div>
<h3> 这里是hello组件 </h3>
/* 将数据绑定到slot的身上 */
<slot :msg="msg"></slot>
</div>
</template>
- 2.6版本的v-slot
- 用途:v-slot的目的是将slot组件身上的数据传递给绑定的未来元素
<div id="app">
<Hello>
/* 以下为v-slot的用法 */
<template v-slot:default = "data">
<p> {{ data.msg }} </p>
</template>
</Hello>
</div>
<template id="hello">
<div>
<h3> 这里是hello组件 </h3>
/* 将数据绑定到slot的身上 */
<slot :msg="msg"></slot>
</div>
</template>
2、组件的生命周期(组件的钩子)
-
为什么要使用生命周期?可以把这个过程类比为人类的生活阶段:幼儿园 小学 初中 高中 大学 社会
-
我们想要使用组件,那么就得在组件的特定阶段完成特点的任务 【 特定时间点,完成特点任务 】
-
组件的生命周期分为三个阶段: 初始化、运行中、销毁 【共有8个钩子函数】
ps:生命周期钩子不允许写成箭头函数,因为箭头函数会改变this指向
-
初始化
- beforeCreate(){}
- 组件即将创建
- 任务: 初始化事件,并且为整个生命周期的开始做准备
- 意义:
- 数据未获取,真实dom未拿到
- 数据请求,数据修改**
- created(){}
- 组件创建结束
- 任务: 进行数据的注入和数据的反应
- 意义:
- 数据拿到了,真实dom没有拿到
- 数据请求,数据修改
- beforeMount () {}
- 组件即将挂载
- 任务: 判断组件是否有el/template选项,如果有那么使用render函数将template模板中的jsx转换成VDOM对象模型,如果没有,需要我们使用$mount/outerHTML手动挂载
- 意义:
- 更多的是内部完成任务,我们外部就不干预了
- 数据请求,数据修改
- mounted () {}
- 组件挂载结束
- 任务: 将vdom渲染为真实dom,然后挂载到页面中,这个时候我们在页面中可以看到内容了
- 意义:
- 操作真实dom 【 可以进行第三方库实例化 】
- 数据请求,数据修改
总结:
1、我们常将数据请求写在 created 中,因为created钩子是第一次获得数据的地方
2、mounted钩子函数可以进行DOM操作【 第三方库实例化【静态数据】 】
- beforeCreate(){}
-
运行中
- beforeUpdate 组件更新前
- 触发条件: 组件的数据发生改变
- 任务: VDOM重新生成,然后通过diff算法和以前的VDOM比对,生成patch补丁对象 【 内部进行 】
- updated 组件更新结束
- 触发条件: 组件的数据发生改变
- 任务: 将patch补丁对象进行渲染生成真实dom
- 意义:
- 可以操作DOM 【 第三方库的实例化【 动态数据 】 】
总结:
1、 平时大家使用updated进行第三方库实例化
- beforeUpdate 组件更新前
-
销毁
- 意义: 用来完成善后工作 【 计时器, 第三库实例, window.onscroll等 】
- 组件的销毁有两种形式
- 内部销毁
- 组件会被销毁掉,但是组件的DOM外壳还在
- 外部销毁
- 通过开关销毁 【 推荐 】
- 内部销毁
- 组件的销毁会触发两个钩子函数【 没什么差别, 任意选择一个使用 】
- beforeDestroy () {} 销毁前
- destroyed () {} 销毁结束
-
3、生命周期相关案例
- swiper+Vue实现轮播图
- swiper:https://www.swiper.com.cn/
<body>
<div id="app">
<input type="text" v-model="num">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="item in banners" :key="item.id">
<img :src="item.img" style="width: 100%;height: 100%;" />
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- 如果需要滚动条 -->
<div class="swiper-scrollbar"></div>
</div>
</div>
</body>
<script src="../../../lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
banners: [],
num: 100
},
created() {
fetch('./data/banner.json')
.then(res => res.json())
.then(data => {
this.banners = data
/*方案2
采用定时器将其放入队列,异步执行
setTimeout(() => {
common代码部分
},0)
*/
/*方案3
Vue中提供了一个 $nextTick:this.$nextTick Vue.nextTick
Vue中nextTick表示DOM更新结束之后执行
*/
//this.$nextTick(()=>{})
Vue.nextTick(() => {
//以下代码即为common代码
this.mySwiper = new Swiper('.swiper-container', {
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// 如果需要滚动条
scrollbar: {
el: '.swiper-scrollbar',
},
})
})
})
.catch(error => console.log(error))
},
updated() {
console.log('updated')
/* 方案1
if( this.mySwiper ) return false
*/
//common代码省略
},
destroyed() {
delete this.mySwiper
}
})
</script>
总结:
1、数据请求 + 数据修改 created中写
2、静态数据第三方库实例化: mounted
3、动态数据第三方库实例化: updated【 要做判断 ,避免重复实例化】 三种方案: Vue.nextTick【 this.$nextTick】 /setTimeout
4、善后工作: destroyed 【否则会一直存在在内存中】
4、自定过滤器
- 过滤器是对已有数据进行格式化
- 过滤器也可以传递参数
- 过滤器要使用管道符才能起作用
- 过滤器分类
- 全局过滤器 Vue.filter(过滤器名称,回调函数)
<div id="app">
/* 过滤器的使用:要格式化的数据 | 过滤器名称 */
<p> {{ time | dateFilter('*') }} </p>
</div>
Vue.filter('dateFilter', (val, type) => { //val就是我们要过滤的数据(接收的time)
var date = new Date(val)
return date.getFullYear() + type + (date.getMonth() + 1) + type + date.getDate()
})
new Vue({
el: '#app',
data: {
time: Date.now()
}
})
- 局部过滤器 filters选项
<div id="app">
<p> {{ time | dateFilter('*') }} </p>
</div>
new Vue({
el: '#app',
data: {
time: Date.now()
},
filters: {
// 过滤器名称: 回调函数
'dateFilter': (val, type) => {
var date = new Date(val)
return date.getFullYear() + type + (date.getMonth() + 1) + type + date.getDate()
}
}
})