懂个锤子Vue 项目工程化扩展:

Vue项目工程化扩展📶:

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

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

学习前置链接: 懂个锤子Vue 项目工程化 懂个锤子Vue 项目工程化进阶⏫

  • 🆗,上述学习了Vue组件的很多种通信方式,而除此之外还有很多隐藏的组件通信方式:
  • 本篇:扩展一些Vue的常见面试题、特殊操作词原理:

v-model 详解

v-model 是 Vue 框架中的一个内置指令:

用于在表单元素,如: inputtextareaselect)上创建双向数据绑定;

双向绑定: 指在视图View 和数据模型Model 之间建立的一种同步机制,通过这种机制:

  • 当视图中的数据发生变化时,数据模型会自动更新,同样,当数据模型发生变化时,视图也会自动更新
  • 双向同步的特性使得数据和视图之间的交互变得更加简便和高效;

它的本质是一种语法糖,简化了数据绑定和事件监听的过程:其原理:

  • 数据绑定v-model 将表单控件的值value,绑定到 Vue 实例的数据属性;

  • 事件监听v-model 监听用户对表单控件的输入事件,如 input 事件,并在用户输入时自动更新数据属性的值;

  • 视图更新:当数据属性的值发生变化时,v-model 自动更新表单控件的值,确保视图和数据的同步;

<template><div id="app" style="border: 3px solid #000; margin: 10px"><p>V-model 详解</p><p>v-model: <input v-model="msg" type="text"><br/></p>  <!-- 双向绑定; --><p>原始input <input :value="msg2" type="text"><br/></p> <!-- 并没有双向绑定; --><p>自定义v-model <input :value="msg3" @input="msg3 = $event.target.value" type="text"><br/></p><!-- 在input中绑定value:value="vue数据属性" --><!-- input本身有个事件叫input, 用于监听value的值, 在input事件中监听并给 msg3 重新赋最新的值;  完成自定义双向绑定 --></div>
</template><script>
export default {name: 'App',data() { return { msg:'',msg2:'',msg3:'',} },
}
</script>

在这里插入图片描述

  • 实际情况: 根据不同的表达元素会有不同的监听事件,输入表单: @input单选表单: @change=""

  • $event.target.value $event: 这是一个特殊变量,代表当前事件对象,

    .target: 事件对象的一个属性,它指向的是触发事件的那个具体的DOM元素

    .value: 当这个表达式用在表单元素上时,它返回的是该表单元素的当前值:value

表单类组件封装

表单类型组件的封装是前端开发中提高代码复用性和可维护性的重要实践: but,随着UI框架丰富,实际开发接触不多

在Vue.js项目中,结合Element UI这样的UI库,封装可以更加高效,自定义特有的样式风格;

  • 提高可维护性:组件化使得每个表单项独立,修改一处不影响其他部分

  • 简化开发:减少重复代码,通过配置即可生成不同的表单元素

  • 增强协作:团队成员可以独立开发各自的组件,减少合并冲突

  • 统一风格:确保整个应用的表单样式一致,增强用户体验

封装表单下拉框组件:

Demo 封装一个自定义表单:表单下拉框组件:

  • 自定义表单组件:/components/menu/BaseSelect.vue

    场景: 查询城市、区县下拉项目中很多地方都会使用,为了方便管理通常定义为一个组件,统一管理数据、样式;

  • 父组件调用: 子组件,及传递数据,部分情况如:修改信息会传递修改前的信息进行展示,默认情况也不会传递;

  • 子组件传递数据: 用户修改表单,表单监听输入,子传父——重新修改父组件值;

自定义组件: /components/menu/BaseSelect.vue

<template><div><!-- 绑定 :value 值 监听change事件: 获取值并传递给父组件 --><select :value="selectId" @change="selectCity"><!-- 组件内加载的下拉数据: --><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {//获取父组件传递的默认值;props: { selectId: String, },methods: {//@change:用户修改触发事件selectCity(e) {this.$emit('changeCity', e.target.value); //向父组件传递 新数据;},},
}
</script>
<style>/* 设置自定义表单样式 */</style>

App.vue 主组件:

<template><div id="app"><!-- 父组件传递数据: :selectId 父组件在子组件上,注册的 自定义属性传值;父组件通过在: 子组件标签上监听自定义事件,并绑定 获取值同步修改selectId;--><BaseSelect :selectId="selectId" @changeCity="selectId = $event" ></BaseSelect></div>
</template><script>
import BaseSelect from './components/menu/BaseSelect.vue'
export default {name: 'App',components:{ BaseSelect },data() { return { selectId: '102', } }, //默认选择102
}
</script>

在这里插入图片描述

v-model 表单下拉框组件:

父组件通过:v-model传递组件数据: 实现子组件和父组件数据双向绑定;

  • 父组件中: 使用 v-model 给组件直接绑数据,因为v-model本质是: :value + @input

    所以: v-model相当于调用子组件配置:<BaseSelect :value="selectId" @input="selecteId = $event" />

  • 所以:子组件中: 必须使用 props 通过 value(必须) 接收,事件触发名 input(必须)

在这里插入图片描述

<BaseSelect v-model="selectId" ></BaseSelect> 相当于:

<BaseSelect :value="selectId" @input="selectId = $event" ></BaseSelect> **要注意:与,子组件配合使用哦!

.sync 修饰符

.sync 修饰符是Vue.js 中用于实现父子组件间数据:双向绑定的一种特殊语法糖🍬 主要在Vue 2.x版本中使用:

特别是在需要:子组件能够直接修改父组件状态的场景下:

  • 简化双向数据流:.sync提供了一种更简洁的方式来实现子组件向父组件传递更新,避免了手动触发事件和监听的繁琐过程;

  • 维护数据流向:虽然Vue推崇单向数据流,但在某些复杂场景下,需要子组件能够影响父组件的状态

    .sync提供了一种控制这种需求的方法,同时保持代码的清晰;

.sync 修饰符使用:

.sync 和 v-model 使用类似: 但,相比v-model更高级方便,支持自定义:父子组件传递属性值

  • 假设我们有一个父组件和一个子组件: 父组件引入子组件,并设置传递属性|值:<子组件 :属性名.sync="xxx" ></子组件>
  • 子组件通过:props:['属性名'] 获取父组件传递值,如需传递|修改父组件数据:
  • 子组件通过:this.$emit('update:属性名', "传递值"); 更新修改父组件数据;

v-model: 实现组件双向绑定,固定了父子传递属性value、监听事件名对应表单的修改事件名

.sync: 可以不局限表单组件,且支持自定义属性名,监听事件名@update:属性名相比之下更加,灵活方便;

封装弹框类的基础组件:

Demo场景: 封装弹框类的基础组件,使用visible属性 true|false显示|隐藏,组件;

在这里插入图片描述


在这里插入图片描述

.sync 与 v-model 区别:

.sync修饰符和 v-model 都是Vue.js中用于实现组件间数据绑定的机制:

.sync修饰符:

.sync主要用于父子组件间的双向数据绑定, 特别是在Vue 2.x中;

它允许子组件修改父组件传递的属性值,通过触发一个特定的事件,通常是update:属性名 来实现;

可以用于: 多个属性,实现对多个数据项的双向绑定 ,不限于特定类型的元素或组件,适用于任何需要双向数据流的场景;

v-model

v-model 是Vue提供的一个指令,主要用于表单输入元素,实现数据的双向绑定;

对于原生表单元素: v-model通常等价于value属性绑定和对应的输入事件监听;

对于自定义组件: v-model内部转换为value的prop和input事件的监听;

在一个组件中只能有一个v-model,因为它代表单一的数据绑定点;

固定了父——子组件传递值:value

总结:

适用场景:v-model更适合简单的表单输入双向绑定,而.sync适用于需要子组件修改父组件数据的复杂场景

版本差异:在Vue 3中,.sync已被废弃,推荐使用Composition API中的方法来实现类似功能

而v-model依然存在,且支持更广泛的类型和自定义行为

灵活性:.sync提供了更灵活的双向绑定方式,尤其是在需要子组件影响父组件状态时

而v-model则更专注于简化用户体验设计中的数据绑定

ref 和 $refs:

在Vue框架中,ref$refs 是用于: 访问、操作组件内部、子组件的DOM元素及实例的关键特性:

ref是一个属性: 可以被添加到Vue模板中的元素、组件上:

  • 元素上: 当应用在普通的HTML元素上时,通过this.$refs可以访问到该元素的DOM节点;

  • 组件上: 当应用在子组件上时,this.$refs将指向:该子组件的实例,允许你调用其方法或访问其数据;

    超级厉害的一个功能: 但注意:可以获取子组件的实例、属性、函数….,但并不能修改!!

$refs是一个对象,它包含了所有通过ref定义的引用:

  • 重要的是要注意: $refs中的引用在DOM渲染完成后才可用,因此通常在:mounted() 钩子中访问,确保元素\组件存在;
  • 当在v-for循环中使用ref时: 如果引用名相同,this.$refs[refName] 会返回一个包含所有对应元素或组件的数组;

ref 和 $refs 获取DOM:

通常情况,我们想要获取一个DOM元素:使用JS的 document.querySelector('选择器..');

这就有一个问题,如果存在相同选择器,就会获取到多个元素,而无法准确的获取某个DOM,当然可以通过设置ID选择器

实际开发中,并不建议设置特别多的ID,且组件化开发: 最后会将组件,合并为一个html 页面,导致无法准确获取对应DOM;

  • ref 属性类似于ID,定义在元素属性上:<元素 ref="属性x" ></元素>
  • JS中通过this.$refs.属性x可快速访问到该元素的DOM节点,匹配最后一个匹配的属性;
<template><div><p class="w" ref="w" >组件中的p属性</p><p ref="w" >组件中的p2属性</p></div>
</template><script>
export default {//通常在:`mounted()` 钩子中访问,确保元素\组件存在;mounted() {//子组件中的P标签 和 父组件中P标签 相同的属性;//因为: 组件最终会合并为一个html页面所以,会发送元素冲突情况: 获取class="w" DOM设置样式;var mydom = document.querySelector('.w');mydom.style.fontSize = '30px';    // 设置字体大小mydom.style.fontWeight = 'bold';  // 设置字体加粗//使用 $refs 获取Domvar mydom2 = this.$refs.w;mydom2.style.fontSize = '30px';    // 设置字体大小mydom2.style.fontWeight = 'bold';  // 设置字体加粗}
}
</script>
<style>/* 设置自定义表单样式 */</style>

在这里插入图片描述

ref 和 $refs 获取组件:

ref 和 $refs最强大之处莫过于: 直接获取组件的实例、属性、函数;

  • 父组件引用子组件: 并在子组件上定义ref值: <子组件 ref="属性x" ></子组件>
  • 即可在父组件:mounted钩子函数中: this.$refs.属性x; 直接获取子组件实例,并通过实例获取:实例对象;

主组件$refs调用 子组件:

<template><div id="app"><!-- 干扰组件,获取Dom --><p class="w" >干扰组件,获取Dom</p><BaseStr ref="ww" ></BaseStr><!-- 引入组件 --></div>
</template><script>
import BaseStr from './components/menu/BaseStr.vue'
export default {name: 'App',components:{ BaseStr },mounted(){//获取子组件实例:var myzzj = this.$refs.ww;console.log(myzzj.str);myzzj.show();}
}
</script>

在这里插入图片描述

Vue异步更新、$nextTick

Vue的异步更新机制和$nextTick方法是其核心特性之一:

用于优化:DOM更新的性能,管理数据变化与视图更新之间的关系;

异步更新机制

Vue采用异步更新策略来处理数据变化与DOM的同步:

  • 当数据发生变化时,Vue并不会立即更新视图,而是将这些变更放入一个队列中;

  • 这个队列会在当前JavaScript执行环境的事件循环结束之后,或在下一个宏任务如:

    setTimeout、setInterval、I/O完成等之前被处理:目的是合并多个数据变化,减少不必要的DOM操作,提高性能;

同时也导致一些问题: 由于数据变化和视图更新不是即时的,这可能导致调试时的逻辑断层

Demo需求: 点击页面编辑按钮,显示一个输入框,并立即获取编辑框的焦点因为异步更新机制: 立刻获取焦点失败!

$nextTick 解决逻辑断层:

$nextTick是一个方法,它允许开发者指定一个回调函数: 该函数将在Vue完成其当前的DOM更新周期后执行:

  • 这意味着,当你在数据变化之后立即需要访问更新后的DOM时
  • 可以使用$nextTick 来确保你的代码在DOM已经根据最新的数据渲染之后执行,
  • 可以在组件生命周期钩子中,如mounted()updated(),确保DOM已经更新后再执行某些操作;

编辑按钮\显示输入框\立即获取焦点

在更新数据的函数中,定义:$nextTick回调函数;

当函数内操作的数据修改后,等待DOM更新执行回调函数,完成对DOM的操作,解决了页面逻辑断层渲染问题;

<template><div class="app"><!-- 默认不展示编辑框 --><div v-if="isShowEdit"> <input type="text" v-model="editValue" ref="inp" /> <button>确认</button> </div><div v-else><button @click="editFn">编辑</button></div></div>
</template><script>
export default {data() {return { isShowEdit: false, editValue: '', }  //默认不展示编辑框},methods: {editFn() {// 1.显示文本框this.isShowEdit = true      //修改data数据 显示编辑框// 2.让文本框聚焦\$nextTick等dom更新完之后 立马执行nextTick中的回调函数// this.$refs.inp.focus()   //使用: $refs 获取指定的DOM元素focus()设置焦点,因为异步刷新机制Dom并不会立刻更新;this.$nextTick(() => {console.log(this.$refs.inp)this.$refs.inp.focus()})},},
}
</script>
<style></style>

在这里插入图片描述

$nextTick还可以使用微任务,如:Promise、MutationObserver

或宏任务如:setTimeout,优先使用微任务来实现;

代码管理:

本代码已经使用Git进行管理: 公众号回复:Vue项目工程化

在这里插入图片描述

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

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

相关文章

WEB前端开发中如何实现大文件上传?

大文件上传是个非常普遍的场景&#xff0c;在面试中也会经常被问到&#xff0c;大文件上传的实现思路和流程。在日常开发中&#xff0c;无论是云存储、视频分享平台还是企业级应用&#xff0c;大文件上传都是用户与服务器之间交互的重要环节。随着现代网络应用的日益复杂化&…

康师傅JAVA核心内容

链接&#xff1a;康师傅JAVA核心内容 (qq.com)

黑龙江等保测评如何做到既全面又高效?

在黑龙江省进行等保测评&#xff0c;必须在全面和高效之间寻求一个平衡点&#xff0c;以保证网络的安全性和可靠性。黑龙江等保测评怎样才能在二者之间发现黄金交汇点&#xff1f;下面&#xff0c;我们来揭开谜底。 精准定位&#xff0c;明确测评范围 首先&#xff0c;一个综…

Docker与LXC差异以及相关命令

容器&#xff1a;Docker与LXC差异以及相关命令 ​ LXC与Docker对比&#xff0c;LXC只实现了进程沙盒化&#xff0c;不支持在不同的机器上进行移植&#xff1b;Docker将应用的所有配置和环境进行了抽象&#xff0c;打包到一个容器中&#xff0c;此容器可以在任何安装了docker的…

vscode搭建rust开发环境

由于rustrover不是免费的&#xff0c;此处教学搭建一套基于vscode的rust开发环境&#xff0c;可运行&#xff0c;可调式 1.下载vscode1.91.1 Download Visual Studio Code - Mac, Linux, Windows 2.下载插件 打开网站下载插件 rust-analyzer-0.4.2049、vscode-lldb-1.10.0、…

IDEA项目的依赖(pom.xml文件)导入问题及解决

前言&#xff1a;该文章为转载&#xff0c;没有仔细的看 IDEA新建项目和pom.xml文件被修改时&#xff0c;右下角都会出现 Maven projects need to be imported&#xff08;项目需要导入依赖&#xff09; 如下&#xff0c;点击 Import Changes导入后&#xff0c;有时会一直处于…

NAS、SAN 与 DAS 的比较与应用场景

文章目录 1. NAS&#xff08;网络附加存储&#xff09;定义特点实现成本&#xff1a;适用场景 2. SAN&#xff08;存储区域网络&#xff09;定义特点实现成本&#xff1a;适用场景 3. DAS&#xff08;直接附加存储&#xff09;定义特点实现成本&#xff1a;适用场景 区别总结结…

Redis学习[1] ——基本概念和数据类型

Redis学习[1] ——基本概念和数据类型 一、Redis基础概念 1.1 Redis是什么&#xff0c;有什么特点&#xff1f; Redis是一个基于**内存的数据库&#xff0c;因此读写速度非常快**&#xff0c;常用作缓存、消息队列、分布式锁和键值存储数据库。支持多种数据结构&#xff1a;…

Java 内推 | 教育行业缺口来了,研发,运维,产品,教研,职能,营销... 别错过

Java 内推 | 教育行业缺口来了&#xff0c;研发&#xff0c;运维&#xff0c;产品&#xff0c;教研,职能&#xff0c;营销… 别错过 岗位职责&#xff1a; 1、根据公司战略及业务规划&#xff0c;参与部门业务架构分析与设计&#xff0c;包含规划立足当前、面向未来的应用架构…

源码编译安装,及nginx服务控制、监控块

1.源码编译安装&#xff1a; [root17dns ~]# wget https://nginx.org/download/nginx-1.27.0.tar.gz 2.解压&#xff1a; [root17dns ~]# tar -zxvf nginx-1.27.0.tar.gz 3.安装gcc等工具 [root17dns ~]# yum -y install gcc gcc-c [root17dns ~]# yum -y install make lrzsz …

postman给全部接口添加请求头数据(如token)

如果给没有一个接口添加请求头token就太慢了&#xff0c;如下图。可以点击所有接口的所属的目录。点击“Scripts”&#xff0c;点击Pre-request按钮。加入代码&#xff1a; pm.request.addHeader("Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI111pXVCJ9.eyJjbGFpbXMiOnsiaW…

小红书笔记评论采集全攻略:三种高效方法教你批量导出

摘要&#xff1a; 本文将深入探讨如何利用Python高效采集小红书平台上的笔记评论&#xff0c;通过三种实战策略&#xff0c;手把手教你实现批量数据导出。无论是市场分析、竞品监测还是用户反馈收集&#xff0c;这些技巧都将为你解锁新效率。 一、引言&#xff1a;小红书数据…

项目实战_表白墙(简易版)

你能学到什么 一个比较简单的项目&#xff1a;表白墙&#xff08;简易版&#xff09;&#xff0c;浏览器&#xff1a;谷歌升级版将在下个博客发布 效果如下 正文 说明 我们是从0开始一步一步做这个项目的&#xff0c;里面的各种问题&#xff0c;我也会以第一人称视角来解…

yolov10在地平线旭日X3派上的部署和测试(Python版本和C++版本)

0、搭建开发环境 当前的测试根据一下的步骤并修改源码是可以实现yolov8的板端运行&#xff0c;如果不想再搭建环境和测试代码bug上浪费更多的时间可以直接获取本人的测试虚拟机&#xff0c;所有的测试代码、虚拟环境和板端测试工程以全部打包到了虚拟机&#xff0c;需要的可以…

OpenBayes 教程上新 | 文生图、图生图、图像修复三合一神器, HiDiffusion 一键启动教程现已上线!

扩散模型已成为高分辨率图像合成的主流方法&#xff0c;传统的扩散模型虽然在图像合成方面取得了显著进展&#xff0c;但在扩展到更高分辨率时往往面临对象重复和计算成本增加的问题。 旷世科技开源的高分辨率框架 HiDiffusion&#xff0c;由分辨率感知 U-Net (RAU-Net) 和改进…

求最大公约数与最小公倍数(C语言 简洁快速版)

求最大公约数 辗转相除法&#xff08;首选&#xff0c;因为简单快捷&#xff09; 思路&#xff1a; 1.将两整数求余 a%b c 2.如果c 0;则b为最大公约数 3.如果c ! 0,则 a b&#xff1b;b c&#xff1b;继续从1开始执行 4.也就是说该循环的是否继续的判断条件就是c是否为0 …

3.4、图

图的介绍 图也是一种非线性结构&#xff0c;图中任意两个节点间都可能有直接关系。相关定义如下&#xff1a; 无向图&#xff1a;图的结点之间连接线是没有箭头的&#xff0c;不分方向。 有向图&#xff1a;图的结点之间连接线是箭头&#xff0c;区分A到B,和B到A是两条线。 …

Codeforces 962 div3 A-F

A 题目分析 签到 C代码 #include<iostream> using namespace std; int main(){int t;cin>>t;while(t--){int n;cin>>n;cout<<n/4n%4/2<<endl;} } B 题目分析 将n*n的方格分成若干个k*k的方格&#xff0c;每个k*k的方格中所有的数都相同 遍历…