vue 内置指令
v-bind: 响应数据并更新DOM特性
v-on: 用于监听 DOM 事件
v-model: 数据双向绑定
v-show:条件渲染指令
v-if: 条件渲染指令
v-else: 条件渲染指令,必须跟 v-if 成对使用
v-for:循环指令
v-text: 更新元素的 textComtent(文本内容)
v-html:更新元素的 innerHTML
v-pre:不需要表达式,跳过这个元素以及子元素的编译过程
v-clock:不需要表达式,这个指令保持在元素上直到关联实例结束编译
v-once:不需要表达式,只渲染元素或组件一次,随后的渲染,组件/元素以及下面的子元素都当成静态页面不在渲染
vue生命周期的八个阶段
1,beforeCreate:在 new 一个 vue 实例后,data 和 methods 中的数据还没有初始化。不能在这个阶段使用 data 中的数据和 methods 中的方法
2,create:data 和 methods 都已经被初始化好了,如果需要调用 methods 中的方法,或 data 中的数据,最早可以在这个阶段进行调用
3,beforeMount:页面还没有挂载,此时页面还是旧的
4,mounted:vue 实例化已经完成,如果想要通过插件操作页面上的 DOM 节点,最早可以在这个节点中执行, 此时虚拟 DOM 挂载完成
5,beforeUpdate:执行这个钩子时,页面中显示的数据还是旧的,data中的数据是更新后的,页面还没有和最新的数据同步
6,updated:页面显示的数据和data中的数据已经同步,都是最新的
7,beforeDestory:vue 实例从运行阶段进入到销毁阶段,这时所有的 data ,methods ,指令 ,过滤器 都是出于可用状态,还没有被真正销毁
8,dastroyed:这个时候所有的 data , methods ,指令 ,过滤器 都是出于不可用状态,组件已经被销毁了
父子组件生命周期执行顺序
1,加载渲染过程
- 父组件执行到 beforeMount 的时候开始执行子组件的生命周期到 mounted ,然后开始执行父组件的 mounted
2,子组件更新过程
- 父组件 beforeUpdate 先执行,然后执行子组件的 beforeupdate , updated , 最后在执行父组件的 updated
3,父组件更新过程
- 父组件 beforeUpdate ,updated
4,销毁过程
- 父组件 beforeDestroy 先执行,然后执行子组件的 beforeDestroy ,destroyed ,最后在执行父组件的 destroyed
es6常用的属性
1,let 和 count:let 定义变量,count:定义常量;两者都不能进行变量提升
2,模板字符串
3,增强函数:函数传参是,可以给定默认值
4,扩展运算符
5,解构赋值
6,set,map
7,数组,将伪数组转换为数组:
- Array.from(arr,(ele) => {}) ,接收两个参数,一个是伪数组,一个是匿名函数,用来对数组的每一项进行处理
- Array.of() 将传入的参数转换为一个数组
- Array.find(()=>{}) : 返回数组中满足条件的第一个元素的值,若不满足这返回undefined
8,迭代器,生成器
9,promise
10,async await
11,模块化:export import
浅拷贝和深拷贝
1,深拷贝的方式:
- 递归调用
- JSON.stringify + JSON.parse
- lodash
- Object.assgin
- structureClone
es6的导入导出
1,导入
- 默认导入:import 名称 from “模块化的路径名”
- 按需导入:import {导入的数据名称} from “模块化的路径名”
2,导出
- 默认导出:export default{导出的全部数据}
- 按需导出:export {导出的数据}
data中数据为什么放在一个对象中?
组件的data写成一个函数,数据一函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护自己的数据。而单纯的写成对象形式,就是的所有组件实例公用一份data,就会造成一个变了,所有的都会发生改变的结果
vue的异步队列和nextTick的区别
Vue的dom更新是异步的,当数据发生变化,vue并不是里面去更新DOM,而是开启一个队列
nextTick:当dom发生变化,更新后执行的回调
vue绑定事件的时候如何阻止冒泡
@click.stop="事件名"
methods,watch,computed的执行顺序
- computed:在dom加载后马上执行
- methods:需要有一定的触发条件,比如点击事件
- watch:用于观察Vue实例上数据变动,数据发生变动时执行
es5和es6的继承的区别
1,es5是新建子类的实例对象this,再将父类的属性添加到子类上面
- 由于父类的内部属性无法获取,导致无法继承原生的构造函数
2,es6是新建父类的实例对象this,然后再用子类的构造函数修饰this,使得父类的所有行为都可以进行
- es6允许继承原生构造函数定义子类
promise的构造函数是同步还是异步的
promise的构造函数是同步执行的,then是异步执行的
setTimeout,promise,async await的区别
setTimeout是宏任务,promise,async await是微任务,async await是promise的同步写法(语法糖),微任务是在宏任务之前执行的
async await如何把异步的操作变成同步的操作
async函数返回的是一个promise对象,在调用这个函数时,如果函数执行成功,内部会调用promise.solve() 方法返回一个promise对象,如果函数执行出现异常,就会调用reject方法返回一个promise对象。async与await配合使用才能是异步操作同步化,await就是等待的意思,等待摸一个函数执行完后,后面的代码才能开始执行
盒模型有几种
1,标准盒模型
-宽高不包含border,padding
2,怪异盒模型(ie)
- 宽高包含了border,padding
v-model实现原理
在内部为不同的输入元素使用不同的属性并抛出不同的事件
- text 和 textarea 元素使用 value 属性和 input 事件
- CheckBox 和 redio 使用 checked 属性和 change 事件
- select 字段将 value 作为 prop 并将 change 作为事件
实现原理:
- v-bind:绑定响应式数据
- 触发 v-on: input 事件并传递数据
组件间的通信方式
1,props / $emit
父组件向子组件传值(props)
子组件向父组件传值($emit)
2,ref / $refs
实现父子组件通信
3,eventBus事件总线(on)
适用于父子组件、非父子组件等之间的通信
4,依赖注入(provide / inject)------ 了解
父子,祖孙之间通信
【注】:依赖注入所提供的属性时 非响应式的
5,children
使用 $parent 可以访问 父组件 的实例(访问的是上一级父组件的属性和方法)
使用 children 并不能保证顺序,并且访问的数据也不是 响应式 的
6,listeners 跨代通信
$attrs:继承所有父组件属性(除了 props 传递的属性、class、style),一般用在子组件的子元素上
listeners"** 将所有的事件监听器指向这个组件的某个特定的子元素。(相当于子组件继承父组件的事件)
hash路由和history路由的区别
1,原理不同:
hash模式的实现通过 监听 hashChange 事件来实现的
history模式是通过 pushState + popstate 事件来实现的
2,表现不同:
hash 模式会在地址栏中有 # 号,而history 模式没有。history 对浏览器的兼容性有要求(IE>=10)
v-for 中使用 key 的原因
key是给内个 vnode 的唯一id,也是 diff 的一种优化策略,可以根据key,跟准确,更快的找到对应的 vnode 节点
vue 相较于原生 js 的优点
1,数据的自动绑定
2,页面参数传递和页面状态管理
3,模块化开发、无刷新保留场景参数更新
4,代码的可阅读性
5,基于强大的 node.js ,拥有 npm 包管理器,可以很好地管理包的版本
6,各组件样式不冲突
7,视图,数据,结构分离
8,虚拟 DOM
9,拥有各种内置指令
对 MVVM 的理解
由 Model, View,ViewModel 三部分组成,Model 层代表数据模型,也可以在 Model 中定义和修改业务逻辑,View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来,ViewModel 是一个同步 View 和 Model 的对象
在MVVM中,数据和视图是不能直接通信的,视图模型相当于一个观察者,监控双方的动作,并及时通知进行相应的动作。当Model发生变化的时候,viewModel能够监听到这种变化,并及时通知view做出相应的修改,反之,当view发生变化是,viewmodel监听到变化后,通知model进行修改,实现视图与模型的互相解耦
Vue数据双向绑定原理
是采用 数据劫持 结合 发布者-订阅者模式 的方式,通过 object.definePoperty() 来个各个属性添加 setter , getter 并劫持监听,在数据变动时发布消息给订阅者,触发响应的监听回调
Vue性能优化
1,尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
2,v-if和v-for不能连用(vue2中v-for的优先级高,vue3 中v-if的优先级高)
3,如果需要使用 v-for 给每项元素绑定事件时,使用事件代理
4,spa页面采用keep-alive缓存组件
5,在更多情况下,使用v-if代替v-show
js 防抖和节流
1,防抖:有些操作是高频触发的,但其实触发一次就好了。等用户高频事件完了,在进行事件操作
事件触发 ---- 开启一个定时器 ---- 如果再次触发,则清楚上一次的,重写一下 ---- 定时到,触发操作
2,节流:节流就是减少流量,将频繁触发的事件减少,并每隔一段时间实行,控制事件触发的频率
事件触发 ---- 执行操作 ---- 关闭阀门 ---- 阀门关闭,后续触发无效 ---- 一定时间后,阀门打开 ---- 操作课再次进行
设计原理
七大设计原理:
1,工厂模式:封装实例的创建过程,解放new class()
2,单例模式:全局只允许有一个实例,多则出错
3,观察者模式:前端常用的设计模式,工作必备,面试必考 ------- 当一个对象的状态或动作取决于另一个对象的状态或动作时,当更改一个对象是,需要更改未知数量的其他对象,当一个对象应该能够通知其他变化而不知道这些其他对象
4,迭代器模式:遍历数据不仅仅是 for 或 forEach,还要更高级的iterator
5,装饰器模式:decorator现已是js标准语法
6,原型模式:原型和原型链式js的必备知识
7,代理模式
vue数据驱动
vue的核心概念就是数据驱动:视图是由数据驱动生成的,我们对视图的修改不会直接操作Dom,而是通过修改数据进行视图更新。相较于传统的Dom进行开发,大大简化了代码量,只关心数据的修改让代码的逻辑变得非常清楚,DOM变成了数据的映射,所有的逻辑都是对数据的操作
解耦与耦合
1,耦合:对象之间的依赖性。对象之间的耦合度越高,维护成本越高
2,解耦:将耦合度降低
3,低耦合:在任何复杂的场景下都可以即拿即用
4,高耦合:组件使用场景少
组件化开发
将复杂的业务逻辑拆分成多个组件,每个组件依赖的css,js,模板,图片等资源放在一起开发和维护。可以简化代码量,对后期的需求变更和维护也更加友好
如何判断对象是否是空对象
1、将对象转换成字符串,再判断是否等于“{}”
let obj = {} JSON.stringify{obj} = {}
2、for in循环
let result=function(obj){ for(let key in obj){ return false;//若不为空,可遍历,返回false } return true; } console.log(result(obj));//返回true
3、Object.keys()方法,返回对象的属性名组成的一个数组,若长度为0,则为空对象(ES6的写法)
console.log(Object.keys(obj).length==0);//返回true
4、Object.getOwnPropertyNames方法获取对象的属性名,存到数组中,若长度为0,则为空对象
console.log(Object.getOwnPropertyNames(obj).length==0);//返回true