Day 06 Vue–生命周期
一、Vue实例的生命周期
从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,就是Vue实例的生命周期。
二、生命周期钩子
生命周期钩子:就是生命周期事件的别名。生命周期钩子又叫生命周期函数 也叫生命周期事件。
创建期间的生命周期函数:
三 钩子函数
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- update
- beforeDestroy
- destroyed
3.1 beforeCreate 和 created 钩子函数之间的生命周期。
在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到在 created 的时候数据已经和 data 属性进行绑定。但此时尚未挂载,el 还不可用。
3.2 created 和 beforeMount 之间的生命周期
在这一阶段,首先会判断对象是否有 el 选项(option)。如果有的话就继续向下编译;如果没有则停止编译,也就意味着停止了生命周期,直到在该 Vue 实例上调用 vm.$mount(el)。
- 如果 Vue 实例对象中有 template 选项,则将其作为模板编译成 render 函数。
- 如果没有 template 选项,则将外部 HTML(outerHTML)作为模板编译。
- 由此可以看出,template 中的模板优先级要高于 outerHTML 的优先级。
3.3 beforeMount 和 mounted 之间的生命周期。
可以看到此时是给 vue 实例对象添加 $el 成员,并且替换掉挂载的 DOM 元素。在之前的结果图中可以看到 beforeMount 之前 el 还是 undefined。
3.4 mounted
注意看之前代码生成的结果图:
从图中我们可以清楚地看到,在 mounted 之前,h1 中还是通过 {{message}} 来占位的,因为此时还没有被挂到页面上,还是 JavaScript 中的虚拟 DOM 形式存在的。在 mounted 之后才发生了变化。
5. beforeUpdate 和 updated 之间的生命周期
从图中我们可以看到,当 vue 中的数据发生改变,会触发对应组件的重新渲染(re-render),先后调用 beforeUpdate 和 updated 钩子函数。
继续做实验,我们在控制台中输入:
vm.message = '触发组件更新'
1
控制台输出为:
我们可以看到触发了这两个钩子函数。
这里需要注意的一点是,两个函数中的 data 都已经更新为 “触发组件更新”,那区别是什么呢?
注意:
这里的 update 指的是,view 层的 update,而不是 vue 对象中 data 属性的 update。所以,这两个函数都发生在 data 改变之后(很容易理解,因为就是 data 属性的改变才触发了这两个函数),区别是 beforeUpdate 发生在 view 层的改变之前,也就是页面还没有重新渲染,此时页面仍然显示 “Vue的生命周期”(beforeUpdate 也是在页面重新渲染前修改 data 的最后时机);而 updated 是发生在 view 层改变之后,也就是此时的页面已经重新渲染为 “触发组件更新”。
6. beforeDestroy 和 destroyed 之间的生命周期
beforeDestroy 是在实例被销毁之前调用,在这一步,实例仍然完全可以调用。
destroyed 函数在实例被销毁之后调用,此时 vue 实例指示的所有东西都会解绑,所有的事件监听器会被移除,所有的子实例也会被销毁。
二、补充定时任务和延迟任务
1、定时任务
setInterval(
function () {
alert(444)
},3000
)//每隔3s钟干什么事
2、延迟任务
setTimeout(
function () {
alert(33333)
},3000) //延迟3s钟干什么事
三、swiper轮播图的学习
1、首先加载插件
需要用到的文件有swiper-bundle.min.js和swiper-bundle.min.css文件,不同Swiper版本用到的文件名略有不同。可下载Swiper文件或使用CDN。
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<script src="dist/js/swiper-bundle.min.js"></script>
<link rel="stylesheet" href="dist/css/swiper-bundle.min.css">
<title>Title</title>
<style>
.swiper-container {
width: 60%;
height: 600px;
}
</style>
</head>
2、写正式代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<title>Title</title>
<style>
.swiper-container {
width: 60%;
height: 600px;
}
img {
width: 100%;
}
</style>
</head>
<body>
<div id="box">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data in datalist">
<img :src="data" alt="">
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: "#box",
data: {
datalist: []
},
mounted() {
//大坑
setTimeout(() => {
//this指的是function这个函数
//使用了箭头函数以后,this指的是上一层
this.datalist = [
"https://www.bing.com/th?id=OHR.TreCime_ZH-CN7609469681_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=HpEdgeAn",
"https://www.bing.com/th?id=OHR.TreCime_ZH-CN7609469681_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=HpEdgeAn",
"https://www.bing.com/th?id=OHR.TreCime_ZH-CN7609469681_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=HpEdgeAn",
"https://www.bing.com/th?id=OHR.TreCime_ZH-CN7609469681_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=HpEdgeAn"
];
}, 800);
},
updated() {
//只要js数据发生变化,组件就会执行updated方法,轮播图又会重新创建
var mySwiper = new Swiper(".swiper-container", {
// 自动轮播
autoplay: {
delay: 1000,//1秒切换一次
},
// direction: 'vertical', // 垂直切换选项
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: ".swiper-pagination"
},
// 如果需要前进后退按钮
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
}
});
//鼠标覆盖停止自动切换
mySwiper.el.onmouseover = function() {
mySwiper.autoplay.stop();
},
//鼠标离开开始自动切换
mySwiper.el.onmouseout = function() {
mySwiper.autoplay.start();
}
},
});
</script>
</html>
四、自定义指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<title>Title</title>
</head>
<body>
<div id="box">
<!-- <div v-mystyle> 我是div</div>-->
<!-- <p v-mystyle> 0pppp</p>-->
<!-- <p > sfasfsdafsd </p>-->
<div v-mystyle="'green'"> 我是div</div>
<div v-mystyle="'red'"> 我是div</div>
<div v-mystyle="color"> 我是div</div>
</div>
</body>
<script>
//自定义指令,不需要写v使用的时候,加上v-名字
// Vue.directive('mystyle', {
// inserted() { //在标签上使用这个指令,就会触发inserted的执行
// console.log('我执行了')
// },
// })
//只要使用了我的指令,背景就变红色
// Vue.directive('mystyle', {
// inserted(ev) { //ev就是dom对象
// ev.style.background='red'
// },
// })
//只要使用了我的指令,背景就变成我传入的颜色
Vue.directive('mystyle', {
inserted(ev, color) { //ev就是dom对象
console.log(ev)
console.log(color.value)
ev.style.background = color.value
},
update(el, input) {
el.style.background = input.value
}
})
var vm = new Vue({
el: '#box',
data: {
color: 'red'
},
})
</script>
</html>
五、过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<title>Title</title>
</head>
<body>
<div id="box">
<ul>
<li v-for="item in datalist">
<h2>{{item.nm}}</h2>
<p>主演是:{{item.star}}</p>
<!-- <img :src="geturl(item.img)" alt="">-->
<img :src="item.img | repUrl" alt="">
</li>
</ul>
</div>
</body>
<script>
Vue.filter('repUrl', function (url) {
return url.replace('w.h', '128.180')
})
var vm = new Vue({
el: '#box',
data: {
datalist: null
},
methods: {
geturl(url) {
return url.replace('w.h', '129.180')
}
},
mounted() {
axios.get("http://127.0.0.1:5000/").then(res => {
console.log(res.data)
this.datalist = res.data.coming
}).catch(err => {
console.log(err);
})
}
})
</script>
</html>
六、单文件组件
# 原来写的组件存在的问题
全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
# 以后每个组件就是一个 xx.vue-----最终----->html,css,js
并且还可以使用 webpack 构建工具
# CLI 会为你搞定大多数工具的配置问题
7 vue-cli
1 安装node(昨天装了),官网下载,一路下一步----》node,npm
2 淘宝镜像(cnpm,)npm install -g cnpm --registry=https://registry.npm.taobao.org
3 装完以后,本地就有cnpm命令,以后再装模块,就使用cnpm安装
2 cnpm install -g @vue/cli # -g 全局安装
3 装完以后就会走vue命令
4 通过vue命令创建项目
vue create 项目名(命令行下创建项目)
vue ui (图形化界面,点点点创建项目)
-点一点就会(bable,eslint)
注意:
新建的这些项目的本质是:cli从git上给你拉了一个空项目(模板),以后再模板上继续写就可以了
5 注意
vue:2.x
bable:兼容性相关(es6的语法,自动转成es5兼容浏览器)
eslint:语法检查,代码格式化
6 运行项目
npm run serve :在浏览器中访问
7 使用ide打开编写
pycharm打开
项目目录介绍
dist: 打包的项目目录(打包后会生成)
node_modules: 项目依赖(删掉,不上传git,使用npm install重新安装)
public: 共用资源
--favicon.ico
--index.html: 项目入口页面,单页面开发
src: 项目目标,书写代码的地方
-- assets:资源,静态图片
-- components:组件(swiper组件...)
-- views:视图组件(也是组件)
-- App.vue:根组件
-- main.js: 入口js
-- router.js: 路由文件
-- store.js: 状态库文件
vue.config.js: 项目配置文件(没有可以自己新建)
package.json:项目配置依赖(等同于python项目的reqirement.txt)
"scripts": {
"serve": "vue-cli-service serve", npm run serve 运行项目
"build": "vue-cli-service build", npm run build 构建项目---》html,css,js
"lint": "vue-cli-service lint" npm run lint 格式化代码
}