Vue2基础四、生命周期

news2024/11/17 13:34:56

零、文章目录

Vue2基础四、生命周期

1、生命周期

  • Vue生命周期:一个Vue实例从 创建销毁 的整个过程。
  • 生命周期四个阶段:① 创建 ② 挂载 ③ 更新 ④ 销毁
    • 创建阶段:创建响应式数据
    • 挂载阶段:渲染模板
    • 更新阶段:修改数据,更新视图
    • 销毁阶段:销毁Vue实例

1682065937815

2、生命周期钩子

  • Vue生命周期过程中,会自动运行一些函数,被称为【生命周期钩子】
  • 让开发者可以在【特定阶段】运行自己的代码

1682066040295

<!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>

3、案例-mounted获取焦点

  • mounted应用:输入框获取焦点

image-20230706161107976

<!DOCTYPE html>
<html lang="zh-CN">

<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>示例-获取焦点</title>
    <!-- 初始化样式 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset.css@2.0.2/reset.min.css">
    <!-- 核心样式 -->
    <style>
        html,
        body {
            height: 100%;
        }
        
        .search-container {
            position: absolute;
            top: 30%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
        }
        
        .search-container .search-box {
            display: flex;
        }
        
        .search-container img {
            margin-bottom: 30px;
        }
        
        .search-container .search-box input {
            width: 512px;
            height: 16px;
            padding: 12px 16px;
            font-size: 16px;
            margin: 0;
            vertical-align: top;
            outline: 0;
            box-shadow: none;
            border-radius: 10px 0 0 10px;
            border: 2px solid #c4c7ce;
            background: #fff;
            color: #222;
            overflow: hidden;
            box-sizing: content-box;
            -webkit-tap-highlight-color: transparent;
        }
        
        .search-container .search-box button {
            cursor: pointer;
            width: 112px;
            height: 44px;
            line-height: 41px;
            line-height: 42px;
            background-color: #ad2a27;
            border-radius: 0 10px 10px 0;
            font-size: 17px;
            box-shadow: none;
            font-weight: 400;
            border: 0;
            outline: 0;
            letter-spacing: normal;
            color: white;
        }
        
        body {
            background: no-repeat center /cover;
            background-color: #edf0f5;
        }
    </style>
</head>

<body>
    <div class="container" id="app">
        <div class="search-container">
            <img src="./img/logo.png" alt="">
            <div class="search-box">
                <input type="text" v-model="words" id="inp">
                <button>百度一下</button>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                words: ''
            },
            // 核心思路:
            // 1. 等input框渲染出来 mounted 钩子
            // 2. 让input框获取焦点 inp.focus()
            mounted() {
                document.querySelector('#inp').focus()
            }
        })
    </script>

</body>

</html>

4、案例-小黑记账清单

(1)功能需求

image-20230706162228312

(2)实现细节

1.基本渲染

  • 拿到数据,存到data的响应式数据中
  • 结合数据,进行渲染 v-for
  • 消费统计 —> 计算属性

2.添加功能

  • 收集表单数据 v-model,使用指令修饰符处理数据
  • 给添加按钮注册点击事件,对输入的内容做非空判断
  • 添加成功后,对文本框内容进行清空

3.删除功能

  • 注册点击事件,获取当前行的id
  • 根据id删除数据

4.饼图渲染

  • 初始化一个饼图 echarts.init(dom) mounted钩子中渲染
  • 根据数据试试更新饼图 echarts.setOptions({…})

(3)代码实现

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- CSS only -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
    <style>
        .red {
            color: red!important;
        }
        
        .search {
            width: 300px;
            margin: 20px 0;
        }
        
        .my-form {
            display: flex;
            margin: 20px 0;
        }
        
        .my-form input {
            flex: 1;
            margin-right: 20px;
        }
        
        .table> :not(:first-child) {
            border-top: none;
        }
        
        .contain {
            display: flex;
            padding: 10px;
        }
        
        .list-box {
            flex: 1;
            padding: 0 30px;
        }
        
        .list-box a {
            text-decoration: none;
        }
        
        .echarts-box {
            width: 600px;
            height: 400px;
            padding: 30px;
            margin: 0 auto;
            border: 1px solid #ccc;
        }
        
        tfoot {
            font-weight: bold;
        }
        
        @media screen and (max-width: 1000px) {
            .contain {
                flex-wrap: wrap;
            }
            .list-box {
                width: 100%;
            }
            .echarts-box {
                margin-top: 30px;
            }
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="contain">
            <!-- 左侧列表 -->
            <div class="list-box">

                <!-- 添加资产 -->
                <form class="my-form">
                    <input v-model.trim="name" type="text" class="form-control" placeholder="消费名称" />
                    <input v-model.number="price" type="text" class="form-control" placeholder="消费价格" />
                    <button @click="add" 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 v-for="(item, index) in list" :key="item.id">
                            <td>{{ index + 1 }}</td>
                            <td>{{ item.name }}</td>
                            <td :class="{ red: item.price > 500 }">{{ item.price.toFixed(2) }}</td>
                            <td><a @click="del(item.id)" href="javascript:;">删除</a></td>
                        </tr>
                    </tbody>
                    <tfoot>
                        <tr>
                            <td colspan="4">消费总计: {{ totalPrice.toFixed(2) }}</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/vue@2/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                list: JSON.parse(localStorage.getItem('list')) || [],
                name: '',
                price: ''
            },
            computed: {
                totalPrice() {
                    return this.list.reduce((sum, item) => sum + item.price, 0)
                }
            },
            mounted() {
                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)'
                            }
                        }
                    }]
                })

                this.refreshChart()
            },
            watch: {
                //数据变化存入本地
                list: {
                    deep: true,
                    handler(newValue) {
                        // 需要将变化后的 newValue 存入本地 (转JSON)
                        localStorage.setItem('list', JSON.stringify(newValue))
                    }
                }
            },
            methods: {
                // 更新图表
                refreshChart() {
                    this.myChart.setOption({
                        // 数据项
                        series: [{
                            data: this.list.map(item => ({
                                value: item.price,
                                name: item.name
                            }))
                        }]
                    })
                },
                add() {
                    if (!this.name) {
                        alert('请输入消费名称')
                        return
                    }
                    if (typeof this.price !== 'number') {
                        alert('请输入正确的消费价格')
                        return
                    }

                    this.list.push({
                        id: new Date,
                        name: this.name,
                        price: this.price
                    })

                    // 重新渲染图标
                    this.refreshChart()

                    this.name = ''
                    this.price = ''
                },
                del(id) {

                    //删除数据
                    this.list = this.list.filter(item => item.id != id)

                    // 重新渲染图标
                    this.refreshChart()
                }
            }
        })
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/800268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于K8s环境·使用ArgoCD部署Jenkins和静态Agent节点

今天是「DevOps云学堂」与你共同进步的第 47天 第⑦期DevOps实战训练营 7月15日已开营 实践环境升级基于K8s和ArgoCD 本文节选自第⑦期DevOps训练营 &#xff0c; 对于训练营的同学实践此文档依赖于基础环境配置文档&#xff0c; 运行K8s集群并配置NFS存储。实际上只要有个K8s集…

Spring Security内置过滤器详解

相关文章&#xff1a; OAuth2的定义和运行流程Spring Security OAuth实现Gitee快捷登录Spring Security OAuth实现GitHub快捷登录Spring Security的过滤器链机制Spring Security OAuth Client配置加载源码分析 文章目录 前言OAuth2AuthorizationRequestRedirectFilterOAuth2Log…

matlab多线程,parfor循环进度,matlab互斥锁

一. 内容简介 matlab多线程&#xff0c;parfor循环进度&#xff0c;matlab互斥锁 二. 软件环境 2.1 matlab 2022b 2.2代码链接 https://gitee.com/JJW_1601897441/csdn 三.主要流程 3.1 matlab多线程 有好几种&#xff0c;最简单的&#xff0c;最好理解的就是parfor&am…

cpolar内网穿透外网远程访问本地网站

文章目录 cpolar内网穿透外网远程访问本地网站 cpolar内网穿透外网远程访问本地网站 在现代人的生活中&#xff0c;电脑是离不开的重要设备&#xff0c;大家看到用到的各种物品都离不开电脑的支持。尽管移动电子设备发展十分迅速&#xff0c;由于其自身存在的短板&#xff0c;…

Leetcode-每日一题【剑指 Offer 66. 构建乘积数组】

题目 给定一个数组 A[0,1,…,n-1]&#xff0c;请构建一个数组 B[0,1,…,n-1]&#xff0c;其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]A[0]A[1]…A[i-1]A[i1]…A[n-1]。不能使用除法。 示例: 输入: [1,2,3,4,5]输出: [120,60,40,30,24] 提示&#xff1a; 所…

SSIS对SQL Server向Mysql数据转发表数据 (三)

1、在控制流界面&#xff0c;在左侧的组件里&#xff0c;添加一个“序列容器组件”和一个“数据流任务组件” 2、双击数据流任务&#xff0c;进入到数据流界面&#xff0c;然后再在左面添加一个OLE DB 源组件、目标源组件 3、右键源组件&#xff0c;编辑&#xff0c;选择好相关…

虎年现货黄金投资布局图

参与现货黄金交易的主要目的&#xff0c;是为了根据行情走势的变动&#xff0c;把握一些较佳的获利机会&#xff0c;在这样的一个过程中&#xff0c;如果投资者能够提前把布局的图表画好&#xff0c;那么就可能获得事半功倍的效果&#xff0c;而本文将为大家简单的介绍&#xf…

C++——STL容器之list链表的讲解

目录 一.list的介绍 二.list类成员函数的讲解 2.2迭代器 三.添加删除数据&#xff1a; 3.1添加&#xff1a; 3.2删除数据 四.排序及去重函数&#xff1a; 错误案例如下&#xff1a; 方法如下&#xff1a; 一.list的介绍 list列表是序列容器&#xff0c;允许在序列内的任何…

前端面试题 —— React (二)

目录 一、React 组件中怎么做事件代理&#xff1f;它的原理是什么&#xff1f; 二、React.Component 和 React.PureComponent 的区别 三、Component, Element, Instance 之间有什么区别和联系&#xff1f; 四、React声明组件有哪几种方法&#xff0c;有什么不同&#xff1f…

数学建模-MATLAB三维作图

导出图片用无压缩tif会更清晰 帮助文档&#xff1a;doc 函数名 matlab代码导出为PDF 新建实时脚本或右键文件转换为实时脚本实时编辑器-全部运行-内嵌显示保存为PDF

120个颠覆你认知的gpt使用案例汇总,办公效率提高500%

文章目录 介绍1.代码生成2.代码注释3.代码解释器4.充当 Linux 终端5.代码纠正6.英语口语练习7.专业的翻译8.面试官9.写任何考科目的作业10.快速解决学习中的任何问题11.网站推荐12.网络工具软件推荐13.快速学习新技能14.快速总结长文本的核心思想15.解决日常办公问题16.制作各种…

【CASA】生态系统NPP及碳源、碳汇模拟(土地利用变化、未来气候变化、空间动态模拟)

碳中和可以从碳排放&#xff08;碳源&#xff09;和碳固定&#xff08;碳汇&#xff09;这两个侧面来理解。陆地生态系统在全球碳循环过程中有着重要作用&#xff0c;准确地评估陆地生态系统碳汇及碳源变化对于研究碳循环过程、预测气候变化及制定合理政策具有重要意义。CASA(C…

【QT 网络云盘客户端】——实现文件属性窗口

目录 文件属性对话框 设置字体样式 获取文件的信息 显示文件属性对话框 当我们点击文件中的属性&#xff0c;则会弹出一个属性对话框&#xff1a; 实现过程&#xff1a; 0.设置 属性 菜单项的槽函数。 1.鼠获取鼠标选中的QListWidgetItem,它包含 图标和文件名 2.根据文件…

Dooring-Saas低代码技术详解

hello, 大家好, 我是徐小夕, 今天和大家分享一下基于 H5-Dooring零代码 开发的全新零代码搭建平台 Dooring-Saas 的技术架构和设计实现思路. 背景介绍 3年前我上线了第一版自研零代码引擎 H5-Dooring, 至今已迭代了 300 多个版本, 主要目的是快速且批量化的生产业务/营销过程中…

CSS Flex 笔记

1. Flexbox 术语 Flex 容器可以是<div> 等&#xff0c;对其设置属性&#xff1a;display: flex, justify-content 是沿主轴方向调整元素&#xff0c;align-items 是沿交叉轴对齐元素。 2. Cheatsheet 2.1 设置 Flex 容器&#xff0c;加粗的属性为默认值 2.1.1 align-it…

Spring 事务的使用、隔离级别、@Transactional的使用

Spring事务是Spring框架提供的一种机制&#xff0c;用于管理应用程序中的数据库事务。 事务是一组数据库操作的执行单元&#xff0c;要么全部成功提交&#xff0c;要么全部失败回滚&#xff0c;保证数据的一致性和完整性。 Spring事务提供了声明式事务和编程式事务两种方式&am…

[Tools: Camera Conventions] NeRF中的相机矩阵估计

参考&#xff1a;NeRF代码解读-相机参数与坐标系变换 - 知乎 在NeRF中&#xff0c;一个重要的步骤是确定射线&#xff08;rays&#xff09;的初始点和方向。根据射线的初始点和方向&#xff0c;和设定射线深度和采样点数量&#xff0c;可以估计该射线成像的像素值。估计得到的…

Live Market:中国“一带一路”十周年,品牌出海跨境电商成为新引擎

​中国提出的“一带一路”倡议已经迎来10周年。高质量共建“数字丝绸之路”是这一倡议的重点方向&#xff0c;能够巩固互联互通合作基础、拓展国际合作新空间、扎牢风险防控网络&#xff0c;实现更高合作水平、更高投入效益、更高供给质量、更高发展韧性&#xff0c;推动共建“…

Python教程三:Python基本概念

1、Python基本语法 Python中严格区分大小写Python中每一行就是一条语句&#xff0c;每条语句以换行结束每一行语句不建议过长&#xff08;一般不建议超过80个字符&#xff09;一条语句可以多行编写&#xff0c;语句后加\结尾Python是缩进严格的语言&#xff0c;所以在Python中…

简单认识NoSQL的Redis配置与优化

文章目录 一、关系型数据库与非关系型数据库1、关系型数据库&#xff1a;2、非关系型数据库3、关系型数据库和非关系型数据库区别&#xff1a;4、非关系型数据库应用场景 二.Redis1、简介2、优点&#xff1a;3、Redis为什么这么快&#xff1f; 三、Redis 安装部署1、安装配置2、…