网站首页 > 技术文章 正文
mvc和mvvm理解
MVC
MVC即Model View Controller,简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示。
- View 接受用户交互请求
- View 将请求转交给Controller处理
- Controller 操作Model进行数据更新保存
- 数据更新保存之后,Model会通知View更新
- View 更新变化数据使用户得到反馈
MVVM
MVVM即Model-View-ViewModel,将其中的 View 的状态和行为抽象化,让我们可以将UI和业务逻辑分开。MVVM的优点是低耦合、可重用性、独立开发。
- View 接收用户交互请求
- View 将请求转交给ViewModel
- ViewModel 操作Model数据更新
- Model 更新完数据,通知ViewModel数据发生变化
- ViewModel 更新View数据
MVVM模式和MVC有些类似,但有以下不同
- ViewModel 替换了 Controller,在UI层之下
- ViewModel 向 View 暴露它所需要的数据和指令对象
- ViewModel 接收来自 Model 的数据
概括起来,MVVM是由MVC发展而来,通过在Model之上而在View之下增加一个非视觉的组件将来自Model的数据映射到View中。
响应原理
vue采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty劫持data属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
生命周期函数
- beforeCreate(创建前) vue实例的挂载元素$el和数据对象 data都是undefined, 还未初始化
- created(创建后) 完成了 data数据初始化, el还未初始化
- beforeMount(载入前) vue实例的$el和data都初始化了, 相关的render函数首次被调用
- mounted(载入后) 此过程中进行ajax交互
- beforeUpdate(更新前)
- updated(更新后)
- beforeDestroy(销毁前)
- destroyed(销毁后)
组件data为什么返回函数
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data。如果单纯的写成对象形式,就使得所有组件实例共用了一份data,造成了数据污染。
vue给对象新增属性页面没有响应
由于Vue会在初始化实例时对属性执行getter/setter转化,所以属性必须在data对象上存在才能让Vue将它转换为响应式的。Vue提供了$set方法用来触发视图更新。
export default { data(){ return { obj: { name: 'fei' } } }, mounted(){ this.$set(this.obj, 'sex', 'man') } } 复制代码
v-if和v-show区别
v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。
所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。
v-model双向绑定原理
v-model本质上是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件。
- text 和 textarea 元素使用 value 属性和 input 事件
- checkbox 和 radio 使用 checked 属性和 change 事件
- select 字段将 value 作为 prop 并将 change 作为事件
所以我们可以v-model进行如下改写:
<input v-model="sth" /> // 等同于 <input :value="sth" @input="sth = $event.target.value" /> 复制代码
这个语法糖必须是固定的,也就是说属性必须为value,方法名必须为:input。
知道了v-model的原理,我们可以在自定义组件上实现v-model。
//Parent <template> {{num}} <Child v-model="num"> </template> export default { data(){ return { num: 0 } } } //Child <template> <div @click="add">Add</div> </template> export default { props: ['value'], methods:{ add(){ this.$emit('input', this.value + 1) } } } 复制代码
key的作用
- 让vue精准的追踪到每一个元素,高效的更新虚拟DOM。
- 触发过渡
<transition> <span :key="text">{{ text }}</span> </transition> 复制代码
当text改变时,这个元素的key属性就发生了改变,在渲染更新时,Vue会认为这里新产生了一个元素,而老的元素由于key不存在了,所以会被删除,从而触发了过渡。
scoped属性作用
在Vue文件中的style标签上有一个特殊的属性,scoped。当一个style标签拥有scoped属性时候,它的css样式只能用于当前的Vue组件,可以使组件的样式不相互污染。如果一个项目的所有style标签都加上了scoped属性,相当于实现了样式的模块化。
scoped属性的实现原理是给每一个dom元素添加了一个独一无二的动态属性,给css选择器额外添加一个对应的属性选择器,来选择组件中的dom。
<template> <div class="box">dom</div> </template> <style lang="scss" scoped> .box{ background:red; } </style> 复制代码
vue将代码转译成如下:
.box[data-v-11c6864c]{ background:red; } <template> <div class="box" data-v-11c6864c>dom</div> </template> 复制代码
scoped样式穿透
scoped虽然避免了组件间样式污染,但是很多时候我们需要修改组件中的某个样式,但是又不想去除scoped属性。
- 使用/deep/
//Parent <template> <div class="wrap"> <Child /> </div> </template> <style lang="scss" scoped> .wrap /deep/ .box{ background: red; } </style> //Child <template> <div class="box"></div> </template> 复制代码
- 使用两个style标签
//Parent <template> <div class="wrap"> <Child /> </div> </template> <style lang="scss" scoped> //其他样式 </style> <style lang="scss"> .wrap .box{ background: red; } </style> //Child <template> <div class="box"></div> </template> 复制代码
ref的作用
- 获取dom元素this.$refs.box
- 获取子组件中的datathis.$refs.box.msg
- 调用子组件中的方法this.$refs.box.open()
computed和watch区别
1.当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性computed。
<template>{{fullName}}</template> export default { data(){ return { firstName: 'xie', lastName: 'yu fei', } }, computed:{ fullName: function(){ return this.firstName + ' ' + this.lastName } } } 复制代码
2.watch用于观察和监听页面上的vue实例,如果要在数据变化的同时进行异步操作或者是比较大的开销,那么watch为最佳选择。
<template>{{fullName}}</template> export default { data(){ return { firstName: 'xie', lastName: 'xiao fei', firstName: 'xie xiao fei' } }, watch:{ firstName(val) { this.fullName = val + ' ' + this.lastName }, lastName(val) { this.fullName = this.firstName + ' ' + val } } } 复制代码
vue路由有几种模式
- hash模式
- history模式
组件之间的传值通信
- 父组件给子组件传值通过props
- 子组件给父组件传值通过$emit触发回调
- 兄弟组件通信,通过实例一个vue实例eventBus作为媒介,要相互通信的兄弟组件之中,都引入eventBus
//main.js import Vue from 'vue' export const eventBus = new Vue() //brother1.vue import eventBus from '@/main.js' export default{ methods: { toBus () { eventBus.$emit('greet', 'hi brother') } } } //brother2 import eventBus from '@/main.js' export default{ mounted(){ eventBus.$on('greet', (msg)=>{ this.msg = msg }) } } 复制代码
axios拦截器怎么配
// 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); 复制代码
链接:https://juejin.im/post/5df1e312f265da33d039d06d
猜你喜欢
- 2024-10-10 「面试题」和Vue.js有关的41个基础问题
- 2024-10-10 Vue面试题 vue面试题2024
- 2024-10-10 Web前端工程师面试之Vue问题汇总解析
- 2024-10-10 2023年最新Vue.js面试题集合 js vue面试题
- 2024-10-10 前端常见面试题 vue篇1 前端面试题2021及答案vue
- 2024-10-10 一些Vue相关的面试题,帮助求职者提升竞争力
- 2024-10-10 Web前端有哪些求职技巧 常见vue面试题怎么答疑
- 2024-10-10 很全面的vue面试题总结 vue面试问题大全及答案大全
- 2024-10-10 Vue 前端面试题 vue前端面试题 社招
- 2024-10-10 Vue3常见面试题:#前端分享# 1 vue面试题及答案前端笔试题
你 发表评论:
欢迎- 07-07使用AI开发招聘网站(100天AI编程实验)
- 07-07Tailwindcss 入门(tailwindcss中文文档)
- 07-07CSS 单位指南(css计量单位)
- 07-07CSS 定位详解(css定位属性的运用)
- 07-07程序员可以作为终身职业吗?什么情况下程序员会开始考虑转行?
- 07-07云和学员有话说:国企转行前端开发,斩获13K高薪!
- 07-0791年转行前端开发,是不是不该转,有啥风险?
- 07-07计算机图形学:变换矩阵(图形学 矩阵变换)
- 595℃几个Oracle空值处理函数 oracle处理null值的函数
- 587℃Oracle分析函数之Lag和Lead()使用
- 575℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 572℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 568℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 561℃【数据统计分析】详解Oracle分组函数之CUBE
- 548℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 541℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端懒加载 (49)
- 前端获取当前时间 (50)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)