懂个锤子Vue 生命周期

Vue生命周期:

紧跟前文,目标学习Vue2.0——3.0: 懂个锤子VueWebPack5.0WebPack高级进阶 涉及的技术栈…

当然既然学习框架的了,HTML+CSS+JS三件套必须的就不说了: JavaScript 快速入门

Vue.js 的生命周期是指从组件实例创建到销毁的整个过程:

这个过程分为四个阶段:创建——挂载——更新——销毁 每个阶段都有相应的生命周期钩子函数;

创建阶段: 准备数据)

  • beforeCreate: 在实例初始化之后,进行数据侦听和事件/侦听器的配置之前同步调用;

    在这个阶段,数据是获取不到的,并且真实dom元素也是没有渲染出来的

  • created: 实例创建完成后立即调用,这一步实例已完成对选项的处理;

    意味着:数据侦听、计算属性、方法、事件/侦听器的回调函数,已被配置完毕,但,挂载阶段还没开始;

    此阶段,可以访问到数据了:但是页面中真实DOM还没有渲染出来;

    钩子函数:可以进行相关初始化事件的绑定、发送请求操作;

挂载阶段: 渲染模板)

  • beforeMount: 在挂载开始之前被调用:相关的 render 函数首次被调用;

    DOM即将渲染出来,与created钩子函数用法基本一致,可以进行相关初始化事件的绑定、发送ajax操作

  • mounted: 实例被挂载后调用,el 被新创建的 vm.$e 替换,如果根实例挂载到了一个元素上,vm.$el也在元素内;

    数据挂载完毕,真实dom元素已经渲染完成了,钩子函数内部可以做一些实例化相关的操作

更新阶段: 修改数据 → 更新视图)

  • beforeUpdate: 在数据发生改变后,DOM被更新之前被调用,适合在现有 DOM 将要被更新之前访问它;

    钩子函数不会立即执行: 当组件挂载完毕的时候,数据发生改变的时候,立马执行;

    钩子函数获取DOM的内容是更新之前的内容: .innerHTML

  • updated: 在数据发生改变后、虚拟DOM重新渲染、更新完毕之后被调用,适合执行依赖于 DOM 的操作;

    数据发现改变之后生成新的虚拟DOM,与之前的虚拟DOM进行比对,差异之后,就会进行真实DOM渲染;

    updated钩子函数内,可以获取:diff算法更新之后的DOM内容;

销毁阶段: 注销Vue实例,清理资源占用

  • beforeDestory: 实例销毁之前调用,在这一步,实例仍然可用;

    组件销毁的时候触发:钩子函数,可以做一些善后操作、清除一些初始化事件、定时器相关的东西;

  • destoryed: 实例销毁后调用:对应 Vue 实例的所有指令都被解绑、事件监听器被移除、所有的子实例也都被销毁

  • 注意: 卸载之后页面还存在,因为卸载并不会清理DOM,但此时VUE实例已经无法操作了;

  • 销毁操作: 有很多种通常是:关闭浏览器调用: Vue实例.$destroy();

在这里插入图片描述

生命周期钩子Demo

<body>
  <div id="app">
    <h3>{{ title }}</h3>
    <div>
      <button @click="count--">-</button>
        <span>{{ count }}</span>
      <button @click="count++">+</button>
    </div>
  </div>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        count: 100,
        title: '计数器'
      },
      //创建阶段: 准备数据)
      beforeCreate () {
        console.log('beforeCreate 响应式数据准备好之前', this.count)
      },
      created () {
        console.log('created 响应式数据准备好之后', this.count);
        //this.数据名 获取请求回来的数据,函数内可以开始发送始化渲染的请求了;
      },

      //挂载阶段: 渲染模板)
      beforeMount () { 
        console.log('beforeMount 模板渲染之前', document.querySelector('h3').innerHTML) },
      mounted () { console.log('mounted 模板渲染之后', document.querySelector('h3').innerHTML) },

      //更新阶段: 修改数据 → 更新视图)
      beforeUpdate () {
        console.log('beforeUpdate 数据修改了',this.count,',视图还没更新', document.querySelector('span').innerHTML) },
      updated () { console.log('updated 数据修改了',this.count,',视图已经更新', document.querySelector('span').innerHTML) },

      //卸载阶段: 注销Vue实例,清理资源占用
      beforeDestroy () {
        console.log('beforeDestroy, 卸载前')
        console.log('清除掉一些Vue以外的资源占用,定时器,延时器...')
      },
      destroyed () {
        console.log('destroyed卸载后: Vue实例失去活性,完全丧失功能,但并不会清理DOM')
      }
    })
  </script>
</body>

生命周期钩子函数案例:

介绍最常用的钩子函数: createdmounted 处于创建和挂载阶段、一般来说页面加载过程中执行、定义的操作;

updated 属于使用过程中执行的钩子函数,update更多会被计算属性、watcher 取而代之;

distroyed Vue实例销毁后调用,通常用于对资源的回收操作;

created应用:

Vue实例创建完成后调用,适合在此阶段进行数据初始化和网络请求,

注意事项datamethods 数据已经可用,但 DOM 还未生成,不能进行 DOM 操作;

Demo案例:created 中将 message 的值从 'Hello, Vue!' 修改为 'Hello, World!,定义一个初始化请求数据;

//因为内部涉及到异步操作,所以为了稳定执行顺序需要 async\await
async created () {
    console.log('created: 组件实例已创建');
    //发送请求获取数据,更新到 list 中,用于页面渲染 v-for
    const res = await axios.get('http://127.0.0.1:3000/news/list');
    this.list = res.data.data.newsList;
    //在 created 钩子中进行数据初始化
    this.newsTitle = 'M新闻';
},

mounted应用:

Vue实例挂载到 DOM 上后调用,适合在此阶段进行依赖于 DOM 的操作,如获取 DOM 元素、发起异步请求等;

Demo案例:mounted 钩子中使用 this.$nextTick 确保 DOM 已经完全渲染,然后将 <h1> 元素的颜色设置为蓝色

mounted() {
    console.log('mounted: 组件已挂载到 DOM');
    // 在 mounted 钩子中进行 DOM 操作
    this.$nextTick(() => {
        const h1Element = this.$el.querySelector('h1');
        h1Element.style.color = 'blue';
    });
}

小黑记账清单:

文档学习借鉴于黑马,但为了接口稳定,本人自己使用Express搭建了后端环境:

原黑马接口文档: https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058

<body>
  <div id="app">
    <div class="contain">
      <!-- 左侧列表 -->
      <div class="list-box">
        <!-- 添加资产 -->
        <form class="my-form">
          <input type="text" class="form-control" placeholder="消费名称" />
          <input type="text" class="form-control" placeholder="消费价格" />
          <button type="button" class="btn btn-primary">添加账单</button>
        </form>
        <table class="table table-hover">
          <thead>
            <tr>
              <th>编号</th>
              <th>消费名称</th>
              <th>消费价格</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>1</td>
              <td>帽子</td>
              <td>99.00</td>
              <td><a href="javascript:;">删除</a></td>
            </tr>
            <tr>
              <td>2</td>
              <td>大衣</td>
              <td class="red">199.00</td>
              <td><a href="javascript:;">删除</a></td>
            </tr>
          </tbody>
          <tfoot>
            <tr>
              <td colspan="4">消费总计: 298.00</td>
            </tr>
          </tfoot>
        </table>
      </div>
      
      <!-- 右侧图表 -->
      <div class="echarts-box" id="main"></div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    /**
     * 接口文档地址:学习借鉴于黑马,但为了接口稳定,本人自己使用Express搭建了后端环境;
     * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
     * 
     * 功能需求:
     * 1. 基本渲染
     * 2. 添加功能
     * 3. 删除功能
     * 4. 饼图渲染
     */
    const app = new Vue({
      el: '#app',
      data: {
        
      },
    })
  </script>
</body>

页面渲染:

页面渲染: 窗口打开立刻发送请求获取数据 created,拿到数据,存到data的响应式数据中,

结合数据,进行渲染 v-for,消费统计 —> 计算属性computed

请求接口: http://127.0.0.1:3000/goodsBill/goodsBillList

<!-- ....省略部分代码 -->
  <body>
    <div id="app">
      <div class="contain">
        <!-- 左侧列表 -->
        <div class="list-box">
          <table class="table table-hover">
            <thead>
              <tr>
                <th>编号</th>
                <th>消费名称</th>
                <th>消费价格</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(item,index) in list" :key="item.id" >
                <td>{{index+1}}</td>
                <td>{{item.name}}</td>
                <td>{{item.price}}</td>
                <td><a href="javascript:;">删除</a></td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <td colspan="4">消费总计: {{ totalPrice.toFixed(2) }}</td>
              </tr>
            </tfoot>
          </table>
        </div>
      </div>
    </div>
    <script>
      /**
       * 接口文档地址:学习借鉴于黑马,但为了接口稳定,本人自己使用Express搭建了后端环境;
       * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058 */
      const app = new Vue({
        el: '#app',
        data: {
          list:[],
        },
        computed: {
          totalPrice () { return this.list.reduce((sum, item) => sum + item.price, 0) }
        },
        async created () {
          const res = await axios.get('http://127.0.0.1:3000/goodsBill/goodsBillList');
          this.list = res.data.data
        }
      })
    </script>
  </body>
</html>

新增商品账单:

新增商品账单: 收集表单数据v-model (Vue优点直接获取数据,使用指令修饰符处理数据,

Vue实例中定义新增函数methods:{ add(){ ... } },并添加按钮注册点击事件:对输入的内容做非空判断,发送请求;

请求成功后,对文本框内容进行清空,并重新渲染列表数据,所以就需要重新请求goodsBillList,为了方便也可以定义函数;

优化:created中页面加载过程中的请求,调用:methods,created阶段:可以访问到数据、函数;

调用接口: http://127.0.0.1:3000/goodsBill/addgoodsBill{ 'name':'汪汪雪饼','price':5 }

<!-- ....省略部分代码 -->
  <body>
    <div id="app">
      <div class="contain">
        <!-- 左侧列表 -->
        <div class="list-box">
          <!-- 添加资产 -->
          <form class="my-form">
            <input type="text" class="form-control" placeholder="消费名称" v-model.trim="name" />
            <input type="text" class="form-control" placeholder="消费价格" v-model.number="price" />
            <button type="button" class="btn btn-primary" @click="add" >添加账单</button>
          </form>
          <!-- ....省略部分代码 -->
        </div>
      </div>
    </div>
    <script>
      /**
       * 接口文档地址:学习借鉴于黑马,但为了接口稳定,本人自己使用Express搭建了后端环境;
       * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058 */
      const app = new Vue({
        el: '#app',
        data: {
          list:[],
          name: '',
          price: ''
        },
        computed: {
          totalPrice () { return this.list.reduce((sum, item) => sum + item.price, 0) }
        },
        async created () {
          // const res = await axios.get('http://127.0.0.1:3000/goodsBill/goodsBillList');
          // this.list = res.data.data
          
          // 优化:created阶段:可以访问到数据、函数, 但是页面中真实DOM还没有渲染出来;
          // 所以可以调用methods中的请求接口函数,实现页面渲染,优化代码结构;
          this.getList();                                                                 //渲染数据;
        },
        methods: {
          //页面渲染:
          async getList(){
            const res = await axios.get('http://127.0.0.1:3000/goodsBill/goodsBillList');
            this.list = res.data.data;
          },
          //新增商品账单:
          async add(){
            // 验证数据非空\发送添加请求\重新渲染数据;
            if (!this.name) { return alert('请输入消费名称'); }
            if (typeof this.price !== 'number') { return alert('请输入正确的消费价格') }
            const res = await axios.post('http://127.0.0.1:3000/goodsBill/addgoodsBill', {  //发送添加请求
              name: this.name,
              price: this.price
            })
            this.getList();                                                                 //重新渲染数据;
            //置空数据
            this.name = ''
            this.price = ''
          },
          //删除商品账单:
          async del (id) { }
        }
      })
    </script>
  </body>
</html>

删除商品账单:

删除商品账单: 注册点击事件,获取当前行的id,根据id发送删除请求,重新渲染列表

调用接口: DELTE http://127.0.0.1:3000/goodsBill/delgoodsBill/:id

商品账单饼图渲染:

前端领域图形渲染:一定离不开的三方依赖:Apache ECharts 内置了丰富的图形组件,轻松的进行数据展示;

引入Echarts依赖: https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js

创建一个容器用于展示组件、mounted函数中DOM已经渲染完成,在其中初始化图形;

在每次数据修改之后,更新图形中的数据,重新渲染图形;

<!-- ....省略部分代码 -->
  <body>
    <div id="app">
      <div class="contain">
        <!-- 左侧列表 -->
        <!-- 右侧图表: 创建一个容器用于展示组件-->
        <div class="echarts-box" id="main"></div>
      </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
      /**
       * 接口文档地址:学习借鉴于黑马,但为了接口稳定,本人自己使用Express搭建了后端环境;
       * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058 */
      const app = new Vue({
        el: '#app',
        data: {
          list:[],
          name: '',
          price: ''
        },
        mounted(){
          //`mounted`函数中DOM已经渲染完成,在其中初始化图形;
          this.myChart = echarts.init(document.querySelector('#main'));                   
          this.myChart.setOption({
            // 大标题
            title: {
              text: '消费账单列表',
              left: 'center'
            },
            // 提示框
            tooltip: {
              trigger: 'item'
            },
            // 图例
            legend: {
              orient: 'vertical',
              left: 'left'
            },
            // 数据项
            series: [
              {
                name: '消费账单',
                type: 'pie',
                radius: '50%',
                data: [         
                  // { value: 1048, name: '球鞋' },
                  // { value: 735, name: '防晒霜' }
                ],
                emphasis: {
                  itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                  }
                }
              }
            ]
          })
        },
        methods: {
          //页面渲染:
          async getList(){
            const res = await axios.get('http://127.0.0.1:3000/goodsBill/goodsBillList');
            this.list = res.data.data;

            //在每次数据修改之后,更新图形中的数据,重新渲染图形;
            this.myChart.setOption({
              series: [
                {
                  data: this.list.map(item => ({ value: item.price, name: item.name}))
                }
              ]
            })  
          }
        }
      })
    </script>
  </body>
</html>


代码GZH回复: Vue生命周期

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java.慈祥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值