Vue.js之MVVM设计模式

前言

看到招聘信息网站上有对MVVM框架经验的需求,刚好曾有过这方面的笔记,在复习的同时总结核心知识点分析给大家。
MVVM是可以实现View和Model的完全分离,通过ViewModel这个桥梁进行交互,然后ViewModel通过双向数据绑定把View层和Model层连接起来,而View层和Model层之间的通信则完全由ViewModel负责。

一、MVC设计模式与MVVM设计模式,vue.js

1、什么是MVC设计模式

MVC是一种最早出现的软件架构模式,它将应用程序的输入、处理和输出明确地划分为三个部分,使得业务逻辑、数据和界面显示可以独立地进行开发、测试和维护。其中MVC指的是Model(模型)、View(视图)、Controller(控制器)

2、为什么还需要MVVM设计模式

在MVC中,Controller负责处理用户输入,并更新Model和View。View被动地接受Controller传来的数据,并显示给用户。而在MVVM中,ViewModel是连接Model和View的桥梁,它实现了View和Model的双向绑定,当Model中的数据变化时,View会自动更新;同样,View中的数据变化也会反映到Model中。所以它比MVC更容易实现复杂的用户界面和数据交互。

二、使用vue框架

vue框架的好处可以不用自己完成复杂的DOM操作了,而由框架帮我们去完成,同时可以使用组件化开发,子组件与父组件之间可以通过触发事件进行通信,从而改变数据,可以使我们很好的复用代码。

1、使用html,js,css在线运行代码

使用链接在线访问vue.global.js或者安装下载vue.global.js在本地项目中
如果想要切换版本

  • 链接:切换版本
<!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><script src="./vue.global.js"></script>
</head>
<body><div id="app">{{message}}<input type="text" v-model="message"></div><script>let app=Vue.createApp({data(){return{message: 'hello world'}}})let vm=app.mount('#app')</script>
</body>
</html>

2、选项式API

let vm=createApp({//选项methods:{},computed:{},watch:{},data(){},mounted(){},
}).mount('#app');

3、声明式渲染

声明式渲染是Vue.js等前端框架的核心概念之一。它意味着开发者只需描述数据应该如何渲染,而不需要手动操作DOM来更新视图。其中messgae可以是js表达式,如字符串,数组,方法

<body><div id="app">{{message}}</div><script>let vm = Vue.createApp({data() {return {message: 'hello world'}}}).mount('#app')setTimeout(()=>{vm.message='world hello'},1000)</script>
</body>
  • proxy内置对象

vm.message利用的原理是Es6的Proxy对象对底层进行监控
Proxy 用于创建一个对象的代理,从而实现对目标对象某些操作的拦截和自定义。比如:
拦截和自定义操作:使用 Proxy 来拦截对目标对象的各种操作,并在这些操作发生时执行自定义代码。
验证和转换:利用 Proxy 来确保目标对象的属性总是符合某些条件,或者在读取或设置属性时执行某些转换。
日志和调试:通过 Proxy,记录对目标对象的所有操作

<!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><script src="./vue.global.js"></script>
</head><body><div id="app">{{message}}</div><script>let data={message:'hello world'};data=new Proxy(data,{// 发生改变时触发setset(target,key,value){console.log(target, key, value,'set')app.innerHTML = value},// 默认执行getget(target){console.log(target.message,'get')return target.message}})app.innerHTML= data.messagesetTimeout(() => {data.message = 'world hello'}, 1000)</script>
</body></html>

4、指令系统与事件方法及传参处理

  • vue指令

常用指令的有v-if,v-else,v-else-is,v-for,v-show,v-on,v-bind,v-model,v-html等,
v-bind:title相当于:title,v-on:click相当于@click

  • 事件方法

methods选项向组件实例添加方法,Vue自动为methods 绑定this,以便于它始终指向组件实例

  • 传参处理

Vue帮我们处理好了如何进行事件传参处理,提供了内部的$event语法来获取event对象

<!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><script src="./vue.global.js"></script>
</head>
<body><div id="app"><div :title="message" :class="className" @click="handleClick($event,123)">{{message}}</div></div><script>let vm=Vue.createApp({data(){return {message: '点击一下有惊喜',className: 'box'}},methods: {handleClick(event,num){this.message='hello world';console.log(event,num,'event,num')}}}).mount('#app')</script>
</body>
</html>

5、计算属性

split(' ').reverse().join(' ')使用空格将字符串变成数组,然后数组顺序颠倒,最后转回字符串类型如。

  • 计算属性computed

调用方法时,若写在methods里需要再方法后加上(),如果是写在computed里,直接写上方法名即可调用

//methods
handleClick()
//computed
handleClick
  • 计算属性与方法相比

具备缓存的能力,而方法不具备缓存,在依赖的数据未改变时,即使调用了两次相同方法,计算属性只执行一次,而在methods里会执行两次。且计算属性只读取不能修改,要想修改,得修改最终依赖的东西。

  • 计算属性原理

计算属性虽然是对象方法,但是以属性的方式进行使用,并且默认是只读的

6、侦听器watch

  • 原理

侦听器是在监听的属性发生改变的时候才会触发,初始时是不会触发的

wathc:{message(newVal,oldVal){console.log(newVal,oldVal);}
}
  • 侦听器与计算属性区别

计算属性适合:多个值去影响一个值的应用;而侦听器适合:一个值去影响多个值的应用,
同时侦听器支持异步的程序,而计算属性不支持异步的程序。
如计算一个加法,由两个变量得出加法的和,这是就需要用到计算属性,而侦听器一般是在异步加载请求后,对后端返回的api进行处理。

7、条件渲染v-if

条件渲染:使用v-if指令条件性地渲染一块内容。这块内容只会在指令的表达式返回真值的时候被渲染。
同时被认为是假值fasle的有(false,0,空字符串,null,undefined和NaN ),
注意:空数组([])在布尔上下文中会被转换为true,因为数组对象总是真值,但是可以使用arr.length来判断

8、 列表渲染v-for

  • v-for用法

v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items形式的特殊语法,其中items是源数据数组,而item 则是被迭代的数组元素的别名。

<!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><script src="./vue.global.js"></script>
</head><body><div id="app"><!-- key是用来跟踪每一个遍历项的身份 --><div v-for="item,index in list" :key="index">{{item}}{{index}}</div><div v-for="value,key,index in info">{{value}}{{key}}{{index}}</div><div v-for="item in test">{{item}}</div><!-- num类型和字符串也可以遍历,数字从1开始到num,字符串逐步返回单个字符类型 --></div><script>let vm = Vue.createApp({data() {return {list:['a','b','c'],info:{username:'小明',age:20},test:'hello world'}}}).mount('#app')</script>
</body></html>
  • 注意v-for不建议与v-if同时使用,可以使用计算属性来实现
<!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><script src="./vue.global.js"></script>
</head><body><div id="app"><div v-for="item,index in updateList" :key="index">{{item.str}}{{index}}</div></div><script>let vm = Vue.createApp({data() {return {list:[{id:1, str:'a'},{id:2, str:'b'},{id:3, str:'c'},],}},computed:{updateList(){return this.list.filter((v)=>v.id%2 ===1)}}}).mount('#app')</script>
</body></html>
  • 在vue中,通常v-for,v-if通常是在template上使用,

9、calss和style的三种使用方式

1)、class的三种使用方式

  • 对象语法

通过绑定一个对象到:class,你可以动态地切换class。

<div :class="isActive ? 'active-class' : 'inactive-class'"></div>
<script>export default {data() {return {isActive: true};}};
</script>
  • 数组语法

将一个数组绑定到:class,以应用一个类列表。数组中的每个元素都会是一个类名。
在这个class绑定的例子中,isActive为true时,active类会被添加,而base-class则始终被添加
这个三元表达式只会判断isActive ? 'active' : '',

<template><div :class="[isActive ? 'active' : '', 'base-class']"></div>
</template>
<script>
export default {data() {return {isActive: true};}
};
</script>
  • 在组件上使用

当在Vue组件上使用class时,可以直接在组件标签上添加静态的class,同时使用:class来动态绑定。

<template><my-component :class="isActive ? 'active-class' : 'inactive-class'"></my-component>
</template>

2)、style的三种使用方式

与calss用法相似

  • 对象语法
<template><div :style="{ color: isActive ? 'aqua' : 'pink' }">Hello world</div>
</template>
<script>
export default {data() {return {isActive: true};}
};
</script>
  • 结合数组和对象语法
<template><div :class="[isActive ? 'active' : '', 'base-class']"></div>
</template>
<script>
export default {data() {return {isActive: true};}
};
</script>
  • 在组件上使用
<template><my-component :style="{ color: isActive ? 'aqua' : 'pink' }"></my-component>
</template>

3)、数组语法的demo

<!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><script src="./vue.global.js"></script><style>.box1{background: aqua;}.box2{color: rebeccapurple;background: orange;}</style>
</head><body><div id="app"><div :class="myClass">123</div></div><script>let vm = Vue.createApp({data() {return {myClass:['box1','box2']}}}).mount('#app')setTimeout(()=>{//删除数组的最后一项vm.myClass.pop();},2000)</script>
</body></html>

10、表单处理与双向绑定

  • 实现双向绑定一般做法
<!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><script src="./vue.global.js"></script>
</head><body><div id="app"><input type="text" :value="message" @input="message=$event.target.value"></div><script>let vm = Vue.createApp({data() {return {message: 'hello world'}}}).mount('#app')setTimeout(() => {vm.message='world hello'}, 2000)</script>
</body></html>
  • v-model也能实现双向绑定

在Vue中是通过v-model指令来操作表单的,可以非常灵活的实现响应式数据的处理
v-model本质上不过是语法糖。可通过value属性+input或change事件来实现同样的效果

<!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><script src="./vue.global.js"></script>
</head><body><div id="app"><input type="text" v-model="message"></div><script>let vm = Vue.createApp({data() {return {message: 'hello world'}}}).mount('#app')setTimeout(() => {vm.message='world hello'}, 2000)</script>
</body></html>
  • checkbox,radio表单类型

表单为checkbox,多选框,radio单选框时,v-modal绑定相同属性

  • select下拉选项
<body><div id="app"><select v-model="city"><option value="成都">成都</option><option value="重庆">重庆</option><option value="北京">北京</option></select>{{city}}</div><script>let vm = Vue.createApp({data() {return {city:'北京'}}}).mount('#app')</script>
</body>

11、生命周期构子函数及原理分析

生命周期钩子

初始化实例触发顺序钩子
beforeCreate此时还不能访问到数据和 DOM,响应式数据页拿不到
created在实例创建完成后被立即调用。响应式数据页可以拿到但是此时还是不能访问到数据和 DOM,
beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用。此时,虚拟 DOM 已经创建完成,但还没有挂载到真实的 DOM 上
mounted此时都能拿到响应式数据和DOM

更新数据时触发
beforeUpdate 在更新数据的时候会触发的生命周期,不能拿到更新后的内容
updated在更新数据后 会触发的生命周期,能拿到更新后的内容

不常用
activatedkeep-alive 组件激活时调用。
deactivatedkeep-alive 组件停用时调用。

卸载实例时触发
beforeUnmount组件实例卸载之前调用。在这一步,实例仍然完全可用。
unmounted组件实例卸载后调用,所有的事件监听器都会被移除,所有的子实例也会被销毁。

不常用
errorCaptured当捕获一个来自子孙组件的错误时被调用。
此钩子会接收三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上冒泡。
renderTracked在响应式依赖被追踪时调用。
renderTriggered在响应式依赖发生改变并导致组件重新渲染时被调用。

12、扩展JavaScript里的fetch函数使用

用于在浏览器中进行网络请求,它提供了一种简单、合理的方式来跨网络异步获取资源。fetch 返回的是一个 Promise 对象,通常用.then() 或async/await 来处理它的响应,默认不发送或接收 cookies。
fetch()发送请求里可以请求的 URL、请求方法和请求JSON数据

<!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><script src="./vue.global.js"></script>
</head><body><div id="app"><ul><li v-for="item in filterList" :key="item.id">{{item.name}}</li></ul></div><script>let vm = Vue.createApp({data() {return {list: []}},created() {fetch('./test.json')// 解析响应体为 JSON.then((res) => res.json()).then((res) => {this.list = res})},computed:{filterList(){return this.list}}}).mount('#app')</script>
</body></html>
[{"id": 1,"name": "小明","gender": "女","age": 20},{"id": 2,"name": "小强","gender": "男","age": 18},{"id": 3,"name": "大白","gender": "女","age": 25},{"id": 4,"name": "大红","gender": "男","age": 22}
]

13、javascript中解构对象使用

<script>const obj = {name: 'yibo',age: 25,gender: 'female'};const { gender, ...newObj } = obj;console.log(obj,'obj'); // [ 'name', 'age', 'gender' ]console.log(newObj,'newObj'); // [ 'name', 'age']console.log(gender,'gender')</script>

14、javascript中filter过滤

filter() 方法遍历数组的每个元素,并返回一个新数组,其中只包含那些使得提供的函数返回 true 的元素。
经常用于过滤筛选不需要的值

this.list.filter((v)=>v.id%2 !==2)

15、v-for中处理特殊项

<div v-for="(item, index) in items" :key="index"><div v-if="item.special" :class="{ 'special-item': true }"><!-- 特殊项的处理方式 -->{{ item.name }} (with special feature)</div><div v-else><!-- 普通项的处理方式 -->{{ item.name }}</div>
</div><style>.special-item {color: red;font-weight: bold;}
</style>

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

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

相关文章

Linux SDIO-WiFi 协议栈

Linux SDIO-WiFi 协议栈 1. 简介2. BCMDHD2.1 WiFi模组2.2 驱动初始化&#xff08;dhd_module_init&#xff09; 3. Broadcom fullmac WLAN 1. 简介 2. BCMDHD BCMDHD&#xff1a;Broadcom Dongle Host DriverSIP&#xff1a;System In Package 2.1 WiFi模组 2.2 驱动初始化…

web server apache tomcat11-12-SSL/TLS Configuration

前言 整理这个官方翻译的系列&#xff0c;原因是网上大部分的 tomcat 版本比较旧&#xff0c;此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎&#xff0c;轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…

Java、Tomcat、Apache HTTP Server以及浏览器服务器的关系

一.浏览器服务器有哪些 浏览器服务器是指在互联网上扮演服务器角色的设备或程序&#xff0c;用于响应浏览器发出的请求并向浏览器返回相应的数据。 常见的浏览器服务器有以下几种&#xff1a; Apache HTTP Server&#xff1a;这是世界上最常用的web服务器软件之一&#xff0c;…

spring DisposableBean作用,在spring Bean销毁时的钩子 以及@PreDestroy

DisposableBean 作用 在Spring框架中&#xff0c;DisposableBean是一个接口&#xff0c;它定义了一个单一的方法&#xff0c;用于在Spring容器关闭时或一个由Spring管理的Bean不再需要时执行特定的清理操作。当一个Bean实现了DisposableBean接口&#xff0c;Spring容器会在销毁…

Windows创建类似Linux软连接、Windows软连接、快捷方式

Windows创建软连接 mklink 在 Windows 系统上&#xff0c;可以使用 mklink 命令来创建类似 Linux 的软连接&#xff0c;也称为符号链接。软连接是一种指向另一个文件或目录的链接&#xff0c;它允许您使用不同的名称来访问相同的文件或目录。与快捷方式不同&#xff0c;软连接…

Integer缓存池知道吗?

因为根据实践发现大部分的数据操作都集中在值比较小的范围&#xff0c;因此Integer搞了个缓存池&#xff0c;默认范围是-128到127&#xff0c;可以根据通过设置JVM-XX: AutoBoxCacheMax <size>来修改缓存的最大值&#xff0c;最小值改不了。 实现的原理是int在自动装箱…

IntelliJ IDEA - 10 款 IDEA 宝贝插件,YYDS!

好久没发这种实用贴了&#xff0c;最近用到了一些能提升工作效率的IDEA插件&#xff0c;给小伙伴们分享一下。相信我&#xff0c;我分享的这些插件&#xff0c;都是实实在在能解决实际开发场景中痛处的。 1、POJO to JSON 开发工作中&#xff0c;常常在设计完API后&#xff0c…

【每日算法】理论:深度学习基础 刷题:栈与队列的转换

上期文章 【每日算法】理论&#xff1a;深度学习基础 刷题&#xff1a;KMP算法思想 文章目录 上期文章一、上期问题二、本期理论问题1、RAW图像和RGB图像的区别&#xff1f;2、LSTM模型3、卷积层和池化层有什么区别4、tokenizer 的分词方法有那些&#xff1f;5、10亿个参数的模…

FPGA实现AXI4总线的读写_如何写axi4逻辑

FPGA实现AXI4总线的读写_如何写axi4逻辑 一、AXI4 接口描述 通道信号源信号描述全局信号aclk主机全局时钟aresetn主机全局复位&#xff0c;低有效写通道地址与控制信号通道M_AXI_WR_awid[3:0]主机写地址ID&#xff0c;用来标志一组写信号M_AXI_WR_awaddr[31:0]主机写地址&…

Nest.js项目初始配置

1.全局安装nest pnpm add -g nestjs/cli nodemon ts-node 2.创建nest项目 nest new project-name 3.安装依赖 pnpm add prisma-binding ts-node prisma/client mockjs nestjs/config class-validator class-transformer argon2 nestjs/passport passport passport-local n…

如何一键清除文件目录下所有的node_modules

如何一键清除文件目录下所有的node_modules 快速删除目录下的node_modules&#xff0c;下面附上windows和mac的脚本指令 windows脚本 FOR /d /r . %d in (node_modules) DO IF EXIST "%d" rm -rf "%d"mac脚本 find . -name "node_modules" -…

最短路问题之Bellman-Ford,SPFA算法,例题 负环

Bellman-Ford算法&#xff1a; Bellman-Ford算法用于解决带有负权边的单源最短路径问题。其基本思想是通过不断地松弛边来逐步求解最短路径。算法的主要步骤如下&#xff1a; 初始化&#xff1a;将源点到各个顶点的距离初始化为无穷大&#xff0c;源点的距离初始化为0。重复更…

JavaScript 变量 及 案例练习

变量 一. 变量是什么: 问题1: 用户输入的数据我们如何存储起来? 答案1: 使用变量 理解变量是如何存储数据的 “容器” **变量: ** 白话: 变量就是一个装东西的盒子通俗: 变量是计算机中用来存储数据的 “容器” , 它可以让计算机变得有记忆注意: 变量不是数据本身, 它们仅…

IDEA2023版本创建Sping项目无法使用Java8

1. 问题复现 1.1 当前版本2023.3.2 1.2 创建项目时&#xff1a;不存在jdk8选项 提示报错 1.3 原因分析 Spring官方发布Spring Boot 3.0.0 的时候告知了一些情况&#xff0c;Java 17将成为未来的主流版本 2. 如何解决 2.1 替换创建项目的源 我们只知道IDEA页面创建Spring项目…

对Java未来的发展趋势和新技术的看法

Java作为一种广泛使用的编程语言&#xff0c;已经走过了数十年的历程&#xff0c;其在企业级应用开发、大数据处理、云计算等多个领域都发挥着重要作用。随着技术的不断进步&#xff0c;Java也在不断发展&#xff0c;呈现出一些新的趋势和新技术。以下是对Java未来发展趋势和新…

Mysql 的char 和varchar的的区别

1、char 和varchar 区别 下面以utf8字符集为例&#xff0c;char和varchar的占比计算&#xff0c;如下图 valueChar(5)bytesVarchar(5)bytesVarchar(100&#xff09;bytes‘’‘ ’15‘’1‘’1‘abcd’‘abcd ’15‘abcd’13‘abcd’13abcdeabcde15abcde16abcde16 varchar使用…

【PHP快速上手(十四)】

目录 PHP快速上手&#xff08;十四&#xff09;PHP 中常用数据库操作使用 WHERE 子句进行条件查询使用 ORDER BY 子句进行排序使用 UPDATE 语句更新数据使用 DELETE 语句删除数据执行事务总结 PHP快速上手&#xff08;十四&#xff09; PHP 中常用数据库操作 当使用 PHP 中的…

NumPy 1.26 中文文档翻译完成

NumPy 1.26 中文文档NumPy 用户指南开始入门什么是 NumPy&#xff1f;NumPy 快速开始NumPy: 绝对初学者的基础知识基础与用法NumPy 基础知识MATLAB 用户的 NumPyNumPy 特性NumPy 如何操作高级用法和互操作性从源码编译使用 NumPy C-APIF2PY 用户指南和参考手册开发人员的底层文…

kubernetes中的静态POD

我们都知道&#xff0c;pod是kubelet创建的&#xff0c;那么创建的流程是什么呐&#xff1f; 此时我们需要了解k8s中config.yaml配置文件了&#xff1a; 他的存放路径&#xff1a; 【/var/lib/kubelet/config.yaml】 一、查看静态pod的路径 [K8Sk8s-master ~]$ sudo cat /va…

前端中的promise.all()的使用

理解和使用Promise.all和Promise.race 一、promise.all的使用 说明 Promise.all 可以将多个Promise实例包装成一个新的Promise实例&#xff0c;等待所有都完成&#xff08;或第一个失败&#xff09;返回值 成功的时候返回的是一个数组&#xff0c;失败的时候则返回先被…