vue快速修改数组的某个值_详解vue组件三大核心概念

8323a91dc5ab5ba135e3fa22ce6b9147.png

前言

本文主要介绍属性、事件和插槽这三个vue基础概念、使用方法及其容易被忽略的一些重要细节。如果你阅读别人写的组件,也可以从这三个部分展开,它们可以帮助你快速了解一个组件的所有功能。

491c2c6706ddce7acd9cd7855765d733.png

本文的代码请猛戳github博客,纸上得来终觉浅,大家动手多敲敲代码!

一、属性

1.自定义属性props

prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。写通用组件时,props 最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,这点在组件开发中很重要,然而很多人却忽视,直接使用 props 的数组用法,这样的组件往往是不严谨的。

// 父组件<props name='属性':type='type':is-visible="false":on-change="handlePropChange":list=[22,33,44]title="属性Demo"class="test1":class="['test2']":style="{ marginTop: '20px' }" //注意:style 的优先级是要高于 stylestyle="margin-top: 10px"></props>
// 子组件props: {name: String,type: {//从父级传入的 type,它的值必须是指定的 'success', 'warning', 'danger'中的一个,如果传入这三个以外的值,都会抛出一条警告validator: (value) => {return ['success', 'warning', 'danger'].includes(value)}},onChange: {//对于接收的数据,可以是各种数据类型,同样也可以传递一个函数type: Function,default: () => { }},isVisible: {type: Boolean,default: false},list: {type: Array,// 对象或数组默认值必须从一个工厂函数获取default: () => []}}

从上面的例中,可以得出props 可以显示定义一个或一个以上的数据,对于接收的数据,可以是各种数据类型,同样也可以传递一个函数。

2.inheritAttrs

这是2.4.0 新增的一个API,默认情况下父作用域的不被认作 props 的特性绑定将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。可通过设置 inheritAttrs 为 false,这些默认行为将会被去掉。注意:这个选项不影响 class 和 style 绑定。 上个例中,title属性没有在子组件中props中声明,就会默认挂在子组件的根元素上,如下图所示:

cba91228061c306b3800a26a1dc67284.png

3. data与props区别

  • 相同点

两者选项里都可以存放各种类型的数据,当行为操作改变时,所有行为操作所用到和模板所渲染的数据同时都会发生同步变化。

  • 不同点

data 被称之为动态数据,在各自实例中,在任何情况下,我们都可以随意改变它的数据类型和数据结构,不会被任何环境所影响。

props 被称之为静态数据,在各自实例中,一旦在初始化被定义好类型时,基于 Vue 是单向数据流,在数据传递时始终不能改变它的数据类型,而且不允许在子组件中直接操作 传递过来的props数据,而是需要通过别的手段,改变传递源中的数据。至于如何改变,我们接下去详细介绍:

4.单向数据流

这个概念出现在组件通信。props的数据都是通过父组件或者更高层级的组件数据或者字面量的方式进行传递的,不允许直接操作改变各自实例中的props数据,而是需要通过别的手段,改变传递源中的数据。那如果有时候我们想修改传递过来的prop,有哪些办法呢? - 方法1:过渡到 data 选项中

在子组件的 data 中拷贝一份 prop,data 是可以修改的

export default {props: {type: String},data () {return {currentType: this.type}}
}

在 data 选项里通过 currentType接收 props中type数据,相当于对 currentType= type进行一个赋值操作,不仅拿到了 currentType的数据,而且也可以改变 currentType数据。 - 方法2:利用计算属性

export default {props: {type: String},computed: {normalizedType: function () {return this.type.toUpperCase();}}
}

以上两种方法虽可以在子组件间接修改props的值,但如果子组件想修改数据并且同步更新到父组件,却无济于事。在一些情况下,我们可能会需要对一个 prop 进行『双向绑定』,此时就推荐以下这两种方法: - 方法3:使用.sync

// 父组件
<template><div class="hello"><div><p>父组件msg:{{ msg }}</p><p>父组件数组:{{ arr }}</p></div><button @click="show = true">打开model框</button><br /><demo :show.sync="show" :msg.sync="msg" :arr="arr"></demo></div>
</template><script>
import Demo from "./demo.vue";
export default {name: "Hello",components: {Demo},data() {return {show: false,msg: "模拟一个model框",arr: [1, 2, 3]};}
};
</script>
// 子组件
<template><div v-if="show" class="border"><div>子组件msg:{{ msg }}</div><div>子组件数组:{{ arr }}</div><button @click="closeModel">关闭model框</button><button @click="$emit('update:msg', '浪里行舟')">改变文字</button><button @click="arr.push('前端工匠')">改变数组</button> </div>
</template>
<script>
export default {props: {msg: {type: String},show: {type: Boolean},arr: {type: Array //在子组件中改变传递过来数组将会影响到父组件的状态}},methods: {closeModel() {this.$emit("update:show", false);}}
};

9848e8d576ad8b9eeb66a3d627a16f4e.gif

父组件向子组件 props 里传递了 msg 和 show 两个值,都用了.sync 修饰符,进行双向绑定。 不过.sync 虽好,但也有限制,比如:

1)不能和表达式一起使用(如v-bind:title.sync="doc.title + '!'"是无效的); 2)不能用在字面量对象上(如v-bind.sync="{ title: doc.title }"是无法正常工作的)。

  • 方法4:将父组件中的数据包装成对象传递给子组件

这是因为在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。比如上例中在子组件中修改父组件传递过来的数组arr,从而改变父组件的状态。

5.向子组件中传递数据时加和不加 v-bind?

对于字面量语法和动态语法,初学者可能在父组件模板中向子组件中传递数据时到底加和不加 v-bind 会感觉迷惑。

v-bind:msg = 'msg'

这是通过 v-bind 进行传递数据并且传递的数据并不是一个字面量,双引号里的解析的是一个表达式,同样也可以是实例上定义的数据和方法(其实就是引用一个变量)。

msg='浪里行舟'

这种在没有 v-bind 的模式下只能传递一个字面量,这个字面量只限于 String 类量,字符串类型。那如果想通过字面量进行数据传递时,如果想传递非String类型,必须props名前要加上v-bind,内部通过实例寻找,如果实例方没有此属性和方法,则默认为对应的数据类型。

:msg='11111' //Number 
:msg='true' //Bootlean 
:msg='()=>{console.log(1)}' //Function
:msg='{a:1}' //Object

二、事件

1.事件驱动与数据驱动

用原生JavaScript事件驱动通常是这样的流程: - 先通过特定的选择器查找到需要操作的节点 -> 给节点添加相应的事件监听 - 然后用户执行某事件(点击,输入,后退等等) -> 调用 JavaScript 来修改节点

这种模式对业务来说是没有什么问题,但是从开发成本和效率来说会比较不理想,特别是在业务系统越来越庞大的时候。另一方面,找节点和修改节点这件事,效率本身就很低,因此出现了数据驱动模式。

Vue的一个核心思想是数据驱动。所谓数据驱动,是指视图是由数据驱动生成的,我们对视图的修改,不会直接操作 DOM,而是通过修改数据,其流程如下:

用户执行某个操作 -> 反馈到 VM 处理(可以导致 Model 变动) -> VM 层改变,通过绑定关系直接更新页面对应位置的数据

可以简单地理解:数据驱动不是操作节点的,而是通过虚拟的抽象数据层来直接更新页面。主要就是因为这一点,数据驱动框架才得以有较快的运行速度(因为不需要去折腾节点),并且可以应用到大型项目。

2.修饰符事件

Vue事件分为普通事件和修饰符事件,这里我们主要介绍修饰符事件。

Vue 提供了大量的修饰符封装了这些过滤和判断,让开发者少写代码,把时间都投入的业务、逻辑上,只需要通过一个修饰符去调用。我们先来思考这样问题:怎样给这个自定义组件 custom-component 绑定一个原生的 click 事件?

<custom-component>组件内容</custom-component>

如果你的回答是<custom-component @click="xxx">,那就错了。这里的 @click 是自定义事件 click,并不是原生事件 click。绑定原生的 click 是这样的:

<custom-component @click.native="xxx">组件内容</custom-component>

实际开发过程中离不开事件修饰符,常见事件修饰符有以下这些: - 表单修饰符

1).lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 。你可以添加 lazy 修饰符,从而转变为使用 change事件进行同步。适用于输入完所有内容后,光标离开才更新视图的场景。

2).trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<input v-model.trim="msg">

这个修饰符可以过滤掉输入完密码不小心多敲了一下空格的场景。需要注意的是,它只能过滤首尾的空格!首尾,中间的是不会过滤的。

3).number

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

<input v-model.number="value" type="text" />

d5c07eb0368dae0300630b1b3b8ccf43.gif

从上面例子,可以得到如果你先输入数字,那它就会限制你输入的只能是数字。如果你先输入字符串,那它就相当于没有加.number - 事件修饰符

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a><!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form><!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

三、插槽

插槽分为普通插槽和作用域插槽,其实两者很类似,只不过作用域插槽可以接受子组件传递过来的参数。

1.作用域插槽

我们不妨通过一个todolist的例子来了解作用域插槽。如果当item选中后,文字变为黄色(如下图所示),该如何实现呢?

28b8e20d4334f18aaa008c62b7e23877.gif
// 父组件
<template><div class="toList"><input v-model="info" type="text" /> <button @click="addItem">添加</button><ul><TodoItem v-for="(item, index) in listData" :key="index"><template v-slot:item="itemProps"> // 这是个具名插槽// 其中itemProps的值就是子组件传递过来的对象<span:style="{fontSize: '20px',color: itemProps.checked ? 'yellow' : 'blue'}">{{ item }}</span></template></TodoItem></ul></div>
</template>
<script>
import TodoItem from "./TodoItem";
export default {components: {TodoItem},data() {return {info: "",listData: []};},methods: {addItem() {this.listData.push(this.info);this.info = "";}}
};
</script>
// 子组件
<template><div><li class="item"><input v-model="checked" type="checkbox" /><slot name="item" :checked="checked"></slot> // 将checked的值传递给父组件</li></div>
</template>
<script>
export default {data() {return {checked: false};}
};
</script>

值得注意:v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名。

2.v-slot新语法

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 。 我们通过一个例子介绍下默认插槽、具名插槽和作用域插槽的新语法:

// 父组件
<template><div class="helloSlot"><h2>2.6 新语法</h2><SlotDemo><p>默认插槽:default slot</p><template v-slot:title><p>具名插槽:title slot1</p><p>具名插槽:title slot2</p></template><template v-slot:item="props"><p>作用域插槽:item slot-scope {{ props }}</p></template></SlotDemo></div>
</template>
<script>
import Slot from "./slot";
export default {components: {SlotDemo: Slot}
};
</script>
// 子组件
<template><div><slot /><slot name="title" /><slot name="item" :propData="propData" /></div>
</template>
<script>
export default {data() {return {propData: {value: "浪里行舟"}};}
};
</script>

a59653bc843e1648f1def13d0c394a36.png

参考文章

  • 珠峰架构课(推荐)
  • Vue开发实战
  • Vue.js 组件精讲
  • Vue.js 官方文档
  • Vue 组件通信全揭秘
  • vue修饰符--可能是东半球最详细的文档(滑稽)

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

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

相关文章

根据id获取多维数组路径_程序员的进阶课-架构师之路(2)-数组

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/m0_37609579/article/details/99355842 从这一节开始&#xff0c;我们就要正式进去数据结构的世界了…

自定义条件查询_数据查询不止有vlookup函数,自定义zlookup函数查询操作更高效...

Excel数据查询&#xff0c;相信大家首先会想到vlookup函数。毋庸置疑vlookup函数在Excel数据查询中作用是非常的强大。但是它也有一些不能实现的数据查询。如上图所示&#xff0c;我们需要根据人员的出现次数&#xff0c;提取第N次的数据。这里vlookup函数就无法使用&#xff0…

2021年中国工业互联网行业发展现状分析,“5G+工业互联网”驱动行业快速发展

一、概述 工业互联网是新一代信息通信技术与工业经济深度融合的新型基础设施、应用模式和工业生态&#xff0c;通过对人、机、物、系统等的全面连接&#xff0c;构建起覆盖全产业链、全价值链的全新制造和服务体系&#xff0c;为工业乃至产业数字化、网络化、智能化发展提供了…

针对数能同传SWIPT的个人理解与总结Part1

无线数能同传&#xff08;Simultaneous Wireless Information and Power Transfer, SWIPT&#xff09;技术是指利用无线射频信号可同时携载信息与能量的特点&#xff0c;从一个射频信号中同时接收信息与能量的技术。 一、接收机架构 SWIPT有很多种解释&#xff0c;携能通信、…

米筐量化不支持c语言_量化 | 从零开始学量化(三):数据获取途径

本系列的前两篇都是一些笼统的介绍&#xff0c;供小白制定学习计划时参考&#xff0c;现在该铺垫的都铺垫的差不多了。循序渐进&#xff0c;从本篇开始会写一些能实操的内容&#xff0c;尽量写的很细节&#xff0c;有任何问题欢迎私戳。本篇给出一些数据获取途径&#xff0c;基…

射频知识简介

无线通信系统中&#xff0c;一般包含有天线、射频前端、射频收发模块以及基带信号处理器四个部分。随着5G时代的&#xff0c;天线以及射频前端的需求量及价值均快速上升&#xff0c;射频前端是将数字信号向无线射频信号转化的基础部件&#xff0c;也是无线通信系统的核心组件。…

尽可能地做到无服务器,但不止于此

毫无疑问&#xff0c;如果您一直关注技术趋势&#xff0c;那么您会看到“无服务器”的兴起。 在某些情况下&#xff0c;“无服务器”被称为“下一个应用程序体系结构”样式。 我什至听说有人说“您不需要技术X&#xff0c;因为无服务器是未来的方式”或“技术X是红鲱鱼&#xf…

信号扫描_科研必备“武器”之扫描电子显微镜

仪器介绍扫描电子显微镜&#xff08;英语名称为Scanning Electron Microscope&#xff0c;缩写为SEM&#xff09;&#xff0c;简称扫描电镜。它是一种电子显微镜&#xff0c;利用聚焦电子束扫描样品的表面来产生样品表面的图像。最常见的扫描电镜模式是检测由电子束激发的原子发…

解决office一打开就显示正在更新,过一会就报错的问题

问题描述&#xff1a; 一打开office就显示正在更新&#xff0c;请稍后&#xff0c;过一会就弹窗报错。 解决方案&#xff1a; 1.winR输入services.msc 2.将Microsoft Office即点即用服务设为自动 如果第二步中已经是自动状态&#xff0c;先禁用一下&#xff0c;再重新设置为…

框架如何调用存储过程_如何在FastReport.Net中使用存储过程

在本文中&#xff0c;我们将讨论使用存储过程来检索报表的数据&#xff0c;使用MS SQL示例&#xff0c;将展示如何在报表中创建和使用函数。Transact SQL允许创建存储过程和函数&#xff0c;存储过程用于自动执行任何操作&#xff0c;这些功能旨在扩展查询功能&#xff0c;它们…

Word无法插入公式项目灰色不可用

在我们平时办公或者是论文写作过程中&#xff0c;插入编辑公式是非常常见的操作。但是有时候我们打开Word点击插入发现公式图标为灰色且不可选。接下来我将介绍如何解决。 1、打开文档找到插入公式位置点击插入选项。 2、发现公式符号变为灰色且不可选择。 3、点击左上角的【文…

同源策略为什么可以防csrf_Spring Security 如何预防CSRF跨域攻击?

序言前面我们学习了 spring security 与 springmvc 的整合入门教程。spring secutity整合springboot入门spring security 使用 maven 导入汇总spring security 业界标准加密策略源码详解这一节我们来学习一下 spring security 是如何预防 CSRF 攻击的。拓展阅读web 安全系列-04…

centos移动文件到指定目录_Dynamo批量分离中心文件并另存到指定目录

我们在做项目的时候&#xff0c;为了方便协作&#xff0c;一般都会采用中心文件的方式&#xff0c;但是最终交付的时候&#xff0c;是需要把中心文件分离的&#xff0c;一个一个的分离&#xff0c;感觉还是他麻烦了&#xff0c;于是就想到用Dynamo来批量操作&#xff0c;简单测…

轻松监控Docker容器中的ADF应用程序

在这篇简短的文章中&#xff0c;我将展示一种简单的方法&#xff0c;以确保在Docker容器中运行的ADF应用程序在内存利用率方面是健康的Java应用程序。 我将使用标准工具JConsole&#xff0c;它是计算机上JDK安装的一部分。 如果存在问题&#xff08;例如&#xff0c;内存泄漏&a…

int型 判断奇偶_XSS(Reflected) 反射型跨站攻击

今天我学习一下反射型XSS。1、low级别打开DVWA网站&#xff0c;先切换到low级别&#xff0c;选择XSS&#xff08;Reflected&#xff09;先查看其源代码&#xff1a;<?php header ("X-XSS-Protection: 0"); // Is there any input? if( array_key_exists( "…

junit 运行_运行,JUnit! 跑!!!

junit 运行JUnit与JavaScript和SVN一起是程序员经常开始使用的一些技术&#xff0c;甚至没有读过一篇博客文章&#xff0c;更不用说一本书了。 也许这是一件好事&#xff0c;因为它们看起来足够简单并且易于理解&#xff0c;因此我们可以立即使用它们而无需任何手册&#xff0c…

将Host Cobol批次和Monolith Webapps移动到云和微服务

在Amazon Event “从大型机到微服务– Vanguard迁移到云”中非常有趣的演示。 以下部分可用作迁移模式 &#xff1a;如何从大型机迁移到微服务的不同方式&#xff1a; 重新托管 再造 重构 使用Linux和Java重新平台 回购 退役 全部结合 该演示文稿还展示了Vanguard的Cloud…

flutterapp部分手机无法打开_Flutter应用程序在最新更新后无法运行

Environment DetailsWindows VS CodeFlutter 1.17.5 • channel stable • https://github.com/flutter/flutter.gitFramework • revision 8af6b2f038 (3 days ago) • 2020-06-30 12:53:55 -0700Engine • revision ee76268252Tools • Dart 2.8.4Error From Debug ConsoleE…

android动态添加的页面怎么加功能_Android跳转应用安装页面

一.低版本跳转方式Intent intent new Intent(Intent.ACTION_VIEW);intent.setDataAndType(uri,"application/vnd.android.package-archive");intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivityForResult(intent, 666);uri是apk的uri记得不要忘了在mani…

字节数组转为二进制数 c#_如何使用字节序列化双精度数组(二进制增量编码,用于低差单调浮点数据集)...

字节数组转为二进制数 c#低延迟系统需要高性能的消息处理和传递。 由于在大多数情况下&#xff0c;数据必须通过有线传输或序列化才能保持持久性&#xff0c;因此编码和解码消息已成为处理管道的重要组成部分。 高性能数据编码的最佳结果通常涉及应用程序数据细节的知识。 本文…