1.vue优点?
答:轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。

2.单页面应用和多页面应用区别及优缺点
答:单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
单页面的优点:
用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。
单页面缺点:
不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多。

3.请说下封装 vue 组件的过程?
答:1. 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。(os:思考1小时,码码10分钟,程序猿的准则。)
  2. 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。
  3. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
  4. 封装完毕了,直接调用即可

4.Vue的路由实现:hash模式 和 history模式

  • hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用 window.location.hash 读取。特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
  • history模式:history采用HTML5的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更

5.再说一下vue2.x中如何监测数组变化

使用了函数劫持的方式,重写了数组的方法,Vue将data中的数组进行了原型链重写,指向了自己定义的数组原型方法。这样当调用数组api时,可以通知依赖更新。如果数组中包含着引用类型,会对数组中的引用类型再次递归遍历进行监控。这样就实现了监测数组变化。

6.Vue 中 key 值的作用?

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM

7.vue-cli 替我们做了哪些工作?

首先需要知道 vue-cli 是什么?它是基于 Vue.js 进行快速开发的完整系统,也可以理解成是很多 npm 包的集合。其次,vue-cli 完成的功能有哪些?

.vue 文件 --> .js 文件
ES6 语法 --> ES5 语法
Sass,Less,Stylus --> CSS
对 jpg,png,font 等静态资源的处理
热更新
定义环境变量,区分 dev 和 production 模式
...

如果开发者需要补充或修改默认设置,需要在 package.json 同级下新建一个 vue.config.js 文件

8.vue路由的钩子函数

由钩子函数分为三种类型如下:
第一种:全局钩子函数。

  router.beforeEach((to, from, next) => {
    console.log('beforeEach')
    //next() //如果要跳转的话,一定要写上next()
    //next(false) //取消了导航
    next() //正常跳转,不写的话,不会跳转
  })
  router.afterEach((to, from) => { // 举例: 通过跳转后改变document.title
    if( to.meta.title ){
      window.document.title = to.meta.title //每个路由下title
    }else{
      window.document.title = '默认的title'
    }
  })

第二种:针对单个路由钩子函数

  beforeEnter(to, from, next){
    console.log('beforeEnter')
    next() //正常跳转,不写的话,不会跳转
  }


第三种:组件级钩子函数

  beforeRouteEnter(to, from, next){ // 这个路由钩子函数比生命周期beforeCreate函数先执行,所以this实例还没有创建出来
    console.log("beforeRouteEnter")
    console.log(this) //这时this还是undefinde,因为这个时候this实例还没有创建出来 
    next((vm) => { //vm,可以这个vm这个参数来获取this实例,接着就可以做修改了
      vm.text = '改变了'
    })
  },
  beforeRouteUpdate(to, from, next){//可以解决二级导航时,页面只渲染一次的问题,也就是导航是否更新了,是否需要更新
    console.log('beforeRouteUpdate')
    next();
  },
  beforeRouteLeave(to, from, next){// 当离开组件时,是否允许离开
    next()
  }

9.NextTick

nextTick可以让我们在下次 DOM 更新循环结束之后执行延迟回调,用于获得更新后的 DOM,

当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值

10.Vue 组件间通信有哪些方式?

Vue 组件间通信六种方式

  1. props/$emit
  2. $emit/$on
  3. vuex
  4. $attrs/$listeners
  5. provide/inject
  6. $parent/$children 与 ref

11.vue组件中的data必须是函数

类比引用数据类型
Object是引用数据类型,如果不用function 返回,每个组件的data 都是内存的同一个地址,一个数据改变了其他也改变了;

javascipt只有函数构成作用域(注意理解作用域,只有函数的{}构成作用域,对象的{}以及 if(){}都不构成作用域),data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响

https://www.jianshu.com/p/839cbef3be41

12.vue生命周期

答:总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

  • 创建前/后: 在beforeCreate阶段,vue实例的挂载元素,el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el还没有。

  • 载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

  • 更新前/后:当data变化时,会触发beforeUpdate和updated方法。

  • 销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

13.Vue实现数据双向绑定的原理

vue.js是采用数据劫持,并结合发布者——订阅者的模式:通过Object.defineProperty()来劫持vue中各个属性的setter、getter,在数据变动的时候,再发布消息给订阅者

https://blog.csdn.net/connie_0217/article/details/79271508

14.那你知道Vue3.x响应式数据原理吗?

(还好我有看,这个难不倒我)

Vue3.x改用Proxy替代Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。

Proxy只会代理对象的第一层,那么Vue3又是怎样处理这个问题的呢?

(很简单啊)

判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。

监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?

我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

15.对keep-alive 的了解?

keep-alive是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
在vue 2.1.0 版本之后,keep-alive新加入了两个属性: include(包含的组件缓存) 与 exclude(排除的组件不缓存,优先级大于include) 。

16.vue.js的两个核心是什么?

数据驱动、组件系统
数据驱动:ViewModel,保证数据和视图的一致性。
组件系统:应用类UI可以看作全部是由组件树构成的。

17.vue常用的修饰符?
答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

18.vue几种常用的指令
答:v-for 、 v-if 、v-bind、v-on、v-show、v-else

19. v-show和v-if指令的共同点和不同点

  • v-show指令是通过修改元素的displayCSS属性让其显示或者隐藏
  • v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

20.为什么避免 v-if  v-for 用在一起

当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。

21.computed和watch的区别

我们可能会有这样的需求,一个数据属性在它所依赖的属性发生变化时,也要发生变化,并返回一个值。这种情况下,我们最好使用计算属性。

watch函数适用于,当数据发生变化时,执行异步操作或较大开销操作的情况。

22.v-show和v-if的区别

v-show 只是在 display: none 和 display: block 之间切换。v-show切换开销很小,更适合于频繁切换的场景。

v-if 属性的初始值为false,足见不会被渲染,为true时页面才会渲染,切换的开销高,不适合经常切换的场景。

23.vue2.0中的$router 和 $route的区别

1.router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。

举例:history对象

$router.push({path:'home'});本质是向history栈中添加一个路由,在我们看来是 切换路由,但本质是在添加一个history记录

方法:

$router.replace({path:'home'});//替换路由,没有历史记录

2.route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等

我们可以从vue devtools中看到每个路由对象的不同

24.MVC,MVVM模式的区别

MVC和MVVM其实区别并不是很大,都是一种设计思想。
MVC
MVC是包括view视图层、controller控制层、model数据层。各部分之间的通信都是单向的。

View 传送指令到 Controller
Controller 完成业务逻辑后,要求 Model 改变状态
Model 将新的数据发送到 View,用户得到反馈
 MVVM
vue是实现了双向数据绑定的mvvm框架,当视图改变更新模型层,当模型层改变更新视图层。在vue中,使用了双向绑定技术,就是View的变化能实时让Model发生变化,而Model的变化也能实时更新到View。  

mvvm主要解决了mvc中大量 dom操作使得页面渲染性能降低,加载速度变慢,影响用户体验。

25.vuex

vuex:是全局状态管理,用于单页面应用组件之间的数据共享.

:是全局状态管理更合适;简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一个组件里进行获取、进行修改,并且你的修改可以得到全局的响应变更。

Vuex原理

上图可以很好的说明Vuex的组成,一个实例化的Vuex.Store由state, mutations和actions三个属性组成:

  • state中保存着共有数据
  • 改变state中的数据有且只有通过mutations中的方法,且mutations中的方法必须是同步的
  • 如果要写异步的方法,需要些在actions中, 并通过commit到mutations中进行state中数据的更改.

更多Vuex信息,请参考Vuex官网 : vuex.vuejs.org

26.如何优化SPA应用的首屏加载速度慢的问题?

  •  把不常改变的库放到 index.html 中,通过 cdn 引入
  • vue 路由的懒加载
  •  vue 组件尽量不要全局引入
  • 使用更轻量级的工具库
  • 开启gzip压缩
  • 首页单独做服务端渲染

27.vue-cli如何新增自定义指令?

1.创建局部指令

var app = new Vue({
    el: '#app',
    data: {    
    },
    // 创建指令(可以多个)
    directives: {
        // 指令名称
        dir1: {
            inserted(el) {
                // 指令中第一个参数是当前使用指令的DOM
                console.log(el);
                console.log(arguments);
                // 对DOM进行操作
                el.style.width = '200px';
                el.style.height = '200px';
                el.style.background = '#000';
            }
        }
    }
})

2.全局指令

Vue.directive('dir2', {
    inserted(el) {
        console.log(el);
    }
})

3.指令的使用

<div id="app">
    <div v-dir1></div>
    <div v-dir2></div>
</div>

28.vue如何自定义一个过滤器?


29.vue 路由跳转四种方式 (带参数)

1.  router-link

2.  this.$router.push() (函数里面调用)

3.  this.$router.replace() (用法同上,push)

4.  this.$router.go(n) ()

this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数

30.组件中写 name 选项有什么作用?

  1. 项目使用 keep-alive 时,可搭配组件 name 进行缓存过滤
  2. DOM 做递归组件时需要调用自身 name
  3. vue-devtools 调试工具里显示的组见名称是由vue中组件name决定的

31.什么时候用到嵌套路由?
何为嵌套路由,顾名思义就是路由嵌套子路由; 
当我们的菜单不止一级的时候,就需要使用嵌套路由了
因此我们需要在 VueRouter 的参数中使用 children 配置,这样就可以很好的实现路由嵌套。

32.在Vue中使用插件的步骤

  • 采用ES6import ... from ...语法或CommonJSrequire()方法引入插件
  • 使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

33.active-class是哪个组件的属性?

vue-router模块的router-link组件。

34.Vue事件绑定原理说一下

原生事件绑定是通过addEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的。

35.SSR了解吗?

SSR也就是服务端渲染,也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端

SSR有着更好的SEO、并且首屏加载速度更快等优点。不过它也有一些缺点,比如我们的开发条件会受到限制,服务器端渲染只支持beforeCreatecreated两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。还有就是服务器会有更大的负载需求。

35.1axios的特点有哪些
答:从浏览器中创建XMLHttpRequests;
node.js创建http请求;
支持Promise API;
拦截请求和响应;
转换请求数据和响应数据;
取消请求;
自动换成json。
axios中的发送字段的参数是data跟params两个,两者的区别在于params是跟请求地址一起发送的,data的作为一个请求体进行发送
params一般适用于get请求,data一般适用于post put 请求。

36.vue-loader是什么?使用它的用途有哪些?
答:vue文件的一个加载器,将template/js/style转换成js模块。
用途:js可以写es6、style样式可以scss或less、template可以加jade等

37.v-modal的使用。
答:v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:
v-bind绑定一个value属性;
v-on指令给当前元素绑定input事件。
38.v-on可以监听多个方法吗?
答:可以,栗子:<input type="text" v-on="{ input:onInput,focus:onFocus,blur:onBlur, }">。

39.vue slot
答:简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪个地方显示、如何显示,就是slot分发负责的活。

40.assets和static的区别
答:相同点:assets和static两个都是存放静态资源文件。项目中所需要的资源文件图片,字体图标,样式文件等都可以放在这两个文件下,这是相同点 
不相同点:assets中存放的静态资源文件在项目打包时,也就是运行npm run build时会将assets中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在static文件中跟着index.html一同上传至服务器。static中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上传,在打包时会提高一定的效率,但是static中的资源文件由于没有进行压缩等操作,所以文件的体积也就相对于assets中打包后的文件提交较大点。在服务器中就会占据更大的空间。
建议:将项目中template需要的样式文件js文件等都可以放置在assets中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css等文件可以放置在static中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。

40.你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?
答:根据vue-cli脚手架规范,一个js文件,一个CSS文件。
41.Vue里面router-link在电脑上有用,在安卓上没反应怎么解决?
答:Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决。
42.Vue2中注册在router-link上事件无效解决方法
答: 使用@click.native。原因:router-link会阻止click事件,.native指直接监听一个原生事件。
43.RouterLink在IE和Firefox中不起作用(路由不跳转)的问题
答: 方法一:只用a标签,不适用button标签;方法二:使用button标签和Router.navigate方法

46.params和query的区别
答:用法:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。
url地址显示:query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
注意点:query刷新不会丢失query里面的数据
params刷新 会 丢失 params里面的数据。
47.vue初始化页面闪动问题
答:使用vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样,虽然一般情况下这个时间很短暂,但是我们还是有必要让解决这个问题的。
首先:在css里加上[v-cloak] {
display: none;
}。
如果没有彻底解决问题,则在根元素加上style="display: none;" :style="{display: 'block'}"
48.vue更新数组时触发视图更新的方法
答:push();pop();shift();unshift();splice(); sort();reverse()
49.vue修改打包后静态资源路径的修改
答:cli2版本:将 config/index.js 里的 assetsPublicPath 的值改为 './' 。
build: {
...
assetsPublicPath: './',
... 
}
cli3版本:在根目录下新建vue.config.js 文件,然后加上以下内容:(如果已经有此文件就直接修改)
module.exports = {
publicPath: '', // 相对于 HTML 页面(目录相同) }
生命周期函数面试题

50.active-class 是哪个组件的属性?
答:vue-router模块的router-link组件。children数组来定义子路由
51.怎么定义 vue-router 的动态路由? 怎么获取传过来的值?
答:在router目录下的index.js文件中,对path属性加上/:id。 使用router对象的params.id。

52.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
答:如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用。
以上面试题仅供个人学习,如有错误请指正。谢谢。

53.vue 弹窗时 监听手机返回键关闭弹窗功能(页面不跳转)

 更新时间:2019年05月10日 15:32:17   转载 作者:Miss丨Fortunes  

这篇文章主要介绍了vue 弹窗时 监听手机返回键关闭弹窗功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值(页面不跳转) ,需要的朋友可以参考下

[注]:popstate 事件

  a.当活动历史记录条目更改时,将触发popstate事件。

  b.如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对history.replaceState()的调用的影响,popstate事件的state属性包含历史条目的状态对象的副本。

  c.需要注意的是调用history.pushState()history.replaceState()不会触发popstate事件。

  d.只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()

具体代码:

1.弹窗事件中调用

2. mounted 生命周期 监听popstate 事件

3.beforeDestroy 生命周期 移除popstate 事件

Logo

前往低代码交流专区

更多推荐