一:Vue的优缺点
1):优点
1、数据驱动视图,对真实 dom 进行抽象出 virtual dom(本质就是一个 js 对象),并配合 diff 算法、响应式和观察者、异步队列等手段以最小代价更新 dom,渲染页面
2、组件化,组件用单文件的形式进行代码的组织编写,使得我们可以在一个文件里编写 html\css(scoped 属性配置 css 隔离)\js 并且配合 Vue-loader 之后,支持更强大的预处理器等功能
3、强大且丰富的 API 提供一系列的 api 能满足业务开发中各类需求
4、由于采用虚拟 dom,让 Vue ssr 先天就足
5、生命周期钩子函数,选项式的代码组织方式,写熟了还是蛮顺畅的,但仍然有优化空间(Vue3 composition-api)
6、生态好,社区活跃
2):缺点
1、由于底层基于 Object.defineProperty 实现响应式,而这个 api 本身不支持 IE8及以下浏览器
2、csr 的先天不足,首屏性能问题(白屏)
3、由于百度等搜索引擎爬虫无法爬取 js 中的内容,故 spa 先天就对 seo 优化心有余力不足(谷歌的 puppeteer 就挺牛逼的,实现预渲染底层也是用到了这个工具)
二:vue 指令和用法
1):v-model 双向数据绑定:
- 定义:用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作;
- v-for 循环;基于源数据多次渲染元素或模板
- v-if v-show 显示与隐藏;
- v-bind 绑定一个 value 属性;
- v-on 指令给当前元素绑定 input 事件;
- v-on 事件;v-once: 只绑定一次;
2):v-show 和 v-if 指令的共同点和不同点?
共同点:都能控制元素的显示和隐藏;
不同点:实现本质方法不同,v-show 本质就是通过控制 css 中的 display 设置为 none,控制隐藏,只会编译一次;v-if 是动态的向 DOM 树内添加或者删除 DOM 元素,若初始值为false,就会编译了。而且 v-if 不停的销毁和创建比较消耗性能
总结:如果要频繁切换某节点,使用 v-show(切换开销比较小,初始开销较大)。如果不需要频繁切换某节点使用 v-if(初始渲染开销较小,切换开销比较大)
3):keep-alive
- 定义:keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染
4):如何获取 dom?
定义:ref=”domName”
this.$refs.domName
5):vue-loader 是什么?使用它的用途有哪些?
- 定义:vue-loader的一个加载器,将 template/js/style 转换成 js 模块
- 用途:js 可以写 es6、style 样式可以 scss 或 less、template 可以加 jade 等
6):key作用
- 定义:key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点。
- 作用主要是为了高效的更新虚拟 DOM。
7):axios 及安装?
定义:请求后台资源的模块。
npm install axios -save
js 中使用 import 进来,然后. get 或. post。返回在.then 函数中如果成功,失败则是在.catch 函数中。
8):vue.cli 项目中 src 目录每个文件夹和文件的用法
- assets 文件夹是放静态资源;
- components 是放组件;
- router 是定义路由相关的配置;
- app.vue 是一个应用主组件;
- main.js 是入口文件。
9):v-if 和 v-for 的优先级
- 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,所以,不推荐 v-if 和 v-for 同时使用。
- 如果 v-if 和 v-for 一起用的话,vue 中的的会自动提示 v-if 应该放到外层去。
三:vue中的方法
1):computed、watch的使用场景,methods的区别
computed:当一个属性受多个属性影响的时候就需要用到 computed(是自动监听依赖值的变化,简化模板内的复杂运算)
例子:购物车商品结算的时候
watch:当一条数据影响多条数据的时候就需要用watch(为了监听某个响应数据的变化)
例子:搜索数据
methods:是一个方法,它可以接受参数,而computed 不能,computed 是可以缓存的,methods 不会。computed 可以依赖其他 computed,甚至是其他组件的 data
2):vue 中怎么重置 data
定义:使用Object.assign(),vm.$data可以获取当前状态下的data,vm.$options.data(this)可以获取到组件初始化状态下的data
Object.assign(this.$data, this.$options.data(this)) // 注意加this,不然取不到data() { a: this.methodA } 中的this.methodA
3):v-on 监听多个方法?
可以监听
<button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来</button> <button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来</button> <!-- 一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号--> <button @click="onEnter(),onLeave ()">点我onEnter onLeave </button> onEnter () { console.log('mouse enter') }, onLeave () { console.log('mouse leave') }
4):$nextTick 的使用
定义:当你修改了 data 的值然后马上获取这个 dom 元素的值,是不能获取到更新后的值,则需要:$nextTick 这个回调,让修改后的 data 值渲染更新到 dom 元素之后在获取,才能成功
new Vue({ el:' #app', data: { list: [ ] }, mounted: function(){ _this.$nextTick(() => { this.get() }, methods: { get: function () { this.$http. get('/api/article'). then(function (res) { this.list = res.data.data.list // ref list引用了u1元素,我想把第一个li颜色变为红色 this.$refs.list.getElementsByTagName('li' )[0].style.color = 'red' })
5):vue 组件中 data 为什么必须是一个函数
- 定义:因为 JavaScript 的特性所导致,在 component 中,data 必须以函数的形式存在,不可以是对象。组件data 写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的 data,私有的数据空间,不会造成混乱,而写成对象形式,就共有同一个data,改一个就全改了
6):渐进式框架的理解
- 定义:主张最少;可以根据不同的需求选择不同的层级;
7):Vue 中双向数据绑定是如何实现的?
定义:vue 双向数据绑定是通过数据劫持结合发布订阅模式的方式来实现的,也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变。
核心:关于 VUE 双向数据绑定,其核心是Object.defineProperty()方法。劫持各个属性setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
8):理解 Vue 的响应式系统
任何一个 Vue Component 都有一个与之对应的 Watcher 实例,Vue 的 data 上的属性会被添加 getter 和 setter 属性,当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此data 的组件去调用他们的 render 函数进行更新
9):单页面应用和多页面应用区别及优缺点
定义:单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于 pc 端。
定义:多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
- 优点:用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点 spa 对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)
- 缺点:不利于 seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多
10):assets 和 static 的区别
相同点:assets 和 static 两个都是存放静态资源文件。
不同点:assets存入静态资源,打包时会放置到asstes中,而压缩后的静态资源最终也static中跟着index.html上传服务器
11):vue 常用的修饰符
.stop:等同于js的event.stopPropagetion(),防止事件冒泡
.prevent:等同于js的evnet.preventDefault(),防止执行预设的行为(如果事件可取消,则取消事件,而不停止事件的进一步传播)
.capture:与事件冒泡的方向相反,事件捕获由外到内
.self:只会触发自己范围内的事件,不包含子元素
.once:只会触发一次
四:Vue 组件间通信
props/$emit(父传子/子传父)
$emit/$on 监听了自定义事件 data-a和data-b,因为有时不确定何时会触发事件,一般会在 mounted 或created 钩子中来监听
vuex
$attrs/$listeners
provide/inject
$parent/$children 与 ref
1):vue 的两个核心点
数据驱动:ViewModel,保证数据和视图的一致性。
组件系统:应用类UI可以看作是由组件书构成的。
2):vue和jQuery的区别
- jQuery是使用选择器()选取 DOM 对象,对其进行赋值、取值、事件绑定等操作,其实和原生的 HTML 的区别只在于可以更方便的选取和操作 DOM 对象,而数据和界面是在一起的。比如需要获取 label 标签的内容:(“lable”).val(), 它还是依赖 DOM 元素的值。
- Vue则是通过 Vue 对象将数据和 View 完全分离开来了。对数据进行操作不再需要引用相应的DOM 对象,可以说数据和 View 是分离的,他们通过 Vue 对象这个 vm 实现相互的绑定。这就是传说中的 MVVM
3):引进组件的步骤
- 在 template 中引入组件;
- 在 script 的第一行用 import 引入路径;
- 用 component 中写上组件名称
4):delete 和 Vue.delete 删除数组的区别
- delete:只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。
- Vue.delete:直接删除了数组 改变了数组的键值。
5):SPA 首屏加载慢如何解决
- 定义:安装动态懒加载所需插件;使用 CDN 资源
6):Vue-router 跳转和 location.href 有什么区别
使用 location.href=’/url’来跳转,简单方便,但是刷新了页面;
使用 history.pushState(‘/url’),无刷新页面,静态跳转;
引进 router,然后使用 router.push(‘/url’) 来跳转,使用了 diff 算法,实现了按需加载,减少了 dom 的消耗。其实使用 router 跳转和使用 history.pushState() 没什么差别的,因为 vue-router 就是用了history.pushState(),尤其是在 history 模式下
7):route 和 router 的区别是什么
- route:是“路由信息对象”,包括 path, params, hash, query, fullPath, matched, name等路由信息参数。
- router:是“路由实例对象”,包括了路由的跳转方法(push、replace),钩子函数等。
8):Vue slot
- 简单来说,假如父组件需要在子组件内放一些 DOM,那么这些 DOM 是显示、不显示、在哪个地方显示、如何显示,就是 slot 分发负责的活。
9):vue 项目是打包了一个 js 文件,一个 css 文件,还是有多个文件
- 定义:根据vue-cli 脚手架规范,一个js文件,一个css文件。
10):router-link电脑上有用,在安卓上没反应解决
- 定义:Vue 路由在 Android 机上有问题,babel 问题,安装 babel polypill 插件解决。
11):Vue2中注册在router-link上事件无效解决
- 定义:使用@click.navtive。router-link会组织click事件,native指直接监听一个原生事件。
12):RouterLink在IE和Firefox中不起作用(路由不跳转)的问题
- 方法一:只用a标签,不适用button标签;
- 方法二:使用button标签和Router.navigate方法
13):axios的特点有哪些
- 从浏览器中创建XMLHttpRequests;
- node.js 创建http请求;
- 支持Promise API;
- 拦截请求和响应;
- 转换请求数据和响应数据;
- 取消请求;
- 自动换成JSON;
- axios中发送字段的参数是data跟params两个,两者的区别在于params是跟请求地址一起发送,data的作为一个请求进行发送 params一般适用于get请求,data一般使用post请求
14):请说下封装 vue 组件的过程?
- 建立组件的模板,先把架子搭起来,写样式,考虑好组件的基本逻辑。(os:思考 1 小时,码码 10 分钟,程序猿的准则。)
- 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。(父传子)
- 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。(传入的方法等)
- 封装完毕了,直接调用即可
15):params 和 query 的区别
- 用法:query要用path来引入;params要用name来引入。接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。
- url 地址显示:query 更加类似于我们 ajax 中 get 传参,params 则类似于 post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
- 注意点:query刷新不会丢失query里面的数据,params刷新会丢失params里面的数据
16):vue初始化页面闪动问题
使用 vue 开发时,在 vue 初始化之前,由于 div 是不归 vue 管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于 的字样(在css加入以👇)
[v-colok]{ display: none; }
如果没有彻底解决问题,则在根元素加上
style="display: none;" :style="{display:'block'}"
17):vue 更新数组时触发视图更新的方法
- push();pop();shift();unshift();splice(); sort();reverse()
五:vue 首屏加载优化
把不常改变的库放到 index.html 中,通过 cdn 引入
然后找到 build/webpack.base.conf.js 文件,在 module.exports = { } 中添加以下代码
externals{ 'vue':'Vue', 'vue-router':'VueRouter', 'element-ui':'ELEMENT' }
六:vue 常用的 UI 组件库
- Mint UI,element,VUX、iView、Bootstrap-Vue、Ant Design Vue、AT-UI、Vant、cube-ui、Muse-UI
七:Vue的生命周期
beforeCreate、created、beforeMount、mounted、beforeUpdate、update、beforeDestory、destroyed(创建、挂载、更新、卸载)
beforeCreate 组件实例被创建之初,组件的属性生效之前 created 组件实例已经完全创建,属性也绑定,但真实dom还没有生成, $el
还不可用beforeMount 在挂载开始之前被调用;相关的render函数首次被调用 mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子 beforeUpdate 组件数据更新之前调用,发生在虚拟dom打补丁之前 update 组件数据更新之后 activited keep-alive专属,组件被激活时调用 deadactivated keep-alive专属,组件被销毁时调用 beforeDestory 组件销毁前调用 destoryed 组件销毁后调用 - 挂载中可以操作DOM、创建中不能操作DOM;常用挂载或者创建生命周期就行了。
八:虚拟DOM和DIFF算法
- 将DOM抽象为虚拟DOM,然后通过新旧虚拟DOM 这两个对象的产生一(DIFF算法),最终只把变化的的部分,重新渲染,提高渲染效率的过程;
- diff是通过JS层面的计算,返回一个patch对象,即补丁对象,在通过特定的操作解析patch对象,完成页面的重新渲染。
九:vue2和vue3原理
- vue2和vue3双向数据绑定原理发生了变化
- vue2的双向数据绑定是立勇ES5的一个API Object.definePropert()对数据进行劫持 集合 发订阅模式的方式来实现的
- vue3中使用ES6的ProxyAPI对数据代理
- 相对于vue2.x,使用proxy的优势如下
- defineProperty只能监听某个属性,不能对全对象监听
- 可以省去for in、闭包等内容来提高效率(直接绑定整个对象即可)
- 默认进行懒观察(lazy observation)
- 在2.x版本里,不管数据多大,都会在一开始就为起床也观察者,当数据很大时,这可能会在页面载入是造成的性能压力。3.0版本,只会对【被用于渲染初始可见部分的数据】创建观察者,而且3.x的观察者更高效
- vue3更精准的变更通知
- 比例来说:2.x版本中,使用Vue.set来给对象新增一个属性是,这个对象的所有watcher都会运行;3.x版本中,只有依赖那个属性的watcher才会重新运行
- vue3新加入TypeScript以及PWA的支持
十:vue-router的动态路由,获取动态参数
- 可以通过query,param两种方式。query通过url传参,刷新页面还在,params刷新页面不在了
params的类型:
- 配置路由格式:/router/:id
- 传递的方式:在path后面跟上对应的值
- 传递后形成的路径:/router/123
query的类类型
- 配置路由格式:/router,也就是普通配置
- 传递的方式:对象中使用query的key作为传递方式
- 传递后形成的路径:/route?id=123
十一:vue中如何定义一个全局变量
只读的全局变量
import Vue from 'vue '; 1et MyComm = new Vue({ methods: { deleteCookie: function (cname) { 1et d = new Date(); let expires = "expires=" + d.toGMTString(); document. cookie = cname + "=;" + expires; } }) export default MyComm; 1.2) 引用 import MyComm from " . / components/ common/ comm" ; MyComm. . deleteCookie(' ms_ username ')
只读的全局变量
new Vue({ router, data: function(){ return { URL: 'http://localhost:8080', } }, render: h => h(App) }).$mount('#app');
十二:Vue路由两种模式的区别、钩子函数、动态路由
- 两种模式:hash模式;history路由模式
- 钩子函数
- 全局前置守卫 router.beforeEach
- 全局解析守卫 router.beforeResolve
- 全局后置钩子 router.afterEach
- 路由独享的守卫 beforeEnter
- 组件内的守卫 beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
- 动态路由
- 前端把路由写好,登录的时候根据用户的角色权限来动态展示路由,(前端控制路由)
- 后台接口提供当前用户对应权限的路由表,前端通过调接口拿到后处理(后端处理路由)
十三:生命周期钩子的一些使用方法
beforecreate:可以在加个loading事件,在加载实例是触发基于源数据多次渲染元素或模板
created:初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted:挂载元素,获取到dom节点
updated:如果对数据统一处理,在这里写上相应函数
beforeDestroy:可以一个确认停止事件的确认框
nextTick:更新数据后立即操作dom