在业务运作时,特定的逻辑代码,需要在特定的阶段去执行,所以需要理解Vue的生命周期,以及各个周期内的方法,才能明确业务代码的编写
概述:Vue生命周期,指一个vue实例从创建到销毁的过程。
分为四个阶段:①创建-->②挂载-->③更新-->④销毁
①创建阶段 拿到数据准备好,进行响应式处理
②挂载阶段基于提供的数据和模板进行渲染,产生页面效果
③更新阶段 对页面进行操作,修改页面,会修改数据,对应着做数据修改,更新视图(这两个动作可以持续循环进行)
④销毁阶段 页面关闭,销毁实例
1、像官网首页那种进页面就要获取数据进行初始化渲染页面的请求,最早也要在创建阶段之后,在响应式数据准备好之后
2、若想要操作dom,至少也要等模板渲染出来,所以最早也要在挂载阶段之后
3、在整个vue的生命周期过程中,从一开始的创建到最后的销毁的一系列过程中,vue都提供了一系列函数,并且到了对应的生命阶段时,会去自动调用这些函数,而这四个阶段一共提供了八个函数(生命周期钩子)
4、有了这些生命周期钩子之后,开发者就可以在特定阶段去执行我们想执行的代码;如上面的1、就响应式的数据准备好之后想发初始化请求,可以写在创建阶段后的钩子里去执行,2、就可以把操作dom的代码写在挂载阶段后的钩子里去执行
这里可以用一个计数器来调这些函数,来演示一下
body代码:
<body>
<div id="app">
<h3>{{ title }}</h3>
<div>
<button @click="count--">-</button>
<span>{{ count }}</span>
<button @click="count++">+</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 100,
title: '计数器'
}
})
</script>
</body>
页面效果:
先写初级阶段的两个钩子,分别对应初级阶段前后,可以尝试故意在初级阶段前,也就是数据还没准备好的beforeCreat钩子里用this 去获取count,去调页面上的响应式数据:
beforeCreate () {
console.log('beforeCreate 响应式数据准备好之前调取count===>', this.count)
},
页面刷新重新加载,就会发现页面报undefined了,是肯定访问不到的啊,
所以切记,在创建阶段的beforeCreate 钩子里面对数据进行任何处理都是不合理的,至少要在created里面至少等数据有了再去操作,
// 1. 创建阶段(准备数据)
beforeCreate () {
console.log('beforeCreate 响应式数据准备好之前调取count===>', this.count)
},
created () {
console.log('created 响应式数据准备好之后', this.count)
// this.数据名 = 请求回来的数据
// 可以开始发送初始化渲染的请求了
},
如下图,这里在created里面获取count就有了, 所以在created里面才可以开始发送初始化渲染的请求
同样,可以在挂载阶段前后两个钩子里,去调H3这个模板,测试渲染成功没有
<h3>{{ title }}</h3>
代码(模板渲染之前调mountedbeforeMount钩子,模板渲染之后调mounted钩子):
// 2. 挂载阶段(渲染模板)
beforeMount () {
console.log('beforeMount 模板渲染之前', document.querySelector('h3').innerHTML)
},
mounted () {
console.log('mounted 模板渲染之后', document.querySelector('h3').innerHTML)
// 可以开始操作dom了
},
这里看到打印出来还是双花括号模板语法,说明在此时即挂载阶段之前的mounted 钩子里,模板是还没有被渲染的:
而在挂载阶段之后的mounted钩子里,再去取H3标签,就已经被渲染了,双花括号title就已经被换成了data里面的值:计算器,并将计算器 输出到控制台,所以如果想操作dom,至少要得到模板渲染之后的mounted 钩子里
小结:这里可以知道,当页面展示这个计数器的时候,其实就已经经历了创建阶段和挂载阶段,
// 3. 更新阶段可以测试点击计算器的加号,数据变化这个过程,(修改数据 → 更新视图)
beforeUpdate钩子执行的时候,数据修改了,视图还没更新, 而updated钩子执行时, 数据修改了,视图已经更新
// 3. 更新阶段(修改数据 → 更新视图)
beforeUpdate () {
console.log('beforeUpdate 数据修改了,视图还没更新', document.querySelector('span').innerHTML)
},
updated () {
console.log('updated 数据修改了,视图已经更新', document.querySelector('span').innerHTML)
},
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h3>{{ title }}</h3>
<div>
<button @click="count--">-</button>
<span>{{ count }}</span>
<button @click="count++">+</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 100,
title: '计数器'
},
// 1. 创建阶段(准备数据)
beforeCreate () {
console.log('beforeCreate 响应式数据准备好之前', this.count)
},
created () {
console.log('created 响应式数据准备好之后', this.count)
// this.数据名 = 请求回来的数据
// 可以开始发送初始化渲染的请求了
},
// 2. 挂载阶段(渲染模板)
beforeMount () {
console.log('beforeMount 模板渲染之前', document.querySelector('h3').innerHTML)
},
mounted () {
console.log('mounted 模板渲染之后', document.querySelector('h3').innerHTML)
// 可以开始操作dom了
},
// 3. 更新阶段(修改数据 → 更新视图)
beforeUpdate () {
console.log('beforeUpdate 数据修改了,视图还没更新', document.querySelector('span').innerHTML)
},
updated () {
console.log('updated 数据修改了,视图已经更新', document.querySelector('span').innerHTML)
},
// 4. 卸载阶段
beforeDestroy () {
console.log('beforeDestroy, 卸载前')
console.log('清除掉一些Vue以外的资源占用,定时器,延时器...')
},
destroyed () {
console.log('destroyed,卸载后')
}
})
</script>
</body>
</html>
功能需求:
1.基本渲染
2.添加功能
3.删除功能
4.饼图渲染
1.基本渲染
(1)思路:刚进页面首先要先发送请求,获取数据,其实所以在created生命周期钩子里面写get数据的方法
data: {
},
created (){
}
1)因为有引下面这个包,所以直接用await axios
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
2)然后get方法的第一个参数是url地址,因为get请求,像get和delete这种请求都需要传一个id,请求所以第二个请求参数要写到params里面以对象形式传过去,如下将创建者写到params里面
params:{
creator:'fly'
}
3)然后发现报错及详情:
async created (){
const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
params:{
creator:'fly'
}
})
// console.log(res)
}
4)解决报错后将获取数据通过控制台打印出来的效果如下:
(2)拿到数据,存到data的响应式数据中
1)要存到data里面,可以定义一个
const app = new Vue({
el: '#app',
data: {
mylist:[]
},
2)在created里面用myList来接收
this.mylist=res.data.data
目前代码
async created (){
const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
params:{
creator:'yang'
}
})
this.mylist=res.data.data
// console.log(res)
}
(3)页面结合数据,进行渲染,通常用v-for
1)连续编号用下标{{index+1}},金额若需要保留两位小数用toFixed( 2 )
<tr v-for="(item,index) in mylist" :key="item.id">
<td>{{index+1}}</td>
<td>{{item.name}}</td>
<td>{{item.price.toFixed(2)}}</td>
<td><a href="javascript:;">删除</a></td>
</tr>
2)已经写了一个类样式为"red" 这里加这个类的条件是金额大于500的大额数字,可以用:class
<tr v-for="(item,index) in mylist" :key="item.id">
<td>{{index+1}}</td>
<td>{{item.name}}</td>
<td :class="{red:item.price>=500}" >{{item.price.toFixed(2)}}</td>
<td><a href="javascript:;">删除</a></td>
</tr>
(4)下面的消费统计,用计算属性实现
<tfoot>
<tr>
<td colspan="4">消费总计: {{totalPrice.toFixed(2)}}</td>
</tr>
</tfoot>
const app = new Vue({
el: '#app',
data: {
myList:[]
},
computed:{
totalPrice(){
return this.myList.reduce((sum,item) => sum +item.price ,0);
}
},
2.添加功能
(1)收集表单数据 思路:输入框填写数据后,点击按钮会加到列表中,所以要考虑到输入框需要收集数据,所以要去data里面声明元素上面的表单元素用v-model将数据与数据做绑定即可
data: {
myList:[],
name:'',
price:''
},
<input type="text" v-model.trim="name" class="form-control" placeholder="消费名称" />
<input type="text" v-model.number="price" class="form-control" placeholder="消费价格" />
<button type="button" class="btn btn-primary">添加账单</button>
(2)给添加按钮注册点击事件,发送添加请求
代码如下
<button type="button" @click="add" class="btn btn-primary">添加账单</button>
methods:{
async add(){
const res=await axios.post('https://applet-base-api-t.itheima.net/bill',{
creator:'fly1',
name:this.name,
price:this.price
})
}
}
(3)数据改变后,页面需要基于新数据重新渲染,所以可以把查询数据渲染的方法封装起来,后面多次使用
3.删除功能
(1)给删除按钮注册点击事件,传id
<td><a href="javascript:;" @click="del(item.id)">删除</a></td>
(2)根据id发送删除请求,注意这里是直接在路径后面拼接id,id要用传过来的id,不写死所以用 ` ,然后用$接上id
del(id){
const res=axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
}
(3)重新渲染, // console.log(id) 下面的id要用传过来的id,不写死所以用 ` 然后用$接上id
del(id){
// console.log(id) 下面的id要用传过来的id,不写死所以用 ` 然后用$接上id
const res=axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
// console.log(res)
this.getList()
}
4.饼图渲染
第一步,想要基于数据动态实时生成饼图,就要先生成一个饼图
这里先引包
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>ECharts</title>
<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="echarts.js"></script>
</head>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
作业思路汇总:
1.基本渲染
2.添加功能
3.删除功能
4.饼图渲染
1.基本渲染
(1)一进页面首先要先发送请求,获取数据,所以在created生命周期钩子里面写get数据的方法
(2)拿到数据,存到data的响应式数据中
(3)页面结合数据,进行渲染,通常用v-for
(4)下面的消费统计,用计算属性实现
2.添加功能
3.删除功能
4.饼图渲染