vue生命周期和vue组件
vue生命周期
官方的生命周期图
简易图
从vue实例创建开始直到实例被销毁,总共经历了8个生命周期钩子【只要写了就会执行】函数
钩子:反序列化验证---》钩子函数
学名[专门名字]---》面向切面编程(AOP)
OOP:面向对象编程
# 重点
1 用的最多的,created 发送ajax请求----》有的人放在mounted中加载
2 beforeDestroy
组件一创建,created中启动一个定时器
组件被销毁,beforeDestroy销毁定时器
八个生命周期钩子函数
函数 | 释义 |
---|---|
beforeCreate | 创建Vue实例之前调用 |
created | 创建Vue实例成功后调用(可以在此处发送异步请求后端数据) |
beforeMount | 渲染DOM之前调用 |
mounted | 渲染DOM之后调用 |
beforeUpdate | 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) |
updated | 重新渲染完成之后调用 |
beforeDestroy | 销毁之前调用 |
destroyed | 销毁之后调用 |
<script>
var vm = new Vue({
el: '.app',
data: {
name: 'sss'
},
methods: {},
beforeCreate() {
console.group('当前状态:beforeCreate')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
created() {
console.group('当前状态:created')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
beforeMount() {
console.group('当前状态:beforeMount')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
mounted() {
console.group('当前状态:mounted')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
beforeUpdate() {
console.group('当前状态:beforeUpdate')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
updated() {
console.group('当前状态:updated')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
// 如果写在Vue实例上,后面这俩是看不到的----》使用组件演示8个生命周期
beforeDestroy() {
console.group('当前状态:beforeDestroy')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
destroyed() {
console.group('当前状态:destroyed')
console.log('当前el状态:', this.$el)
console.log('当前data状态:', this.$data)
console.log('当前name状态:', this.name)
},
})
</script>
练习
# 实现实时聊天效果(在线聊天室)
-轮询:定时器+ajax http:http版本区别
-长轮询:定时器+ajax http
-websocket协议:服务端主动推送消息
https://zhuanlan.zhihu.com/p/371500343
vue组件
组件开发的好处------重用代码
组件分类
-
全局组件
在任意组件中都可以使用
Vue.component('child', { template: ` <div> <button>后退</button> <span style="font-size: 40px">首页--{{ name }}</span> <button @click="handleFor">前进</button> <lqz1></lqz1> </div>`,// 里面写html内容,必须包在一个标签中 data() { // data必须是方法,返回对象 return { name: '彭于晏', t: null } }, methods: { handleFor() { this.name = 'lqz' } }, components: { 'lqz1': { template: ` <div> <h1>局部组件---{{ age }}</h1> </div>`, data() { return { age: 19 } } }, } })
-
局部组件
只能在当前组件中使用
var foo={ template: ` <div> <h1>局部组件---{{ age }}</h1> </div>`, data() { return { age: 19 } } } var vm = new Vue({ ... components: { foo } })
组件总结
根组件与组件
- 根组件:产生一个new Vue()实例---》管理一个div标签
- 自定在定义的全局,局部是组件
- 组件有自己的html,css,js----》可绑定一些属性和事件来控制组件的变化
- 在组件中,this--->代指当前组件
- 父子组件的data是无法共享数据的
- data是一个函数,需要有返回值(return)
JavaScript七种数据类型
类型 | 释义 | python对应的类型 |
---|---|---|
String | 表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串 。 | 字符串 |
Number | Number 类型采用 IEEE754 标准中的 “双精度浮点数” 来表示一个数字,不区分整数和浮点数 。 | 整型 |
Boolean | true 和 false | 布尔常量 |
Symbol | ES6 新增的一种原始数据类型,它的字面意思是:符号、标记。代表独一无二的值 | |
Undefined | 未定义的值,是js中特殊的原始数据类型 | |
Null | 空值,表示一个对象被人为的重置为空对象,而非一个变量最原始的状态,内存中中null是处于游离状态 | |
Object | 引用类型,ECMA262 把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。 |
在 ECMAScript 规范中,引用类型除 Object 本身外,Date、Array、RegExp 也属于引用类型 。
案例
<h2>String类型 age='age'</h2>
<child age="age"></child>
<h2>String类型 age='19'</h2>
<child age="19"></child>
<h2> Number类型 :age='19'</h2>
<child :age="19"></child>
<h2> Number类型 :age='age'</h2>
<child :age="age"></child>
组件间通信
父子组件之间的数据不共享的,需要进行数据传输有三种方式,分别是自定义属性、自定义事件和使用ref属性实现两者数据共享。
1.组件间通信之父传子---自定义属性--props
- 父传子
采用自定义属性--父传子
1.通过自定义属性---自定义的变量不能用驼峰,不要与子组件中的变量冲突
父组件里 <child :age="age" ></child>
2. 子组件中引用props,可以指定自定义属性的类型,也可以直接用数组
props:{age:Number}
<body>
<div class="app">
<child :age="age" ></child>
</div>
</body>
<script>
// 父中有age,子child 只有name,没有age,现在把父中的age传到child中,显示
var child={
template:`
<div>
<button>后退</button>
首页---名字:{{name}}---年龄:{{age}}
<button>前进</button>
</div>`,
data(){
return{
name:'kiki'
}
},
props:{age:Number}
}
var vm = new Vue({
el:'.app',
data:{
age:19
},
components:{
child
}
})
</script>
-
属性验证---传入的必须JavaScript的七种数据类型
如果子组件有相同变量mynam值,组件里的标签内属性myname优先用子组件里面的变量myname。如果想调用父组件标签的变量,需要在
props
指明props: {age: Number, myname: String} <body> <div class="app"> <child :age="age" myname="成和花" ></child> </div> </body> <script> // 父中有age,子child 只有name,没有age,现在把父中的age传到child中,显示 var child={ template:` <div> <button>后退</button> 首页---名字:{{myname}}---年龄:{{age}} <button>前进</button> </div>`, data(){ return{ myname:'kiki' } }, props:{age:Number,myname: String} } var vm = new Vue({ el:'.app', data:{ age:19 }, components:{ child } }) </script>
2.组件间通信之子传父---自定义事件
想要子组件传给父组件数据共享
逻辑:
页面是子组件,有一个按钮触发事件,子组件的触发事件触发了父组件的函数, 子组件 <button @click="handleSend">点我传递</button>
在子组件触发自定义事件对应的触发函数(函数在父组件中)并传参数给父组件的变量数据。
<child @myevent="handleEvent"></child>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<p>子组件传递过来的数据:{{mytext}}</p>
<hr>
<child @myevent="handleEvent"></child>
</div>
</body>
<script>
var child={
template:`
<div>
<input type="text" v-model="mytext">
<button @click="handleSend">点我传递</button>
</div>`,
data(){
return{
mytext:''
}
},
methods:{
handleSend(){
// // 子组件中,触发自定义事件的执行,会执行父组件自定义事件绑定的函数,有几个参数,就传几个参数
this.$emit('myevent',this.mytext)
}
}
}
var vm = new Vue({
el:'.app',
data:{
mytext:''
},
methods:{
handleEvent(mytext){
//mytext是子组件传过来的,并赋值给父组件的mytext
this.mytext=mytext
}
},
components:{
child
}
})
</script>
</html>
流程:
1.子组件触发点击事件
<button @click="handleSend">点我传递</button>
2.子组件点击事件触发的函数触发了自定义事件的触发
methods:{
handleSend(){
this.$emit('myevent',this.mytext)//触发了自定义事件
3.触发并赋值
<child @myevent="handleEvent"></child>
handleEvent(mytext){
//mytext是子组件传过来的,并赋值给父组件的mytext
this.mytext=mytext
3.ref属性---实现父子组件通信
自定义属性和自定义事件可以实现父子传值,同时ref也可以实现。
1.ref
写在普通标签上,通过this.$refs.myinput
拿到的标签的dom对象
通过this.$refs
可以拿到标签上写了ref
属性的标签,对象属性key值是ref
对应的value
值,value
值是原生的dom
对象
<button @click="handleClick">点我显示数据</button>---》{{age}}
<input type="text" ref="myinput">
// 直接修改原生dom对象的value属性,input就能看到有值了
this.$refs.myinput.value='我该了值'
-
ref属性写在组件上,通过
this.$refs.mychild
拿到的是子组件对象 -------常用方法可以操作子组件对象的属性和方法,
子传父`this.age=this.$refs.mychild.age` 父传子`this.$refs.mychild.age=this.age`
重点:以后可以不用关注是父传子还是子传父,直接通过组件对象使用即可
代码展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<button @click="handleClick">点我显示数据</button>---》{{age}}
<br>
<input type="text" ref="myinput">
<br>
<div ref="mydiv">我是div</div>
<hr>
<child ref="mychild"></child>
</div>
</body>
<script>
// 父中有age,子child 只有name,没有age,现在把父中的age传到child中,显示
var child={
template:`
<div>
<h1>名字:{{name}}---->年龄:{{age}}</h1>
<button @click="handleClick">点我弹出名字</button>
</div>`,
data(){
return{
name:'kiki',
age:18
}
},
methods:{
handleClick(){
alert(this.name)
}
}
}
var vm = new Vue({
el:'.app',
data:{
age:19
},
methods:{
handleClick() {
// 1 ref 属性放在普通标签上,拿到标签的dom对象
// 通过this.$refs可以拿到所有标签上写了ref属性的 标签 ,对象类型 key值是ref对应的value值, value值是原生dom对象
// console.log(this.$refs)
// 直接修改原生dom对象的value属性,input就能看到有值了
// this.$refs.myinput.value='我改了值'
//2 ref 属性放在 组件上,拿到的是 组件对象 ,就可以使用组件对象的属性和方法
console.log(this.$refs) // 对象中有3个值,两个普通标签,一个组件
this.$refs.mychild // 就是组件对象,可以 .属性, .方法
this.age=this.$refs.mychild.age
// 重点:以后就不需要关注是子传父还是父传子了,直接通过对象取值赋值即可,而且可以主动调用子组件中的函数
this.$refs.mychild.handleClick() //触发子组件的点击事件
}
},
components:{
child
}
})
</script>
</html>
4.localstorage\sessionstorage\cookie
把数据保存在localstorage\sessionstorage\cookie,可以存数据、获取数据以及进行数据的修改和删除。用户登录的token就是存在cookie中,详细跳转https://www.cnblogs.com/zhanglanhua/p/17142806.html
5.Vuex插件
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
详情请前往https://www.cnblogs.com/zhanglanhua/p/17142779.html
动态组件
通过点击上面的组件可以实现的效果
1.不使用动态组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<span @click="handldClick('home')">首页</span> | <span @click="handldClick('order')" >订单</span> | <span @click="handldClick('goods')">商品</span>
<home v-if="type=='home'"></home>
<order v-else-if="type=='order'"></order>
<goods v-else></goods>
</div>
</body>
<script>
var home={
template:`
<div>
<h1>home页面</h1>
</div>
`}
var order={
template:`
<div>
<h1>order页面</h1>
</div>
`}
var goods={
template:`
<div>
<h1>goods页面</h1>
</div>
`}
var vm = new Vue({
el:'.app',
data:{
type:'home',
},
methods:{
handldClick(type){
this.type=type
}
},
components:{
home,
order,
goods
}
})
</script>
</html>
2.动态组件--component
<component :is="who"></component>
通过动态组件控制传过来的参数是哪个,就执行那个组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<span @click="handldClick('home')">首页</span> | <span @click="handldClick('order')" >订单</span> | <span @click="handldClick('goods')">商品</span>
<component :is="who"></component>
</div>
</body>
<script>
var home={
template:`
<div>
<h1>home页面</h1>
</div>
`}
var order={
template:`
<div>
<h1>order页面</h1>
</div>
`}
var goods={
template:`
<div>
<h1>goods页面</h1>
</div>
`}
var vm = new Vue({
el:'.app',
data:{
who:'home',
},
methods:{
handldClick(type){
this.who=type
}
},
components:{
home,
order,
goods
}
})
</script>
</html>
3.keep_alive 包裹动态组件,能保持动态组件里的内容不被销毁
<keep-aliv>
<component :is="who"></component>
</keep-aliv>
计算属性
-
input输入单词,首字母转成大写展示
<input type="text" v-model="mytext">--->{{mytext.slice(0,1).toUpperCase()+mytext.slice(1)}}
-
input输入单词,首字母转成大写展示----函数方式
只要页面刷新(加载页面),函数就会执行,无论跟函数是否有关系,
// 插值语法直接调用函数 <input type="text" v-model="mytext">--->{{getUpper()}} // vue直接编写函数带返回值 methods:{ getUpper(){ return this.mytext.slice(0,1).toUpperCase()+this.mytext.slice(1) }
-
计算属性--computed----》配置项
里面写方法------》方法当属性来用,不加括号,只要computed里面的方法才能不加括号,一定要有返回值。
<h1>计算属性</h1> <input type="text" v-model="mytext">--->{{newText}} <br> <input type="text" v-model="age">--->{{age}} // 计算属性---->computed 里面写方法,以后,方法当属性用 ,一定要有return值 computed :{ newText(){ console.log('执行了计算属性') return this.mytext.slice(0,1).toUpperCase()+this.mytext.slice(1) } }
代码展示
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<!-- <h1>首字母大写</h1>-->
<!-- <input type="text" v-model="mytext">-–>{{mytext.slice(0,1).toUpperCase()+mytext.slice(1)}}-->
<!-- <h1>input输入单词,首字母转成大写展示---函数方式---》只要页面刷新,无论跟它有没有关,都会重新运算</h1>-->
<!-- <input type="text" v-model="mytext">-–>{{getUpper()}}-->
<h1>计算属性</h1>
<input type="text" v-model="mytext">--->{{newText}}
<br>
<input type="text" v-model="age">--->{{age}}
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
mytext:'',
age:19,
},
methods:{
getUpper(){
return this.mytext.slice(0,1).toUpperCase()+this.mytext.slice(1)
}
},
// 计算属性---->computed 里面写方法,以后,方法当属性用 ,一定要有return值
computed :{
newText(){
console.log('执行了计算属性')
return this.mytext.slice(0,1).toUpperCase()+this.mytext.slice(1)
}
}
})
</script>
</html>
- 计算属性重写过滤案列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<h1>过滤案件</h1>
<p>请输入要搜索的内容:<input type="text" v-model="myText" ></p>
<ul>
<li v-for="item in newList"> {{item}}</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
myText:'',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
},
methods:{
},
computed:{
newList(){
return this.dataList.filter(item=>item.indexOf(this.myText)>=0)
}
},
})
</script>
</html>
监听属性---watch
在data中定义了一些变量,只要变量发生了变化,就执行一个函数
// 监听属性
watch:{
course_type(){
console.log('我变化了')
this.getData()
}
}
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue.js"></script>
</head>
<body>
<div class="app">
<!-- <span @click="handleClick(1)">Python</span> | <span @click="handleClick(2)" >Java</span>-->
<span @click="course_type=1">Python</span> | <span @click="course_type=2" >Java</span>
<div>
假设有很多课程,点击上面的标签可以完成过滤
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
course_type:'0',
age:19,
},
created(){
this.getData()
},
methods:{
getData(){
// 发送ajax ,获取所有课程,通过course过滤
// http://127.0.0.1:8080/api/v1/courses?course_type=0
},
// // 基本方法
// handleClick(type){
// this.course_type=type
// console.log('基础方法')
// this.getData()
// },
},
// 监听属性
watch:{
course_type(){
console.log('我变化了')
this.getData()
}
}
})
</script>
</html>
总结目前学过的配置项
- el(template)
- data :组建中 方法
- methods
- 8个生命周期钩子
- components
- watch
- computed
补充知识
-
之前前后端交互使用
xml
格式 -
后来json格式,格式出现,前后端交互,主流都是json格式
可能觉得返回给前端页面的数据是可以看到的---响应内容
有些会采用前后端加密解密的方式去保证数据的安全,但是麻烦又慢,一般都不会选择的
-
目前有些比json更安全/高效/节约空间的编码格式,后期前后端交互使用其他的编码格式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了