Vue2基础知识(一) 认识Vue

news2024/11/19 22:44:08

在这里插入图片描述

  • 💌 所属专栏:【Vue2】
  • 😀 作 者:长安不及十里
  • 💻工作:目前从事电力行业开发
  • 🌈目标:全栈开发
  • 🚀 个人简介:一个正在努力学技术的Java工程师,专注基础和实战分享 ,欢迎咨询!
  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘
  • 📌 格言:把戏把戏要过手

  • 📏 官网:https://v2.cn.vuejs.org
  • ⛳ 参考教程:https://www.bilibili.com/video/BV1HV4y1a7n4
  • 🔧 Vue脚手架:https://cli.vuejs.org/zh
  • 🔧 VueRouter:https://router.vuejs.org/zh
  • 🔧 VueX:https://vuex.vuejs.org/zh

一 认识Vue

1.1 前端发展历程

前端技术开发在过去的十年里经历了从HTML、CSS到JavaScript的演变。在这个历程中,前端工程师的角色也发生了变化,他们不再只是单纯的代码开发者,还需要与设计师、产品经理、运营人员等其他团队成员协作,共同完成网站的开发。

  • 2010年以前,前端工程师主要负责网站的静态页面开发,如网页设计、图片处理等。在这个阶段,前端工程师的技能主要包括HTML、CSS和JavaScript等基本技术。
  • 2010年,JavaScript成为了前端开发的主要语言。随着JavaScript的普及和发展,越来越多的前端工程师开始关注JavaScript的应用和开发。
  • 2011年,jQuery成为了前端开发的主流库,并且HTML5和CSS3开始受到重视。这也是前端开发变得更加动态和交互性的开始。
  • 2012年,响应式设计和移动设备优先的设计理念开始流行,前端开发在移动端上崭露头角。
  • 2013年,Angular引入了模块化和数据绑定的概念,Bootstrap实现了响应式框架,前端开发变得更加简单和高效。
  • 2014年,React发布,革新出组件化的思想,前端开发变得更加灵活和可维护。
  • 2015年,ES6发布,带来了诸如箭头函数、模板字符串和解构赋值等语言的改进,使JavaScript变得更加易用和现代化。同年,Vue的发布迅速获得了广泛应用。
  • 2016年,前端工具链的发展得到了加速,例如Webpack和Babel等工具的普及使得前端工程化得到了广泛推广。
  • 2017年,JavaScript库和框架更加多样,Angular、React和Vue等都在不断地演进和优化。PWA技术的普及使得网页更接近原生应用的用户体验。
  • 2018年,JavaScript框架的选择更加复杂,同时CSS预处理器(例如Sass和Less)和CSS-in-JS的技术也逐渐成熟。
  • 2019年,前端技术继续保持快速发展的趋势,更加注重用户体验和开发效率。例如,React Hooks和Vue 3等技术的推出使得前端代码更简洁并可维护。
  • 2020年,因新冠疫情影响,居家办公及远程工作成为新趋势。虚拟会议和在线教育等普及推动了前端技术的发展,也更加重视了访问性和用户体验。
  • 2021年,新技术和工具不断推陈出新。Web Assembly使得前端代码获得更高的效率,而预渲染和静态站点生成等技术让前端应用可以获得更快的加载速度。
  • 2022年,VR(虚拟现实)和AR(增强现实)技术的不断发展,前端开发者需要开发出更加适合VR/AR场景的应用程序。
  • 2023年至今,AI(人工智能)技术的突破性进展,前端技术将在AI 技术的加持下得到更广泛的应用,从而带来更智能和更高效的前端开发体验。

1.2 Vue

Vue是什么?
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
image.png
Vue的作者?
尤雨溪
Vue的特点?

  1. 遵循 MVVM 模式,借鉴 angular 的模板和数据绑定技术,借鉴 react 的组件化和虚拟 DOM 技术。
  2. 适合 移动/PC 开发,代码简洁,体积小,运行效率高。
  3. 它本身只关注 UI,可以轻松引入 vue 插件或其它第三库开发项目。
  4. 繁荣的生态,百花齐放的组件。
  5. 经过多次的迭代,稳定性号。

Vue vs Anguar?
我们第一个项目由于是Angualr编写的项目,再次我想比较一下他的区别

  • 学习:Vue比较容易上手,Angualr需要自己去学习一番,比如Ts语法,当时我认为在后端开发人员看来Angualr的学习成本好像也不是很高,他有这像后端一样的语法结构树,类似的结构,View,样式,脚本分离
  • 生态:可能在国内使用Anguar的团队相对于Vue的来说比较少,所以生态Vue的生态强太多,当真实开发中遇到问题可能找不到解决办法
  • 性能:虽然 Angular 和 Vue 都提供了很高的性能,但由于 Vue 的虚拟 DOM 实现的重量较轻,所以可以说 Vue 的速度/性能略微领先,更简单的编程模型使 Vue 能够提供更好的性能。Angular 可能会很慢的原因是它使用脏数据检查,这意味着 Angularmonitors 会持续查看变量是否有变化。

Vue.js 是轻量级的开发框架,很适合开发小规模灵活的 Web 应用程序;而 Angular 尽管学习曲线较为陡峭,但却是构建完整复杂应用的好选择。

1.3 开发工具准备

  • 下载插件

image.png

  • 安装调试

image.png

  • VsCode 代码开发工具安装
  • 下载地址:https://code.visualstudio.com/
  • 傻瓜式安装ok

二 Vue 基础语法

2.1 Vue 的引入

  • 原生网页开发:我们学习基本语法时使用
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>  
  • 组件开发:基于Vue提供的脚手架进行开发,后面到了组件开发进行介绍,参考资料:https://cli.vuejs.org/zh/

2.2 Hello Word

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>For</title>
    <!-- 引入开发包 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
      <body>
      <div id="app">
      <h1>{{msg}}</h1>
      </div>
      <script>
      // 创建Vue实例
      var app = new Vue({
      // 挂载点: 通过id选择器找到挂载点
      el: '#app',
      // 数据
      data: {
        msg: "hello world",
      },
    })
    </script>

image.png
image.png

2.3 Vue 实例

每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:

var vm = new Vue({
 // 选项
 })

虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名表示 Vue 实例。
当创建一个 Vue 实例时,你可以传入一个选项对象。这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。作为参考,你也可以在 API 文档中浏览完整的选项列表。
MVVM模型:
image.png
Vue 实例:https://v2.cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E6%95%B0%E6%8D%AE
我们打开开发者工具F12,打印app Vue实例

2.3.1 el

  • 类型:string | Element
  • 限制:只在用 new 创建实例时生效。
  • 详细:提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。在实例挂载之后,元素可以用 vm. e l 访问。如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用 v m . el 访问。如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用 vm. el访问。如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用vm.mount() 手动开启编译。

image.png

2.3.2 data

  • 类型:Object | Function
  • 限制:组件的定义只接受 function。
  • 详细:Vue 实例的数据对象。Vue 会递归地把 data 的 property 转换为 getter/setter,从而让 data 的 property 能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的 property 会被忽略。

image.png
目前我们就介绍这两个,后面遇到了自己查文档,打开调试工具观察Vue实例

2.4 插值表达式

image.png

  • 案例
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>For</title>
  <!-- 引入开发包 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">
    <h1>{{msg}}</h1>
    <p>{{1==0}}</p>
    <p>{{1>0}}</p>
    <p>{{1<0}}</p>
    <p v-html="html"></p>
    <image v-bind:src="img"></image>


  </div>
  <script>
    // 创建Vue实例
    var app = new Vue({
      // 挂载点: 通过id选择器找到挂载点
      el: '#app',
      // 数据
      data: {
        msg: "我是插值表达式基本语法",
        html: "<h1>我是h1标签</h1>",
        url: "https://www.baidu.com",
        img: "https://www.baidu.com/img/bd_logo1.png?where=super",
        flag: true,
      },
    })
  </script>

image.png

  • 数据绑定最常见的形式就是使用Mustache语法 (双大括号) 的文本插值,Mustache 标签将会被替代为对应数据对象上 msg property 的值。无论何时,绑定的数据对象上 msg property 发生了改变,插值处的内容都会更新。
  • 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html。
  • Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind指令。
  • 对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。

2.5 指令

指令 (Directives) 是带有 v- 前缀的特殊 attribute。
指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。
指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
这里我也不介绍完了,自己可以去查看官网,介绍我认为难理解的
image.png
image.png

2.5.1 v-show vs v-if

image.png

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>For</title>
  <!-- 引入开发包 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">

  <!-- v-show -->
    <h1 v-show="isShow">我是v-show</h1>
    <button @click="isShow=!isShow">v-show切换</button>
    <!-- v-if -->
    <h1 v-if="isShow">我是v-if</h1>
    <button @click="isShow=!isShow">v-if切换</button>
    <!-- v-bind -->
    <a v-bind:href="url">百度</a>
    <img v-bind:src="img" alt="">
    <button v-bind:disabled="isButtonDisabled">Button</button>

  </div>
  <script>
    // 创建Vue实例
    var app = new Vue({
      // 挂载点: 通过id选择器找到挂载点
      el: '#app',
      // 数据
      data: {
       // 是否展示
        isShow: true,
        url: "https://www.baidu.com",
        img: "https://www.baidu.com/img/bd_logo1.png?where=super",
      },
    })
  </script>
  • v-show是通过display:none来控制元素的显示和隐藏
  • v-if是通过添加和删除元素来控制元素的显示和隐藏
  • v-show的元素始终会被渲染在DOM中,而v-if的元素只有在条件为true时才会被渲染在DOM中

2.5.2 v-on

  • 缩写:@
  • 预期:Function | Inline Statement | Object
  • 参数:event
  • 修饰符
    • .stop - 调用 event.stopPropagation()。
    • .prevent - 调用 event.preventDefault()。
    • .capture - 添加事件侦听器时使用 capture 模式。
    • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
    • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
    • .native - 监听组件根元素的原生事件。
    • .once - 只触发一次回调。
    • .left - (2.2.0) 只当点击鼠标左键时触发。
    • .right - (2.2.0) 只当点击鼠标右键时触发。
    • .middle - (2.2.0) 只当点击鼠标中键时触发。
    • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
  • 用法:绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event property:v-on:click=“handle(‘ok’, $event)”。从 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。

image.png

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>For</title>
  <!-- 引入开发包 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">
    <!-- v-on -->
    <h1 style="color: #f70303;">{{ message }}</h1>
    <button v-on:click="reverseMessage">逆转消息</button>
    <!-- 简写 -->
    <button @click="reverseMessage">简写逆转消息</button>
    <!-- 传参 -->
    <button @click="reverseMessage('hello v-on')">传参逆转消息</button>
  </div>
  <script>
    // 创建Vue实例
    var app = new Vue({
      // 挂载点: 通过id选择器找到挂载点
      el: '#app',
      // 数据
      data: {
        // 是否展示
        message: 'Hello Vue!'
      },
      // 方法
      methods: {
        // 逆转消息
        reverseMessage: function () {
          this.message = this.message.split('').reverse().join('')
        },
        // 传参逆转消息
        reverseMessage: function (message) {
          this.message = message.split('').reverse().join('')
        }

      },
    })
  </script>

本文又介绍了Vue的一个实例 ,方法区:
methods

  • 类型:{ [key: string]: Function }
  • 详细:methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。

image.png

2.5.3 v-bind

  • 缩写::
  • 预期:any (with argument) | Object (without argument)
  • 参数:attrOrProp (optional)
  • 修饰符
    • .prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。(差别在哪里?)
    • .camel - (2.1.0+) 将 kebab-case attribute 名转换为 camelCase。(从 2.1.0 开始支持)
    • .sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
  • 用法:动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。在绑定 class 或 style attribute 时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。

image.png

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>For</title>
  <!-- 引入开发包 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">
    <!-- v-bind -->
    <h1 style="color: #f70303;">{{ message }}</h1>
    <!-- v-bind -->
    <button v-bind:style="{color:color}">v-bind</button>
    <!-- class -->
    <div :class="class1">class</div>
    <!-- 简写 -->
    <button :style="{color:color}">简写v-bind</button>

    <!-- 改变颜色 -->
    <button @click="changeColor">改变颜色</button>

  </div>
  <script>
    // 创建Vue实例
    var app = new Vue({
      // 挂载点: 通过id选择器找到挂载点
      el: '#app',
      // 数据
      data: {
        // 是否展示
        color: '#f70303',
        message: 'Hello Vue!',
        tiele: 'Hello Vue!',
        class1: 'box',



      },
      // 方法
      methods: {
        // 改变颜色
        changeColor: function () {
          this.color = '#03f7f7',
            this.class1 = 'box1'
        },

      },
    })
  </script>

  <style>
    .box {
      width: 100px;
      height: 100px;
      background-color: #f70303;
    }

    .box1 {
      width: 100px;
      height: 100px;
      background-color: #03f7f7;
    }
  </style>
  • 其他
<!-- 绑定一个 attribute -->
<img v-bind:src="imageSrc">

<!-- 动态 attribute 名 (2.6.0+) -->
<button v-bind:[key]="value"></button>

<!-- 缩写 -->
<img :src="imageSrc">

<!-- 动态 attribute 名缩写 (2.6.0+) -->
<button :[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个全是 attribute 的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通过 prop 修饰符绑定 DOM attribute -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

2.5.4 v-for

  • 预期:Array | Object | number | string | Iterable (2.6 新增)
  • 用法:基于源数据多次渲染元素或模板块。此指令之值,必须使用特定语法 alias in expression,为当前遍历的元素提供别名:
    | ```vue
{{ item.text }}
``` | | --- |

image.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>For</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div>
            <ul>
                <li v-for="(item,index) in items" :key="id" >{{index}}--{{  item.name  }} </li>
            </ul>
            <button @click="add()">增加</button>
            <button @click="del()">删除</button>
            <button @click="change()">修改</button>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                items: [
                    { id: 1, name: 'Alice' },
                    { id: 2, name: 'Bob' },
                    { id: 3, name: 'Charlie' }
                ]
            },
            methods: {
                add() {
                   this.items.push({ id: 4, name: 'David' })
                },
                del(){
                    this.items.splice(1,1)
                },
                change(){
                    this.items[0].name = '测试'
                }
            },
        })
    </script>

这个key属性有什么作用呢?

  • key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。
  • 如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法;而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素。
  • 详细来说,我们知道,vue实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。

image.png
image.png
image.png

2.5.5 v-model

  • 预期:随表单控件类型不同而不同。
  • 限制
    • components
  • 修饰符
    • .lazy - 取代 input 监听 change 事件
    • .number - 输入字符串转为有效的数字
    • .trim - 输入首尾空格过滤
  • 用法:在表单控件或者组件上创建双向绑定

image.png

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>For</title>
  <!-- 引入开发包 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">
    <!-- v-model -->
    <div>
      <input type="text" v-model="name">
      <input type="password" v-model="password">
      <select v-model="sex">
        <option value="男">男</option>
        <option value="女">女</option>
      </select>
    </div>
    <!-- 填写的信息 -->
    <div>
      <p>姓名:{{name}}</p>
      <p>密码:{{password}}</p>
      <p>性别:{{sex}}</p>
    </div>

    <script>
      // 创建Vue实例
      var app = new Vue({
        // 挂载点: 通过id选择器找到挂载点
        el: '#app',
        // 数据
        data: {
          // 姓名
          name: '',
          // 密码
          password: "",
          // 性别
          sex: "",
          // 爱好
          hobby: [],
          // 城市
          city: "",

        },
        // 方法
        methods: {
        },
      })
    </script>

**lazy **
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:

| ```vue

**number **
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

| ```vue

 |
| --- |

这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。
**trim **
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

| ```vue
<input v-model.trim="msg">

|
| — |

其他的请参考官方文档,或者自己使用时查询文档

2.6 案例

image.png

<!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" />
  <link rel="stylesheet" href="./css/index.css" />
  <title>记事本</title>
</head>
<body>
  <!-- 主体区域 -->
  <section id="app">
    <!-- 输入框 -->
    <header class="header">
      <h1>小黑记事本</h1>
      <input v-model="todoName" placeholder="请输入任务" class="new-todo" />
      <button @click="add" class="add">添加任务</button>
    </header>
    <!-- 列表区域 -->
    <section class="main">
      <ul class="todo-list">
        <li class="todo" v-for="(item, index) in list" :key="item.id">
          <div class="view">
            <span class="index">{{ index + 1 }}.</span> <label>{{ item.name }}</label>
            <button @click="del(item.id)" class="destroy"></button>
          </div>
        </li>
      </ul>
    </section>
    <!-- 统计和清空 → 如果没有任务了,底部隐藏掉 → v-show -->
    <footer class="footer" v-show="list.length > 0">
      <!-- 统计 -->
      <span class="todo-count">合 计:<strong> {{ list.length }} </strong></span>
      <!-- 清空 -->
      <button @click="clear" class="clear-completed">
        清空任务
      </button>
    </footer>
  </section>

  <!-- 底部 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    // 添加功能
    // 1. 通过 v-model 绑定 输入框 → 实时获取表单元素的内容
    // 2. 点击按钮,进行新增,往数组最前面加 unshift
    const app = new Vue({
      el: '#app',
      data: {
        todoName: '',
        list: [
          { id: 1, name: '跑步一公里' },
          { id: 2, name: '跳绳200个' },
          { id: 3, name: '游泳100米' },
        ]
      },
      methods: {
        del(id) {
          // console.log(id) => filter 保留所有不等于该 id 的项
          this.list = this.list.filter(item => item.id !== id)
        },
        add() {
          if (this.todoName.trim() === '') {
            alert('请输入任务名称')
            return
          }
          this.list.unshift({
            id: +new Date(),
            name: this.todoName
          })
          this.todoName = ''
        },
        clear() {
          this.list = []
        }
      }
    })

  </script>
</body>

</html>

image.png

2.7 扩展

2.7.1 数据代理

Vue的数据代理是一种让Vue实例直接访问data选项中定义的属性的机制,在Vue实例创建时,Vue会使用Object.defineProperty方法重新定义data选项中的属性,并将它们代理到Vue实例本身上,这样,我们就可以通过Vue实例直接访问data选项中定义的属性,而不需要使用this.$data。

<!--
 * @Description: 侦听属性
 * @version: 1.0
 * @Author: shu
 * @Date: 2023-04-16 16:46:33
 * @LastEditors: 修改者填写
 * @LastEditTime: 2023-04-16 16:46:33
-->
<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>侦听属性</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
    </div>
    <script>
        var obj = {}
        var value = 'Hello, World!'
        Object.defineProperty(obj, 'message', {
            get: function () {
                console.log('Getting value: ' + value)
                return value
            },
            set: function (newValue) {
                console.log('Setting value: ' + newValue)
                value = newValue
            }
        })
        console.log(obj.message) // 输出: Getting value: Hello, World!  Hello, World!
        obj.message = 'Hello, Vue!'
        console.log(obj.message) // 输出: Setting value: Hello, Vue!  Getting value: Hello, Vue!  Hello, Vue!


    </script>

</html>

image.png

  • 在这个示例中,我们首先定义了一个名为obj的空对象,然后使用Object.defineProperty方法将一个名为message的属性添加到该对象中。
  • 我们定义了message属性的getter和setter方法,这些方法会在属性被访问或修改时被调用。在getter方法中,我们输出当前属性的值,然后返回该值。
  • 在setter方法中,我们输出新的属性值,然后将其赋给value变量。
  • 当我们使用obj.message访问message属性时,getter方法会被调用,并输出属性的当前值,当我们使用obj.message = ‘Hello, Vue!’ 修改message属性的值时,setter方法会被调用,并输出新的属性值。
  • 在Vue中,Object.defineProperty方法被使用来将data选项中的属性转换为具有响应式更新能力的属性。当我们修改Vue实例上的某个属性的值时,实际上会调用该属性的setter方法,从而触发响应式更新。
  • 这样,我们就可以实现数据的自动更新,而不需要手动调用更新方法。

2.7.2 列表渲染的Key的唯一性

🌈为啥需要保证key唯一?
⏺️在Vue的列表渲染中,为什么要求每个子组件或元素都必须有一个唯一的key属性呢?这是因为Vue在进行列表渲染时,会基于key属性来判断两个元素是否相同,以便进行优化操作。
⏺️具体来说,当Vue进行列表渲染时,它会为每个子组件或元素创建一个虚拟节点(Virtual Node),这些虚拟节点会被缓存在内存中,以便在列表数据发生变化时进行比较和更新。在创建虚拟节点时,Vue会根据每个子组件或元素的key属性来判断它们是否相同。
⏺️如果两个子组件或元素的key属性相同,则它们被认为是同一个元素,并且不需要重新渲染;如果两个子组件或元素的key属性不同,则它们被认为是不同的元素,并且需要重新渲染。

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>For</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <div>
            <ul>
                <li v-for="(item,index) in items" :key="id" >{{index}}--{{  item.name  }} </li>
            </ul>
            <button @click="add()">增加</button>
            <button @click="del()">删除</button>
            <button @click="change()">修改</button>
        </div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                items: [
                    { id: 1, name: 'Alice' },
                    { id: 2, name: 'Bob' },
                    { id: 3, name: 'Charlie' }
                ]
            },
            methods: {
                add() {
                   this.items.push({ id: 4, name: 'David' })
                },
                del(){
                    this.items.splice(1,1)
                },
                change(){
                    this.items[0].name = '测试'
                }
            },
        })
    </script>

我们来总结下:

  1. Vue会监测数据源数组(如items)的变化,当数组发生变化时,Vue会重新计算虚拟DOM树并比较新旧DOM树之间的差异。
  2. 对于新旧DOM树之间的每个元素,Vue会根据其key属性来判断它们是否是同一个元素。如果两个元素的key相同,则Vue认为它们是同一个元素,会对其进行更新操作;否则Vue会将其视为不同的元素,会对其进行添加或删除操作。
  3. 当Vue判断出需要对一个元素进行更新操作时,Vue会根据元素对应的虚拟DOM节点(如VNode)的属性来更新DOM节点的状态,例如更新文本内容、样式、属性等。在更新DOM节点的过程中,Vue也会更新对应的数据源数组中的元素。
  4. 当Vue判断出需要对一个元素进行添加或删除操作时,Vue会在DOM树中插入或删除对应的DOM节点,并更新数据源数组的长度和索引。
  5. 当列表中的元素数量非常大时,Vue可能会采用一些优化策略来提高渲染性能,例如使用对象池来复用已有的DOM节点,使用异步更新队列来合并多个更新操作等。

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

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

相关文章

原创!—混合灰狼层次结构的自适应麻雀搜索算法GWHASSA

麻雀搜索算法&#xff08;SSA&#xff09;是薛建凯等人[1]提出的一种群体智能优化算法,是受麻雀觅食和躲避捕食者行为启发而设计出的算法。该算法于2020年首次提出&#xff0c;具有局部搜索能力强、调整参数少等特点&#xff0c;已成功应用于CT图像的现场检测、电池堆参数的优化…

分布式和微服务

问题分析&#xff1a; 简单来说&#xff0c;分布式是一组通过网络进行通信&#xff0c;并且为了完成共同的计算任务的计算机节点组 成的系统。 分布式系统的设计理念&#xff0c;其实是来自于小型机或者大型机的计算能力的瓶颈和成本的 增加。 在集中式系统里面&#xff0c;要…

FL Studio21最新中文破解进阶高级完整版安装下载教程

目前水果软件最版本是FL Studio21&#xff0c;它让你的计算机就像是全功能的录音室&#xff0c;大混音盘&#xff0c;非常先进的制作工具&#xff0c;让你的音乐突破想象力的限制。喜欢音乐制作的小伙伴千万不要错过这个功能强大&#xff0c;安装便捷的音乐软件哦&#xff01;如…

ThreadLocal源码解密

1 背景 作为一只懒懒地程序员,其实我是不太爱看源码的,晦涩、深奥、难懂、耗费时间等等,就觉得不是我这种能力平平地小老百姓能吃得消的,但现实比人强,记得曾经我就被不懂原理的情况下乱用ThreadLocal给毒打了。 犹记得当时在一个JSF服务中的责任链的校验场景中需要在源…

使用vcpkg管理依赖第三库

文章目录 使用vcpkg管理依赖第三库vcpkg安装vcpkg经典模式使用从仓库列表搜索依赖项从某个基线版本的列表中查询某个依赖项信息安装依赖库 vcpkg清单模式的使用vcpkg清单模式的使用例子说明 使用vcpkg管理依赖第三库 vcpkg 有两种操作模式&#xff1a;经典模式和清单模式。 在…

36 机器学习(四):异常值检测|线性回归|逻辑回归|聚类算法|集成学习

文章目录 异常值检测箱线图z-score 保存模型 与 使用模型回归的性能评估线性回归正规方程的线性回归梯度下降的线性回归原理介绍L1 和 L2 正则化的介绍api介绍------LinearRegressionapi介绍------SGDRegressor 岭回归 和 Lasso 回归 逻辑回归基本使用原理介绍正向原理介绍损失…

深入理解JavaScript ES8的新特性

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

opencv改善pdf清晰度

improve-pdf 介绍&#xff1a; 使用python脚本对pdf进行优化&#xff0c;提高pdf清晰度&#xff0c;使文字更加清晰&#xff0c;观感更佳。仅适用黑白扫描版pdf&#xff0c;且文字较清晰&#xff0c;若模糊会更加模糊。 原理&#xff1a; pdf转成png图片 再使用opencv对图片…

【算法训练-回溯算法 三】【回溯算法最佳实践】括号生成、复原IP地址

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【回溯算法】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

由Django-Session配置引发的反序列化安全问题

漏洞成因 漏洞成因位于目标配置文件settings.py下 关于这两个配置项 SESSION_ENGINE&#xff1a; 在Django中&#xff0c;SESSION_ENGINE 是一个设置项&#xff0c;用于指定用于存储和处理会话&#xff08;session&#xff09;数据的引擎。 SESSION_ENGINE 设置项允许您选择不…

MSQL系列(六) Mysql实战-SQL语句优化

Mysql实战-SQL语句优化 前面我们讲解了索引的存储结构&#xff0c;BTree的索引结构&#xff0c;以及索引最左侧匹配原则&#xff0c;Explain的用法&#xff0c;可以看到是否使用了索引&#xff0c;今天我们讲解一下SQL语句的优化及如何优化 文章目录 Mysql实战-SQL语句优化1.…

统信uos 1030 企业版 安装.net core环境

安装.net core步骤 添加密钥和包存储库 安装 .NET 之前&#xff0c;请运行以下命令&#xff0c;将 Microsoft 包签名密钥添加到受信任密钥列表&#xff0c;并添加包存储库wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-mic…

nuxt使用i18n进行中英文切换

中文效果图&#xff1a; 英文效果图&#xff1a; 版本&#xff1a; 安装&#xff1a; npm install vue-i18n8.27.0 --savenpm i nuxtjs/i18n # npm 新建en.js与zh.js两个文件进行切换显示 en.js内容 import globals from ./../js/global_valexport default {/******* 公共内…

什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别?软件测试等相关概念入门篇

1、什么是软件测试&#xff1f; 常见理解&#xff1a; 软件测试就是找BUG&#xff0c;发现缺陷 真正理解&#xff1a; 软件测试就是验证软件产品特性是否满足用户的需求 测试定义&#xff1a; 测试人员验证软件是否符合需求的这个过程就是测试 2、为什么要有测试 标准情况下&a…

ShareMouse for Mac(多台电脑鼠标键盘共享软件)

ShareMouse mac版是一款Mac平台上可以在多台电脑间共享鼠标的工具软件&#xff0c;sharemousefor Mac支持 Windows 与 Mac&#xff0c;并可以在不同电脑间共享剪贴板。只需要移动鼠标指针的到想控制的显示器那里去、鼠标光标就会神奇地“跨越”到邻近的电脑屏幕上。每个计算机都…

vue中使用coordtransform 互相转换坐标系

官方网站&#xff1a;https://www.npmjs.com/package/coordtransform 在使用高德sdk时&#xff0c;其返回的坐标在地图上显示时有几百米的偏移&#xff0c;这是由于高德用的是 火星坐标&#xff08;GCJ02&#xff09;&#xff0c;而不是wgs84坐标。为了消除偏移&#xff0c;将G…

KubeSphere安装mysql8

需要持久化储存数据的&#xff0c;建立有状态服务。 无状态服务是不会持久化的&#xff0c;重启就归零 KubeSphere 创建自建应用后&#xff0c;创建有状态服务&#xff0c;但是自己应用的有状态服务不能外放端口&#xff0c;需要在服务哪里删除pod&#xff0c;在创建负载指定相…

微信小程序会议OA系统其他页面

前言&#xff1a; 及上一文章&#xff1a;https://blog.csdn.net/djssubddbj/article/details/133895170?spm1001.2014.3001.5501我们所写的会议OA的首页&#xff0c;在这个上面我们继续完成我们的会议OA系统&#xff0c;这是我们的本期所要完成的页面 自定义组件 微信小程序…

基于MATLAB的GPS卫星绕地运行轨迹动态模拟仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 Prn NavData(PRNS_SEL,1);%识别导航数据中的PRNiode NavData(PRNS_SEL,11);%企…

客户端post请求,服务器收到{}数据解决方法

当我们发起登录请求时&#xff0c;后台接收到的为{}数据 原因&#xff1a;传送过去的对象格式不对 解决方案&#xff1a; 引入qs npm install qs 在data中格式化数据 const res await axios({url:http://127.0.0.1:3000/post,method:post,data:Qs.stringify({username:te…