Vue2系列(lqz)——Vue生命期钩子、组件
文章目录
Vue声明期钩子
表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数钩子函数: 满足特点条件被回调的方法
8个生命周期函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<child v-if="isShow"></child>
</div>
</body>
<script>
Vue.component('child', {
template: `<div>
child-->div
<button @click="name='egon'">点我变egon</button>
<button @click="name='lqz'">点我变lqz</button>
<br>
{{name}}
</div>`,
data() {
return {
name: 'lqz',
t: null,
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
//用的最多,向后端加载数据,创建定时器等
console.log("页面已被vue实例渲染, data, methods已更新");
console.log('mounted')
this.t = setInterval(function () {
console.log('daada')
}, 3000)
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeDestroy() {
console.log('created')
},
destroyed() {
//组件销毁,清理定时器
clearInterval(this.t)
this.t = null
console.log('destoryed')
},
})
var vm = new Vue({
el: '#box',
data: {
isShow: true
}
})
</script>
</html>
组件
1 fetch和axios
axios与fetch实现数据请求
(1)fetch(不是所有浏览器都支持,谷歌浏览器支持)XMLHttpRequest 是一个设计粗糙的 API,配置和调用方式非常混乱,而且基于事件的异步模型写起来不友好。 兼容性不好polyfill: https://github.com/camsong/fetch-ie8
1.1 fetche使用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fetch</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<button @click="handleClick()">获取影片信息</button>
<ul>
<li v-for="data in datalist">
<h3>{{data.name}}</h3>
<img :src="data.poster"/>
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el: "#box",
data: {
datalist: []
},
methods: {
handleClick() {
//https://m.maizuo.com/v5/?co=mzmovie#/films/nowPlaying
fetch("./json/test.json").then(res => res.json()).then(res => {
console.log(res.data.films)
this.datalist = res.data.films
})
}
}
})
/*
// post-1
fetch("**",{
method:'post',
headers: {
"Content‐Type": "application/x‐www‐form‐urlencoded"
},
body: "name=kerwin&age=100",
credentials:"include"
}).then(res=>res.json()).then(res=>{console.log(res)});
// post-2
fetch("**",{
method:'post',
headers: {
"Content‐Type": "application/json"
},
body: JSON.stringify({
myname:"kerwin",
myage:100
})
}).then(res=>res.json()).then(res=>{console.log(res)});
*/
</script>
</body>
</html>
1.2 axios的使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios</title>
<script type="text/javascript" src="js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="box">
<button @click="handleClick()">正在热映</button>
<ul>
<li v-for="data in datalist">
<h3>{{data.name}}</h3>
<img :src="data.poster"/>
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
datalist:[]
},
methods:{
handleClick(){
axios.get("./json/test.json").then(res=>{
console.log(res.data.data.films) // axios 自动包装data属性 res.data
this.datalist = res.data.data.films
}).catch(err=>{
console.log(err);
})
}
}
})
</script>
</body>
</html>
2 计算属性
复杂逻辑,模板难以维护
(1) 基础例子
(2) 计算缓存 VS methods-计算属性是基于它们的依赖进行缓存的。-计算属性只有在它的相关依赖发生改变时才会重新求值
(3) 计算属性 VS watch
- v-model3
2.1 通过计算属性实现名字首字母大写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!--大段的代码写在这里不好,使用计算属性-->
{{mytext.substring(0,1).toUpperCase()+mytext.substring(1)}}
<p>计算属性:{{getname}}</p>
<!--普通方法要加括号-->
<p>普通方法:{{getNameMethod()}}</p>
<!--区别是在同一个页面中使用多次计算属性,不会多次执行-->
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
mytext:'lqz',
},
computed:{
getname(){//依赖的状态改变了,会重新计算
console.log('计算属性')
return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
}
},
methods:{
getNameMethod(){
console.log('普通方法')
return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
}
}
})
</script>
</html>
2.2 通过计算属性重写过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<p><input type="text" v-model="mytext" @input="handleChange"></p>
<ul>
<li v-for="data in newlist">{{data}}</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
mytext: '',
datalist: ['aaa', 'abc', 'abcde', 'abcdef', 'bbb', 'bac'],
},
computed: {
newlist() {
var newlist = this.datalist.filter(item => {
return item.indexOf(this.mytext) > -1
})
return newlist
},
},
})
</script>
</html>
3 Mixins
混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
4 虚拟dom与diff算法 key的作用
4.1 Vue2.0 v-for 中 :key 有什么用呢?
其实呢不只是vue,react中在执行列表渲染时也会要求给每个组件添加key这个属性。
key简单点来说就是唯一标识,就像ID一样唯一性
要知道,vue和react都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。
只做同层级的对比
按照key值比较,出现新的key就插入
通组件对比
4.2 虚拟DOM的diff算法
4.3 具体实现
4.3.1 把树按照层级分解
4.3.2 同key值比较
4.3.3 通组件对比
<div id="box">
<div v-if="isShow">111</div>
<p v-else>222</p>
<!--
{tag:div,value:111}
{tag:p,value:222}
直接不比较,直接删除div,新增p
-->
<div v-if="isShow">111</div>
<div v-else>222</div>
<!--
{tag:div,value:111}
{tag:div,value:222}
比较都是div,只替换文本内容
-->
</div>
https://segmentfault.com/a/1190000020170310
5 组件化开发基础
5.1 组件是什么?有什么用
扩展 HTML 元素,封装可重用的代码,目的是复用
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
6 组件注册方式
1 全局组件
Vue.component
2 局部组件
6.1 定义全局组件,绑定事件,编写样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<navbar></navbar>
</div>
</body>
<script>
//没有代码提示,语法检查,目前这么用
//后面会使用webpack打包,直接定义成 xx.vue文件,通过webpack打包
Vue.component('navbar',{
template:`
<div>
<button @click="handleClick">返回</button>
我是NavBar
<button style="background: red">主页</button>
</div>
`,
methods:{
handleClick(){
console.log('nav nav')
}
}
})
var vm = new Vue({
el: '#box',
data: {
},
})
</script>
</html>
6.2 定义局部组件
Vue.component('navbar', {
template: `
<div>
<button @click="handleClick">返回</button>
我是NavBar
<button style="background: red">主页</button>
<br>
<child></child>
</div>
`,
methods: {
handleClick() {
console.log('nav nav')
},
},
components: {
child: {
template: `<button>儿子</button>`,
}
}
})
7 组件编写方式与Vue实例的区别
1 自定义组件需要有一个root element,一般包裹在一个div中
2 父子组件的data是无法共享
3 组件可以有data,methods,computed....,但是data 必须是一个函数
Vue.component('navbar', {
template: `
<div>
<button @click="handleClick">返回</button>
我是NavBar{{aa}}
<button style="background: red">主页</button>
<br>
<child></child>
</div>
`,
methods: {
handleClick() {
console.log('nav nav')
},
},
components: {
child: {
template: `<button>儿子</button>`,
}
},
data(){
return {
aa:'lqz'
}
},
})
8 组件通信
1 父子组件传值 (props down, events up)
2 父传子之属性验证props:{name:Number}Number,String,Boolean,Array,Object,Function,null(不限制类型)
3 事件机制a.使用 $on(eventName) 监听事件b.使用 $emit(eventName) 触发事件
4 Ref<input ref="mytext"/> this.$refs.mytext
5 事件总线var bus = new Vue();* mounted生命周期中进行监听
8.1 父子通信之父传子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!--保证属性名和props中的属性名和变量名一致即可-->
<navbar myname="lqz"></navbar>
<navbar myname="egon"></navbar>
<!--注意数据绑定-->
<navbar :myname="egon"></navbar>
<!--可以传多个,但是注意,传入的isshow是字符串,可以使用数据绑定变成布尔-->
<navbar :myname="egon" isshow="false"></navbar>
<navbar :myname="egon" :isshow="false"></navbar>
</div>
</body>
<script>
//没有代码提示,语法检查,目前这么用
//后面会使用webpack打包,直接定义成 xx.vue文件,通过webpack打包
Vue.component('navbar', {
template: `
<div>
<button>返回</button>
父组件传递的内容是:{{myname}}
<button>主页</button>
<br>
</div>
`,
props:['myname']
})
var vm = new Vue({
el: '#box',
data: {},
})
</script>
</html>
属性验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<navbar myname="egon" :isshow="false"></navbar>
<!--报错-->
<navbar myname="egon" isshow="false"></navbar>
</div>
</body>
<script>
Vue.component('navbar', {
template: `
<div>
<button>返回</button>
父组件传递的内容是:{{myname}}
传入的布尔是{{isshow}}
<button>主页</button>
<br>
</div>
`,
// props:['myname'],
props:{
myname:String,
isshow:Boolean,
},
})
var vm = new Vue({
el: '#box',
data: {},
})
</script>
</html>
8.2 父子通信之子传父(通过事件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
子组件中监听自定义事件,随便起名
<!-- <navbar @myevent="handleClick"></navbar>-->
<navbar @myevent="handleClick($event)"></navbar>
</div>
</body>
<script>
Vue.component('navbar', {
template: `
<div>
<button>返回</button>
组件
<button @click="handleEvent">点击按钮把子组件数据传递到父组件</button>
<br>
</div>
`,
data(){
return {
name:'lqz'
}
},
methods:{
handleEvent(){
// this.$emit('myevent') //myevent:子组件中监听自定义事件
this.$emit('myevent',100) //100表示传递的参数
}
}
})
var vm = new Vue({
el: '#box',
data: {},
methods:{
handleClick(ev){
console.log('点击子组件,我会执行')
console.log(ev)
}
}
})
</script>
</html>
8.3 通过子传父控制字组件显示隐藏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
普通方式
<button @click="isShow=!isShow">点击隐藏显示</button>
<navbar v-show="isShow"></navbar>
<hr>
字传父方式
<mybutton @myevent="handleShow"></mybutton>
<navbar v-show="isShow"></navbar>
</div>
</body>
<script>
Vue.component('mybutton', {
template: `
<div>
<button @click="handleClick">点我隐藏显示</button>
</div>
`,
methods: {
handleClick() {
this.$emit('myevent')
}
}
})
Vue.component('navbar', {
template: `
<div>
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</div>
`,
data() {
return {
name: 'lqz'
}
},
methods: {
handleEvent() {
// this.$emit('myevent') //myevent:子组件中监听自定义事件
this.$emit('myevent', 100) //100表示传递的参数
}
}
})
var vm = new Vue({
el: '#box',
data: {
isShow: true
},
methods: {
handleShow() {
this.isShow=!this.isShow
}
}
})
</script>
</html>
8.4 ref属性
ref放在标签上,拿到的是原生节点
ref放在组件上,拿到的是组件对象,
通过这种方式实现子传父(this.$refs.mychild.text)
通过这种方式实现父传子(调用子组件方法传参数)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!-- 通过ref,获取input的值-->
<input type="text" ref="mytext">
<button @click="handleClick">点我</button>
<child ref="mychild"></child>
</div>
</body>
<script>
Vue.component('child',{
template:`<div>child</div>`,
data(){
return {
text:'子组件数据'
}
},
methods:{
add(){
console.log('子组件的add方法')
}
}
})
var vm = new Vue({
el: '#box',
data: {
},
methods: {
handleClick() {
console.log(this)
//this.$refs.mytext 获取到input控件,取出value值
console.log(this.$refs.mytext.value)
console.log(this.$refs.mychild.text)
// this.$refs.mychild.add()
this.$refs.mychild.add('传递参数')
}
}
})
</script>
</html>
8.5 事件总线(不同层级的不通组件通信)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<child1></child1>
<child2></child2>
</div>
</body>
<script>
var bus=new Vue() //new一个vue的实例,就是中央事件总线
Vue.component('child1', {
template: `<div>
<input type="text" ref="mytext">
<button @click="handleClick">点我</button>
</div>`,
methods:{
handleClick(){
bus.$emit('suibian',this.$refs.mytext.value) //发布消息,名字跟订阅消息名一致
}
}
})
Vue.component('child2', {
template: `<div>
<div>收到的消息 {{msg}}</div>
</div>`,
data(){
return {msg:''}
},
mounted(){
//生命周期,当前组件dom创建完后悔执行
console.log('当前组件dom创建完后悔执行')
//订阅消息
bus.$on('suibian',(item)=>{
console.log('收到了',item)
this.msg=item
})
}
})
var vm = new Vue({
el: '#box',
data: {},
methods: {
handleClick() {
console.log(this)
//this.$refs.mytext 获取到input控件,取出value值
console.log(this.$refs.mytext.value)
console.log(this.$refs.mychild.text)
// this.$refs.mychild.add()
this.$refs.mychild.add('传递参数')
}
}
})
</script>
</html>
9 动态组件
1 <component> 元素,动态地绑定多个组件到它的 is 属性
2 <keep-alive> 保留状态,避免重新渲染
9.1 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<ul>
<li><a @click="who='child1'">首页</a></li>
<li><a @click="who='child2'">商品</a></li>
<li><a @click="who='child3'">购物车</a></li>
</ul>
<component :is="who"></component>
</div>
</body>
<script>
var bus = new Vue() //new一个vue的实例,就是中央事件总线
Vue.component('child1', {
template: `<div>
首页
</div>`,
})
Vue.component('child2', {
template: `<div>
商品
</div>`,
})
Vue.component('child3', {
template: `<div>
购物车
</div>`,
})
var vm = new Vue({
el: '#box',
data: {
who:'child1'
},
})
</script>
</html>
9.2 keep-alive使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<ul>
<li><a @click="who='child1'">首页</a></li>
<li><a @click="who='child2'">商品</a></li>
<li><a @click="who='child3'">购物车</a></li>
</ul>
<keep-alive>
<component :is="who"></component>
</keep-alive>
</div>
</body>
<script>
var bus = new Vue() //new一个vue的实例,就是中央事件总线
Vue.component('child1', {
template: `<div>
首页
</div>`,
})
Vue.component('child2', {
template: `<div>
商品
<input type="text">
</div>`,
})
Vue.component('child3', {
template: `<div>
购物车
</div>`,
})
var vm = new Vue({
el: '#box',
data: {
who:'child1'
},
})
</script>
</html>
Vue2系列(lqz)——Vue生命期钩子、组件的更多相关文章
- Vue生命周期 钩子函数和组件传值
Vue生命周期 钩子函数 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等. 同时在这个过程中也会运行一 ...
- Vue生命周期钩子---2
vue生命周期简介 咱们从上图可以很明显的看出现在vue2.0都包括了哪些生命周期的函数了. 生命周期探究 对于执行顺序和什么时候执行,看上面两个图基本有个了解了.下面我们将结合代码去看看钩子函数的执 ...
- vue生命周期钩子
转载自:https://segmentfault.com/a/1190000008010666?utm_source=tag-newest https://segmentfault.com/a/119 ...
- vue生命周期 钩子函数
首先,1.x和2.x的生命周期钩子对比: 钩子函数的树状图,红色的是我们可以利用的函数,绿色的是函数解析,蓝色的是函数执行时机 <!DOCTYPE html> <html> & ...
- vue 生命周期钩子函数
实例中的生命周期钩子可以分为以下8种情况: beforeCreate: 实例刚被创建,vue所有属性都还不存在 created: 实例创建完成,但$el还不存在 beforeMount:挂载之前 mo ...
- Vue生命周期钩子---3
vue生命周期流程图:4张图 : 生命周期的解析和应用: Vue 实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom→渲染.更新→渲染.卸载等一系列过程,我们称这是 Vue ...
- 对vue生命周期/钩子函数的理解
对于实现页面逻辑交互等效果,我们必须知晓vue的生命周期,才能愉快的玩耍,知道我们写的东西应该挂载到哪里,vue官方给出的api讲解的那叫一个简单啊,如下: 所有的生命周期钩子自动绑定this上下文到 ...
- vue 生命周期钩子
每个vue实例被创建时都会经历一系列初始化的过程,像是一个生命从无到有的过程,所以叫生命周期,而这个过程都有对应的不同阶段,也就对应了生命周期不同的钩子函数,这些生命周期函数,作为vue实例的属性使用 ...
- vue 生命周期钩子 过滤器 计算属性
每一个Vue实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测.编译模板.挂载实例到DOM,然后在数据变化时更新DOM,在这个过程中,实例也会调用一些生命周期钩子,这就给我们提供了 ...
- 关于 vue 生命周期 钩子函数 事件
vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染->更新->渲染.卸载等一系列过程,我们称这是vue的生命周期. 通俗的将就是vue实例从创建到销毁 ...
随机推荐
- go语言编写算法
1.冒泡排序 // 冒泡排序 a := []uint8{9, 20, 10, 23, 7, 22, 88, 102} for i := 0; i < len(a); i++ { for k := ...
- Yolov5代码解析(输入端、BackBone、Neck、输出端))
[深度学习]总目录 输入端:数据增强.锚框计算等. backbone:进行特征提取.常用的骨干网络有VGG,ResNet,DenseNet,MobileNet,EfficientNet,CSPDark ...
- MVC 模式和三层架构
1. MVC 模式 MVC 模式和三层架构是一些理论的知识,将来我们使用了它们进行代码开发会让我们代码维护性和扩展性更好. MVC 是一种分层开发的模式,其中: M:Model,业务模型,处理 ...
- 【技术积累】Spring Boot中的基础知识【一】
写在前面 笔者在学校里学习Spring项目的时候,基本上都是老师照着书念PPT,然后演示一些有限的课堂案例,笔者印象很深刻,学校里整个Spring项目也就做了留个课堂练习,而且难度基本上属于连接上数据 ...
- 加密流量识别检测(一)——在VM虚拟机上搭建指定拓扑
- 一文帮你搞定H5、小程序、Taro长列表曝光埋点
对于很多前端同学来说,"埋点"常常是一个不愿面对却又无法逃避的话题.为什么这么说呢,相信很多前端同学都深有体会:首先埋点这个事基本是前端"独享"的,服务端基本不 ...
- base64详解
base64详解 前置知识 位与字节 二进制系统中,每个0或1就是一个位(bit,比特),也叫存储单元,位是数据存储的最小单位. 其中8bit就称为一个字节(Byte). 1B=8位 位运算 与运算: ...
- linux内核编译中常用的目标(二)
文章目录 一. 目标 all 或者 空 二. 目标 vmlinux 三. 目标 modules 四. 目标 Image/zImage/uImage 1.Image和zImage的区别 2.uImage ...
- Unity自定义类使用携程--自身不继承MonoBehaviour
[TOC] 参考: https://www.jianshu.com/p/67f498cb839b 话不多说,直接上代码 1 using System.Collections; 2 using Unit ...
- python(django启动报错,之编码问题)UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 0: invalid start byte