文章目录
前言一、如何分包加载?分包加载的优势在哪?二、什么是MVC和MVVM?三、什么是Proxy及其作用四、实现垂直居中的几种方法(包含css3新特性flflex布局)五、说说vue是如何监听对象和数组变化的前言
小滴课堂,旨在让编程不在难学,让技术与生活更加有趣。 随着互联网+的时代,在线教育技术越来越便捷,小滴课堂依托在线教育时间以及空间上的便利,为广大IT从业者提供了更为方便、快捷的学习交流途径、提供大量高质量的IT在线课程。更多教程请访问(添加VX:xdclass99)
一、如何分包加载?分包加载的优势在哪?
回答
(一)分包的介绍
分包加载其实就是把小程序划分成不同的子包,然后在用户使用的时候才进行加载,就是我们口中常说的按需加载。每个分包⼀般会有⼀个主包,主包会在小程序启动时首先下载,其他分包则会在进⼊对应页面时下载对应包的资源。
⽬前小程序分包⼤⼩有以下限制:
整个⼩程序所有分包⼤小不超过 8M单个分包/主包⼤小不能超过 2M
(二)分包的使用
通过在app.json中设置subpackages字段声明项目的分包结构,这⾥我们看下官网的例⼦:
{"pages":["pages/index","pages/logs"],"subpackages": [{"root": "packageA","pages": ["pages/cat","pages/dog"]}, {"root": "packageB","name": "pack2","pages": ["pages/apple","pages/banana"]}]}
可以看到这⾥除了主包里的pages页面外,subpackages中也配置了几个包,里面也有对应的页面。subpackages具体配置可以看下下图: 这⾥root根目录指的是指定根目录的文件夹,来看下目录结构就知道了
上⾯指定的root中packageA和packageB就是packageA和packageB的路径
这里使用时需要注意几点,如下:
subpackages配置路径外的目录会被打包到主包(app)中
主包(app)可以有⾃己的pages(即subpackages外的 pages 字段)subpackage 的根目录不能是另外⼀个 subpackages 内的子目录tabBar 页面必须在主包(app)内分包与分包之间不可以引用其js⽂件、template以及资源(如packageA 无法require packageB JS 文件),但可以 require app`、⾃己package 内的 js⽂件、template以及资源
(三)分包的优势
采用分包加载,对开发者而⾔,代码体积可以承载更⼤;而对⽤户而言,可以提高小程序的启动速度,大大提升体验。
二、什么是MVC和MVVM?
回答
(一)MVC和MVVM都是常⻅的软件架构,在软件的设计过程中经常被提到。具体区别,你真的理解了吗?
(二)MVC
视图(View):⽤户看到并与之交互的界⾯,HTML在其中起着重要作⽤,即应⽤程序中显示数据的部分控制器(Controller):应⽤程序中处理⽤户交互的部分,⼀般应⽤程序从视图层读取数据,控制⽤户的输⼊,并向Model发送数据模型(Model):应⽤程序中处理数据的逻辑部分,并存取数据交互模式⼀般有两种。⼀种是通过 View 接受指令,传递给 Controller。⼀种是直接通过controller接受指令。 直接通过controller接受指令图解:
(三)MVVM
组成部分: Model:应用软件中的数据提供部分View: 应用软件中的视图部分,也就是用户看到的界面部分ViewModel:将View中的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开,取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑
MVVM 模式将 Controller 改名为 ViewModel,同时改变了通信方向。
View的变动,自动反映在 ViewModel,反之亦然。 Angular 和 Vue 都采用这种模式。
特点:
低耦合。视图(View)可以独立于Model变化和修改,⼀个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把⼀些视图逻辑放在⼀个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发⼈员可以专注于业务逻辑和数据的开发(ViewModel),设计⼈员可以专注于页⾯设计。
图解:
三、什么是Proxy及其作用
回答
(一)概述:
Proxy可以理解成,在⽬标对象之前架设⼀层 “拦截”,当外界对该对象进⾏操作的时候,都必须经过这层拦截,而Proxy就充当了这种机制,类似于代理的含义,它可以对外界访问对象之前进行过滤和改写该对象。
(二)引⼦:
如果对vue2.xx了解或看过源码的⼈都知道,vue2.xx中使⽤ Object.defifineProperty()⽅法对该对象通过递归+遍历的⽅式来实现对数据的监控的,但这种方式是有缺点的。
缺点如下:
当我们使用数组的方法或改变数组的下标是不能重新触发 Object.defifineProperty中的set()方法的,因此就做不到实时响应了。必须遍历每个对象的每个属性,才能进行监听,如果对象嵌套很深的话,需要使用递归调用。 因此vue3.xx中之后就改用Proxy来更好的解决如上面的问题。
(三)基本语法:
const obj = new Proxy(target, handler);/*** 参数说明如下:** target: 被代理对象。** handler: 是⼀个对象,声明了代理target的⼀些操作。** obj: 是被代理完成之后返回的对象。*/当外界每次对obj进⾏操作时,就会执⾏handler对象上的⼀些⽅法。handler中常⽤的对象⽅法如下:1. get(target, propKey, receiver)2. set(target, propKey, value, receiver)3. has(target, propKey)4. construct(target, args):5. apply(target, object, args)
(四)使用Proxy实现简单的Vue双向绑定
步骤:
需要实现⼀个数据监听器 Observer, 能够对所有数据进行监听,如果有数据变动的话,拿到最新的值并通知订阅者Watcher.需要实现⼀个指令解析器Compile,它能够对每个元素的指令进⾏扫描和解析,根据指令模板替换数据,以及绑定相对应的函数。需要实现⼀个Watcher, 它是链接Observer和Compile的桥梁,它能够订阅并收到每个属性变动的通知,然后会执⾏指令绑定的相对应 的回调函数,从而更新视图。
(五)实现Vue双向绑定的js部分
class Vue {constructor(options) {this.$el = document.querySelector(options.el);this.$methods = options.methods;this._binding = {};this._observer(options.data);this._compile(this.$el);}_pushWatcher(watcher) {if (!this._binding[watcher.key]) {this._binding[watcher.key] = [];}this._binding[watcher.key].push(watcher);}/*observer的作⽤是能够对所有的数据进⾏监听操作,通过使⽤Proxy对象中的set⽅法来监听,如有发⽣变动就会拿到最新值通知订阅者。*/_observer(datas) {const me = this;const handler = {set(target, key, value) {const rets = Reflect.set(target, key, value);me._binding[key].map(item => {item.update();});return rets; }};this.$data = new Proxy(datas, handler);}/*指令解析器,对每个元素节点的指令进⾏扫描和解析,根据指令模板替换数据,以及绑定相对应的更新函数*/_compile(root) {const nodes =Array.prototype.slice.call(root.children);const data = this.$data;nodes.map(node => {if (node.children && node.children.length) {this._compile(node.children);}
const $input = node.tagName.toLocaleUpperCase() ==="INPUT";const $textarea = node.tagName.toLocaleUpperCase()=== "TEXTAREA";const $vmodel = node.hasAttribute('v-model');// 如果是input框 或 textarea 的话,并且带有 v-model 属性的if (($vmodel && $input) || ($vmodel && $textarea)) {const key = node.getAttribute('v-model');this._pushWatcher(new Watcher(node, 'value', data, key));node.addEventListener('input', () => {data[key] = node.value;});}if (node.hasAttribute('v-bind')) {const key = node.getAttribute('v-bind');this._pushWatcher(new Watcher(node, 'innerHTML', data, key));}if (node.hasAttribute('@click')) {const methodName = node.getAttribute('@click');const method =this.$methods[methodName].bind(data);node.addEventListener('click', method);}});}}/*watcher的作⽤是 链接Observer 和 Compile的桥梁,能够订阅并收到每个属性变动的通知,执⾏指令绑定的响应的回调函数,从⽽更新视图。*/class Watcher {constructor(node, attr, data, key) {this.node = node;this.attr = attr;this.data = data;this.key = key; }update() {this.node[this.attr] = this.data[this.key];} }
四、实现垂直居中的几种方法(包含css3新特性flflex布局)
回答
1.position:absolute绝对定位
(一)已知子元素⾼度
.parent {position: relative;width: 300px;height: 300px;background: #000;}.son {position: absolute;top: 50%;left: 50%;width: 100px;height: 100px;margin-top: -50px;margin-left: -50px;background: red;color:#fff;}
效果如下图
(二)未知子元素高度:
.parent {position: relative;width: 300px;height: 300px;background: #000;}.son {position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);background: red;color: #fff;}
效果如下图:
这两种方法均可达到垂直居中的效果,第⼀种是利用绝对定位+margin来设置的,第⼆种是利用决定定位+translate来设置,可以看到第⼆种不需要去计算宽高值的实际⼤小,直接用百分比即可达到效果。
2.利用table-cell
利⽤table-cell将元素变成表格形式,之后⽤vertical-align:middle对⼦元素设置垂直居中
代码如下:
.parent {display: table-cell;vertical-align: middle;text-align: center;width: 300px;height: 300px;background: #000;}.son {background: red;color: #fff;}
效果如下:
3.利用css3的flex布局
这里运用到了css3的flflex布局,align-items将子元素垂直居中,之后justify-content则设置水平居中
代码如下:
.parent {display: flex;align-items: center;justify-content: center;width: 300px;height: 300px;background: #000;}.son {background: red;color: #fff;}
效果如下
五、说说vue是如何监听对象和数组变化的
回答
思路
(一)vue中对象数据的更新问题
新增数据更新问题 描述 通过普通对象添加属性⽅法,Vue不能监测到且不是响应式
this.obj.name= '小滴课堂'
解决 this.$se
this.$set(this.obj,'name','小滴课堂')
注意this.$set不能给vue实例的根数据对象添加属性
(二)数组数据更新问题
描述
直接通过数组索引值改变数组的数据,Vue监测不到改变实际在 js 内存已经把数据的第⼀项数据修改了
解决
Vue在数组的原始操作方法上包裹了重新解析模板的⽅法,也就是说我们在data里面的数组操作方法不是原生的,是vue封装过的哪些数组操作方法经过了封装?
如果觉得《小滴课堂新版互联网大厂前端高频面试题(8)~持续更新中》对你有帮助,请点赞、收藏,并留下你的观点哦!