CSS3的新特性有哪些?
- 新增 RGBA , HSLA 模式
- 文字阴影(text-shadow)
- 边框: 圆角(border-radius) 边框阴影 : box-shadow
- 盒子模型: box-sizing
- 背景:background-size background-origin background-clip
- 渐变
- 过渡
- 自定义动画
- 媒体查询 多栏布局
- border-image 图片边框
- 2D 转换/3D 转换
- 字体图标
- 弹性布局 flex
请解释CSS盒模型,并说明两种不同类型的盒模型
- 元素选择器(如div、p)
- 类选择器(如.myClass)
- ID选择器(如#myId)
- 属性选择器(如[type="text"])
- 伪类选择器(如:hover)
- 伪元素选择器(如::before)
- 组合选择器(如后代选择器A B、子代选择器A > B等
CSS的盒模型
盒子模型分为两种:
第一种:是 W3C 标准的盒子模型(标准盒模型)
第二种:IE 标准的盒子模型(怪异盒模型)
标准盒模型与怪异盒模型的表现效果的区别之处:
1、标准盒模型中 width 指的是内容区域 content 的宽度
height 指的是内容区域 content 的高度
标准盒模型下盒子的大小 = content + border + padding + margin
2、怪异盒模型中的 width 指的是内容、边框、内边距总的宽度(content + border +
padding);height 指的是内容、边框、内边距总的高度
怪异盒模型下盒子的大小=width(content + border + padding) + margin
常用的伪类选择器
- :hover 伪类选择器:当鼠标悬停在元素上时触发。常用于添加交互效果。
- :active 伪类选择器:当元素被激活(例如,用户点击它)时触发。常用于添加点击效果。
- :focus 伪类选择器:当元素获得焦点(例如,用户点击或通过 Tab 键导航到它)时触发。常用于添加表单元素的样式。
- :first-child 伪类选择器:选择元素的第一个子元素。常用于添加列表项的样式。
- :last-child 伪类选择器:选择元素的最后一个子元素。常用于添加列表项的样式。
- :nth-child() 伪类选择器:选择元素的第 n 个子元素。可以使用表达式来选择不同的子元素。例如,:nth-child(2n) 选择偶数子元素,:nth-child(3n+1) 选择第 1、4、7、10 个子元素。
- :nth-of-type() 伪类选择器:选择同一类型的元素中的第 n 个元素。例如,:nth-of-type(2n) 选择偶数元素。
- :not() 伪类选择器:选择不匹配指定选择器的元素。例如,:not(.class) 选择没有 .class 类的元素。
- :checked 伪类选择器:选择被选中的表单元素(例如,复选框或单选按钮)
js数据类型有哪些
JS数据基础类型有:
String、Number、Boolean、Null、undefined五种基本数据类型,加上新增的两种ES6的类型Symbol、BigInt
JS有三种 复杂类型 (引用数据类型):
Object(对象)、Array(数组)、function(函数)
null和undefined区别
1.undefined 的判断
(1) undefined表示缺少值,即此处应该有值,但是还没有定义
(2) 变量被声明了还没有赋值,就为undefined
(3) 调用函数时应该提供的参数还没有提供,该参数就等于undefined
(4) 对象没有赋值的属性,该属性的值就等于undefined
(5) 函数没有返回值,默认返回undefined
2.null 的判断
(1) null表示一个值被定义了,但是这个值是空值
(2) 作为函数的参数,表示函数的参数不是对象
(3) 作为对象原型链的终点 (Object.getPrototypeOf(Object.prototype))
(4) 定义一个值为null是合理的,但定义为undefined不合理(var name = null)
3.typeof 类型不同
-
typeof null; // 'object'
-
typeof undefined; // 'undefined'
4.Number() 转数字也不同
-
Number(null); // 0
-
Number(undefined); // NaN
箭头函数与普通函数的区别?
(1) 箭头函数比普通函数更加简洁
(2) 箭头函数没有自己的this
箭头函数不会创建自己的this, 所以它没有自己的this, 它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了, 之后不会改变。
(3) 箭头函数继承来的this指向永远不会改变
(4) call()、apply()、bind()等方法不能改变箭头函数中this的指向
(5) 箭头函数不能作为构造函数使用
由于箭头函数时没有自己的this,且this指向外层的执行环境,且不能改变指向,所以不能当做构造函数使用。
(6) 箭头函数没有prototype
原型链
(1) prototype:所有的函数都有原型prototype属性,这个属性指向函数的原型对象。
(2) __proto__,这是每个对象(除null外)都会有的属性,叫做__proto__,这个属性会指向该对象的原型。
(3) constructor: 每个原型都有一个constructor属性,指向该关联的构造函数。
原型链:获取对象时,如果这个对象上本身没有这个属性时,它就会去它的原型__proto__上去找,如果还找不到,就去原型的原型上去找...一直直到找到最顶层(Object.prototype)为止,Object.prototype对象也有__proto__属性,值为null
闭包的理解?
通俗来讲:闭包是在一个函数内部在定一个函数,然后内部函数访问外部函数的一个变量就会形成闭包,闭包的话会形成一个私有空间,然后避免全局变量的一个污染,然后会持久化存储数据到内存中,但是闭包也有弊端,它会导致内存泄漏
内存泄漏怎么解决?
首先避免它的使用,其次的话就是变量执行完以后,可以让它赋值为null,最后利用JS的一个垃圾回收机制进行回收
闭包用处:
读取内部函数的变量;
这些变量的值始终会保持在内存中,不会在外层函数调用后被自动清除
闭包优点:
变量会一直在内存中;
避免全局变量的污染;
私有变量的存在;
闭包缺点:
变量长期储存在内存中,会增大内存的使用量,使用不当会造成内存泄露
JS垃圾回收机制
垃圾回收机制(Garbage Collection)简称GC:是JavaScript中使用的内存管理系统的基本组成部分
JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时会 “自动” 释放、释放的过程成为垃圾回收
内存在不使用的时候会被垃圾回收器自动回收
js列举和数组操作相关的方法(常用)
添加元素
push(): 在数组的末尾添加一个或多个元素,并返回新的长度。
unshift(): 在数组的开头添加一个或多个元素,并返回新的长度。
删除元素
pop(): 删除数组的最后一个元素,并返回那个元素。
shift(): 删除数组的第一个元素,并返回那个元素。
splice(): 通过删除、替换或添加新元素来改变数组的内容。
查找元素
indexOf(): 查找元素在数组中的索引。
lastIndexOf(): 从数组的末尾开始查找元素。
find(): 查找第一个满足测试函数的元素。
findIndex(): 查找第一个满足测试函数的元素的索引。
排序和翻转
sort(): 对数组元素进行排序。
reverse(): 颠倒反转数组中元素的顺序。
遍历和过滤
forEach(): 对数组的每个元素执行一次提供的函数。
map(): 创建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值。
filter(): 创建一个新数组,包含通过所提供函数实现的测试的所有元素。
reduce(): 对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
reduceRight(): 类似reduce(),但是从数组的末尾开始累加。
归并数组
concat(): 合并两个或多个数组。
slice(): 提取原数组的一部分,返回一个新数组。
其它方法
join(): 将数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
toString(): 返回一个表示数组内容的字符串。
split(): 把字符串转换成数组。
toLocaleString(): 返回一个表示数组内容的本地化字符串。
js中不会影响原数组的方法
- concat(),该方法可以连接两个或多个数组,并将新的数组返回。不会对原数组产生影响
- join()
该方法可以将数组转换为一个字符串 - slice()
可以用来从数组提取指定元素 - forEach()
- map()
JS中字符串常用方法
1.charAt()方法
charAt() 方法可返回字符串中指定位置的字符。
2.concat() 方法
concat() 方法用于连接两个或多个字符串。
3.indexOf() 方法
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
如果没有找到匹配的字符串则返回 -1。
4.includes() 方法
includes() 方法用于判断字符串是否包含指定的子字符串。
5.match() 方法
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
6.replace() 方法
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
7.search() 方法
search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回与指定查找的字符串或者正则表达式相匹配的 String 对象起始位置。
8.slice() 方法
slice(start, end) 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。
9.split() 方法
split() 方法用于把一个字符串分割成字符串数组。
10.trim() 方法
trim() 方法用于删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等。
JS中常用对象方法
Object.create()创建对象
该方法用于创建一个新对象,新建对象具有指定原型和若干个指定属性;
Object.assign()合并对象
该方法用于将源对象(sources)的所有可枚举的自有属性(不是通过继承得来的属性)复制到目标对象(target)上;
Object.defineproperties()修改对象多个旧属性或定义对象多个新属性
该方法与上面那个方法使用方式相似,只不过可以对多个属性进行修改或新增;
var、let和const的区别?
变量提升
var 声明的变量存在变量提升,即变量可以在声明前调用,值为 undefined。
let 和 const 不存在变量提升,变量一定要声明之后才能使用,否则会报错。
暂时性死区
var 不存在暂时性死区
let 和 const 存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
块级作用域
var 不存在块级作用域
let 和 const 存在块级作用域
初始值设置
var 和 let 可以不设置初始值
const 声明变量必须设置初始值
重复声明
var 允许重复声明变量
let 和 const 不允许重复声明变量,会抛出 SyntaxError 的错误
数据修改
var 和 let 可以修改数据
const 定义的常量是基本数据类型,不能修改。定义的常量要是引用数据类型,就可以修改。因为保存在栈内存的数据是不可以被修改的。而基本数据类型是直接存储在栈内存中的,所以不能被修改。引用数据类型在栈内存中存储的是一个指针,真正的数据存储在指针指向的堆地址,不可被修改的是指针,真正的数据是可变的。
重新赋值
var 和 let 声明的变量都可以重新赋值
const 声明的变量不能重新赋值
浅拷贝和深拷贝区别概念常见情况?
- 浅拷贝:在栈内存中重新开辟一块内存空间,并将拷贝对象储存在栈内存中的数据存放到其中。
- 深拷贝:基于浅拷贝的过程如果栈内存里面存储的是一个地址,那么其在堆内存空间中的数据也会被重新拷贝一个并由栈空间新创建的地址指向。
常见的 “浅” 拷贝方法:Object.assign(),slice(),concat()方法,ES6拓展运算符
实现 “深” 拷贝常见方法:JSON.parse(JSON.stringify(obj)),递归,第三方插件等
防抖和节流
防抖(debounce):单位时间内,频繁触发事件,只执行最后一次。
比如点击按钮,2秒后调用函数,结果在1.5秒的时候又点了,则会重新计算2秒后在调用函数。
应用场景:搜索框、输入框、手机邮箱验证等
思路:利用定时器,每次触发先清除定时器()
节流(throttle):单位时间内,频繁触发事件,只执行一次
应用场景比较多的是:鼠标经过、页面缩放、滚动条滚动scroll事件、下拉刷新等高频事件
思路:利用定时器,判断是否有定时器,如果有等定时器结束再开启新的定时器
promise
promise是一种避绝回调地域的异步解决方法
promise有三种状态,初始,成功,失败,不论结果哪一种,其他操作改变不了这状态
promise确定有三种,
1.当处于初始状态,无法知道进展到哪一个阶段
2.无法取消promise
3.不设置回调函数,promise内部抛出的错误,不会反映到外部
用法: Promise 对象是一个构造函数,会接受一个函数作为参数,这个函数的两个参数分别是 resolve和reject
resolve 函数的作用是将 Promise 对象的状态从 “未完成” 变为 “成功”
reject 函数的作用是将 Promise 对象的状态从 “未完成” 变为 “失败”
Vue
vue中的data为什么是一个函数?
在vue组件中,data必须是一个函数,如果是一个对象,vue组件可以同时存在多个实例,如果用对象形态的data,那么所有的实例会共享一个data对象,造成数据干扰问题
因此data设置成函数,可以让每个是咧都拥有自己的独立data对象,当组件创建多次,每个实例都会调用该函数会返回一个新的data对象,保证数据隔离性
因此为了避免数据共享和隔离性,已经方便使用组件实例的属性方法。所有data必须是一个函数
另外,data作为函数还有一个特性,就是可以接受参数,这个参数就是组件实例本身,可以定义组件时需要使用组件实例一些属性方法计算初始数据
谈谈MVVM
在mvvm框架下的视图和模型是不能直接通信的,只能通过viewmodel进行交互,他能监听到数据变化,然后通知视图进行更新,用户操作视图时,vm也能监听到视图变化,通知数据做出想对应的改动,从而实现数据双向绑定
优点:可重用性,把视图逻辑放在vm里面,让很多vm重用这段视图逻辑
独立开发性:开发人员可以专注与业务逻辑和数据开发,设计人员可以专注页面设计
mvvm和mvm区别:mvvm通过数据来显示视图而不是节点操作mvvm主要解决mvc大量dom操作,使渲染性能降低,加载慢,用户体验不好等
mvm:单项绑定,model绑定view,用js更新model时候,view会自动更新,缺点是前后端无法独立开发,必须等后端接口做好了才可以往下走; 前端没有自己的数据中心,太过依赖后台
MVVM与MVC最大的区别就是:它实现了View和Model的自动同步, 也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示, 而是改变属性后该属性对应View层显示会自动改变
$nextTick 是什么?为什么优先解决微任务?
nextTick
中的回调是在下次 DOM
更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
。主要思路就是采用微任务优先的方式调用异步方法去执行 nextTick
包装的方法
vuex 是什么?为什么使用?
vuex 是专门为 vue 提供的全局状态管理系统,用于多个组件中数据共享、数据缓存等。(无法持久化、内部核心原理是通过创造一个全局实例 new Vue)
主要包括以下几个模块:
State(斯逮特):定义了应用状态的数据结构,可以在这里设置默认的初始状态。
Getter(盖特er):允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
Mutation(喵特森):是唯一更改 store 中状态的方法,且必须是同步函数。
Action(哎可森):用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
Module(猫渡):允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
v-model 原理
是采用数据劫持结合发布者-订阅者模式的方式,
通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应的监听回调从而达到数据和视图同步。
浏览器的本地存储
-localStorage 浏览器窗口关闭内容不会消失,存储大小一般为5mb,setItem、getItem、remove、clear等api,持久化存储,需要手动清除才会消失,getItem获取不到对应的value会返回null。
-sessionStorage 浏览器窗口关闭,存储的数据会清空,setItem、getItem、remove、clear。
-cookie是一种浏览器管理状态的一个文件,它有name、value,Domain、path等等,数据大小不能超过 4K,是服务器向浏览器发送的一小块数据,不可以跨域请求。设置的cookies过期时间之前一直有效,即使窗口和浏览器关闭,数据会自动地传递到服务器,服务器也可以写cookies到客户端
请说出常用的设计模式?(5 种以上)并举例实际项目中的使用场景。
1.工厂模式 - 传入参数即可创建实例
虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode
2.单例模式 - 整个程序有且仅有一个实例
vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉
3.观察者模式 (响应式数据原理)
4.策略模式 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略
5.策略模式:优化 if else 冗余代码
6.代理模式:mini-vue proxy
vue 父子组件如何通讯
props、$emit:
父组件使用动态数据传递,子组件使用props接收,可以使用数组/对象数据结构,对象结构可以定义类型和默认值。
子组件使用$emit 事件回传
自定义事件进行组件通讯:
自定义事件就是使用一个额外的 js 文件,其中声明一个 Vue 实例即可
$on,$emit,$off,参数分别是:注册函数名,真实函数
$on:绑定自定义事件
$emit:调用自定义事件
$off:在组件销毁时,要及时销毁自定义事件,否则可能会造成内存泄漏。在 beforeDestroy 中调用$off
$refs:获取当前组件实例
$parent&$children:获取当前组件的父组件和子组件
vuex:Vue 中全局状态管理系统,用于多个组件中数据共享。
provide&inject:上层组件提供,下层组件注入使用。(适用于组件库编写)
v-if 和 v-show的区别
v-if是通过添加和删除元素来进行显示或者隐藏
v-show是通过操作DOM修改display样式来修改元素的显示和隐藏
如果需要频繁的进行元素的显示和隐藏使用v-show性能更好
v-show和v-if指令的共同点和不同点
相同点:
v-show和v-if都能控制元素的显示和隐藏。
不同点:
1.实现本质方法不同:v-show本质就是通过设置css中的display设置为none;控制隐藏v-if是动态的向DOM树内添加或者删除DOM元素;
2.v-show都会编译,初始值为false,只是将display设为none,但它也编译了;v-if初始值为false,就不会编译了
总结:v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,如果要频繁切换某节点时,故v-show性能更好一点。
为什么避免v-if和v-for一起使用
vue2.x版本中,当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级;
vue3.x版本中,当 v-if 与 v-for 一起使用时,v-if 具有比 v-for 更高的优先级。
官网明确指出:避免 v-if 和 v-for 一起使用,永远不要在一个元素上同时使用 v-if 和 v-for。
可以先对数据在计算数据中进行过滤,然后再进行遍历渲染;
操作和实现起来都没有什么问题,页面也会正常展示。但是会带来不必要的性能消耗;
父子组件声明周期调用顺序?
挂载阶段
执行顺序为:
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
更新阶段
执行顺序为:
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
销毁阶段
执行顺序为:
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
规律就是:父组件先开始执行,然后等到子组件执行完,父组件收尾。
第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
vue 双向绑定原理(响应式原理)?
采用数据劫持结合观察者模式的方式
通过 Object.defineProperty()来劫持各个属性(只会劫持已经存在的属性)的 setter,getter,dep 和 Watcher 实现依赖收集和派发更新的过程:
vue 将 data 初始化为一个 Observer 并对对象中的每个值,重写了其中的 get、set,data 中的每个 key,都有一个独立的 dep(依赖收集器)。
在 get 中,向 dep(依赖收集器)添加了监听
在 mount 时,实例了一个 Watcher,将收集器的目标指向了当前 Watcher
在 data 值发生变更时,触发 set,触发了 dep(依赖收集器)中的所有监听的更新,来触发 Watcher.update
vue中常见指令
v-model 多用于表单元素实现双向数据绑定
v-bind:简写为冒号:“:”,动态绑定一些元素的属性,类型可以是:字符串、对象或数组。
v-on:click 给标签绑定函数,可以缩写为:“@”,例如绑定一个点击函数 函数必须写在methods里面
v-for 格式: v-for="字段名 in(of) 数组json" 循环数组或json,记得加上key
v-show 显示内容
v-if 指令:取值为true/false,控制元素是否需要被渲染
v-else 指令:和v-if指令搭配使用,没有对应的值。当v-if的值false,v-else才会被渲染出来
v-else-if 必须和v-if连用
v-text 解析文本
v-html 解析html标签 (一般常见的解决后台的富文本内容)
v-bind:class 三种绑定方法
v-once 进入页面时 只渲染一次 不在进行渲染
v-cloak 防止闪烁
v-pre 把标签内部的元素原位输出
父子组件声明周期调用顺序?
加载渲染过程:
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
更新过程:
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
销毁过程:
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
全流程:
beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeDestroy -> destroyed
vue2 和 vue3 的区别?
响应式系统:vue2 是 Object.defineProperty();vue3 使用的是 proxy
vue3 全部由 ts 重构,对 ts 支持更友好
自定义渲染器
composition API
vue3 可以存在多个根节点,vue2 只能有一个
vue 的生命周期 八个阶段
1.beforeCreate
在实例创建之间执行,数据是未加载状态。
创建一个Vue实例,此时实例上只有一些生命周期函数和默认的事件
此时data computed watch methods上的方法和数据均不能访问
2.created
在实例创建、数据加载后,能初始化数据,DOM渲染之前执行。
可以对data数据进行操作,可进行一些请求,请求不易过多,避免白屏时间太长。
3.beforeMount
虚拟DOM已创建完成,在数据渲染前最后一次更改数据。el未挂载。
判断el的挂载方式
判断是否有template设置
将template进行渲染保存到内存当中,还未挂载在页面上
4.mounted
页面、数据渲染完成。el挂载完毕。可以访问DOM节点。
将内存中的模版挂载到页面上
此时可以操作页面上的DOM节点
此时组件从创建阶段进入运行阶段
5.beforeUpdate
重新渲染之前触发。不会造成重渲染。
页面显示的数据是旧的,此时data里面的数据是最新,页面数据和data数据暂未同步6.updated
数据已经更新完成,DOM也重新render完成,更改数据会陷入死循环。
根据data里的最新数据渲染出最新的DOM树,然后将最新的DOM挂载到页面
此时data和页面数据一致,都是最新的
7.beforeDestroy
实例销毁前执行,实例仍然完全可用。
此时组件从运行阶段进入到销毁阶段
组件上的data和methods以及过滤器等都出于可用状态,销毁还未执行
8.Destroyed
实例销毁后执行,这时候只剩下DOM空壳。
组件已经被完全销毁,组件中所有的数据、方法、指令、过滤器等,都已不可用
简述Vue每个周期具体适合哪些场景?
beforeCreate: 在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法
created: data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作
beforeMount: 执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的
mounted: 执行到这个钩子的时候,就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行
beforeUpdate: 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步
updated: 页面显示的数据和data中的数据已经保持同步了,都是最新的
beforeDestory: Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
destroyed: 这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。
什么是MVC?(了解即可)
MVC是应用最广泛的软件架构之一,一般MVC分为:Model(模型),View(视图),Controller(控制器)。 这主要是基于分层的目的,让彼此的职责分开.View一般用过Controller来和Model进行联系。Controller是Model和View的协调者,View和Model不直接联系。基本都是单向联系。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下
vue-router 有哪几种导航钩子?
第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子
第三种:单独路由独享组件