vue常见面试题

vue常见面试题(生命周期、路由是重点)

Vue 实现数据双向绑定的原理:Object.defineProperty()

vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty将它们转为getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue 的数据双向绑定 将 MVVM 作为数据绑定的入口,整合Observer,Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 的数据变化,通过 Compile 来解析编译模板指令(vue 中是用来解析 {{}}),最终利用 watcher 搭起 observer 和 Compile 之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据 model 变更双向绑定效果

最简单的发布订阅者模式:

// 发布者:收集依赖/收集订阅
class Dep {
  constructor() {
    // 这个 subs 数组,用来存放所有订阅者的信息
    this.subs = [];
  }

  // 向subs数组中,添加订阅者的信息
  addSub (watcher) {
    this.subs.push(watcher);
  }

  // 发布通知的方法
  notify () {
    this.subs.forEach(watcher => watcher.update());
  }
}

// 订阅者的类
class Watcher {
  constructor(cb) {
    this.cb = cb;
  }
  // 触发回调的方法
  update () {
    this.cb();
  }
}


const w1 = new Watcher(() => {
  console.log('我是第1个订阅者');
})

const w2 = new Watcher(() => {
  console.log('我是第2个订阅者');
})

// 收集订阅者的信息
const dep = new Dep();
dep.addSub(w1);
dep.addSub(w2);

dep.notify();
<body>
 <div id="app">
 <input type="text" id="txt">
 <p id="show"></p>
</div>
</body>
<script type="text/javascript">
 var obj = {}
 Object.defineProperty(obj, 'txt', {
	 get: function () {
		return obj
	 },
	 set: function (newValue) {
	 	document.getElementById('txt').value = newValue
	 	document.getElementById('show').innerHTML = newValue
	 }
	 })
	 document.addEventListener('keyup', function (e) {
	 obj.txt = e.target.value
 })
</script>

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

hash 模式:在浏览器中符号“#”,#以及#后面的字符称之为 hash,用 window.location.hash 读取;

特点:hash 虽然在 URL 中,但不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端安全无用,hash 不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端
来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

history 模式:history 采用 HTML5 的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及 popState 事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。

vue-router官网里如此描述:不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个index.html 页面,这个页面就是你 app 依赖的页面

css 只在当前组件起作用

在 style 标签中写入 scoped 即可 例如:<style scoped></style>

v-if 和 v-show 区别

  • v-if 按照条件是否渲染,
  • v-show 是 display 的 block 或 none;

$route 和$router 的区别

  • $route 是路由信息对象,包括 path,params,hash,query,fullPath,matched,name等路
    由信息参数
  • $router 是路由实例对象包括了路由的跳转方法,钩子函数等

vue.js 的两个核心是什么

数据驱动、组件系统

vue 常用的修饰符?

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

v-on 可以绑定多个方法吗

可以

vue 中 key 值的作用?

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

什么是 vue 的计算属性?

在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次
使用的情况下,尽量采取计算属性的方式。
好处
①使得数据处理结构清晰;
②依赖于数据,数据更新,处理结果自动更新;
③计算属性内部 this 指向 vm 实例;
④在 template 调用时,直接写计算属性名即可;
⑤常用的是 getter 方法,获取数据,也可以使用 set 方法改变数据;⑥相较于 methods,不管依赖的数据变不变,methods 都会重新计算,但是依赖数据不变的时候 computed 从缓存中获取,不会重新计算

vue 等单页面应用及其优缺点

优点
Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。

缺点:不支持低版本的浏览器,最低只支持到 IE9;不利于 SEO 的优化(如果要支持 SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退

对 keep-alive 的了解

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

MVC和MVVM

.....................................什么是MVVM?

MVVM 是 Model-View-ViewModel 的缩写。 MVVM 是一种设计思想
	* Model层代表数据模型 (定义数据修改和操作的业务逻辑)
	* View 代表UI组件    (将数据模型转化成 UI 展现出来)
	* ViewModel 是一个同步 View 和 Model的对象
	
在 MVVM 架构下, View 和 Model 之间并没有直接的联系,而是通过 ViewModel进行交互, 
Model 和 View之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,
而 Model 数据的变化也会立即反应到 View 上。

ViewModel 通过双向数据绑定把 View 层和 Model 层连接起来,而 View 和Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM 来统一管理

...............................mvc和mvvm的区别:

mvc 和 mvvm 其实区别并不大。都是一种设计思想。主要就是 mvc 中 Controller 演变成 mvvm 中viewModel。 mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验

父子之间传值和兄弟之间传值

父组件向子组件传值-基本使用:
    1.父组件通过属性方式向子组件传值
    2.子组件通过props接收
    3.通过子组件template,渲染到页面上
    
子组件向父组件传值:
	1.子组件用 $emit() 触发事件
	2.$emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据
	3.父组件用v-on 监听子组件的事件
通过$emit 方式,通过事件触发向上一层触发事件,子组件触发的事件父组件恰好在监听
监听后就可以获取子组件带过来的内容,实现子组件向父组件传值的功能
	
兄弟之间传值:
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件

兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
	1.提供事件中心 var hub = new Vue()
	2.传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
	3.接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
	4.销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据

vue是什么?
vue是一套构建用户界面的渐进式框架,采用自底向上增量开发的设计。 
Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合

如何理解数据的响应式?
    数据发生变化--页面也跟着发生变化;不需要操作DOM
    所有的 DOM 操作都由 Vue 来处理,编写的代码只需要关注逻辑层面即可
    

Vue全局桶

Vue有著名的全家桶系列:
包含了vue-router/vuex/vue-resource/.再加上构建工具vue-cli,less样式
就是一个完整的vue项目的核心构成。

概况起来就是:
    1.项目构建工具
    2.路由
    3.状态管理
    4.http请求工具
    
Vue核心思想:组件化开发和数据驱动

Vue-router

 vue-router的基本使用:
    1.导入 vue 文件:首先 vue.js、然后 vue-router.js 

    2.添加路由连接: <router-link to="/user">User</router-link>
        * router-link是vue中提供的标签,默认会被渲染为a标签
        * to属性默认会被渲染为       href属性
        * to属性的值默认会被渲染为   #开头的hash地址

    3.路由占位符:<router-view></router-view>
        * 将来通过路由规则匹配到的组件,将会被渲染到router-view所在的位置

    4.创建路由组件 const 组件名 = {template:` `}

    5.创建路由实例 且 配置路由规则 routes 
        * routes是路由规则数组
        * 每个路由规则都是一个配置对象,其中至少包含path: 和 component:两个属性
        * path      表示当前路由规则---匹配的hash地址
        * component 表示当前路由规则---对应要展示的组件
        const router =new VueRouter({
            routes:[{
                path: '/user',
                component: 路由名称
            }]
        })
    
    6.挂载路由对象router,到Vue实例对象中

vue的一些用法

......................自定义指令........................................
1...........全局自定义指令

      inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)
      1. 自定义指令的语法规则(获取元素焦点)
      Vue.directive('focus', {
          inserted: function(el) {
            // 获取元素的焦点
            el.focus();
          }
      });

      2. 自定义指令用法
            <input type="text" v-focus> 

2...........带参数的布局自定义指令

        bind:只调用一次,指令第一次绑定到元素时调用。
        Vue.directive('color', {
            bind: function(el, binding) {
                // 根据指令的参数设置背景色
                el.style.backgroundColor = binding.value.color
            }
        });

        指令的用法:  <input type="text" v-color='msg'>   **在data中定义msg**
        
3..........布局自定义指令的用法: 放在vue实例里面,作为vue实例对象的属性或者方法
           局部指令:只能在本组件中使用。
                       
          directives: {
            color: {
                bind: function(el, binding) {
                    el.style.backgroundColor = binding.value.color;
                }
            },
            focus: {
                inserted: function(el) {
                    // 获取元素的焦点
                    el.focus();
                }
            }
        }
......................计算属性.................................
1.为什么需要计算属性?
	表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简洁!
	
2.计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不存在缓存
...................... 侦听器watch:直接用于vue实例对象中.........
侦听器的应用场景:数据变化时执行异步或开销较大的操作 (验证用户名是否可用)
原理:数据一旦发生变化就通知侦听器所绑定的方法

.......................过滤器............................
1.过滤器的作用:格式化数据。如将字符串格式化为首字母大写,将日期格式化为指定的格式
  ...............全局过滤器
  1.自定义过滤器
      Vue.filter('过滤器名称',function(value){
          // return 过滤器处理的结果  (业务逻辑)
      })
  2.过滤器的使用
  	1、插值表达式 <div>{{msg | upper}}</div> 
  	2、属性绑定   <div :abc='msg | upper'>测试数据</div>  
  ................局部过滤器
  	filters: {
        过滤器名称: function(){
        }
    }
..............................................................

1.选用vue的原因

  • Vue的核心思想、优点

  • 从学习成本来说,Vue 更容易上手,更轻量,结合 Vuex 管理状态,视图逻辑和数据的耦合度低,

    项目结构清晰明了,Vue 的可扩展性也非常好

5.谈谈你对组件化的理解

个人理解每个组件就是页面的一个区域,
可以把页面由原来的一个整体,拆分成每个部分;每个部分称为一个组件
好处:合理的拆分组件可以将一个大型的项目,像拼积木一样拼接起来
     一个大型的项目业务逻辑比较复杂;但是经过拆分每个组件变得精小,这样每个组件的维护相对容易
     
组件化开发的好处:
    - 提高开发效率
    - 方便重复使用
    - 提升整个项目的可维护性
    - 便于协同开发
    - 高内聚性 
    - 低耦合度 
    - 组件之间的传值很方便
    
 ...........................................模块化的理解?
 1.模块化简而言之就是一个模块执行一定的功能,当我们在代码中需要这部分功能时不需要重复编写模块代码,
   而是直接 将之前写好的功能模块引入就可以了。
 2.前端模块化就是把复杂的代码分成一个个独立的模块。
 
 *但是这样又会引来模块与模块之间的依赖问题,所以就有了CommonJS,AMD,CMD规范,最后又出现了webpack.
 
 浏览器端不能使用 CommonJS规范;因为 CommonJS 下,模块是同步加载的;
 AMD/CMD可以理解为是commonjs在浏览器端的解决方案,AMD/CMD下,模块都是异步加载的
 
 1.AMD模块化规范代表:RequireJS
    主要特性1:对于依赖的模块,**AMD 是提前执行**
    主要特性2:推崇依赖前置;
 2.CMD模块化规范代表:SeaJS
    主要特性1:对于依赖的模块,**CMD 是延迟执行**
    主要特性2:推崇依赖就近;
3. ES6的模块化(大趋势):es6是在语言标准层面上,实现了模块功能,
	完全可以取代CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案
 ----》
 模块化规范,认为是一种明文的约定,大家都按照相同的约定写代码,减少了不必要的沟通成本,
 极大方便了各个模块之间的调用,方便别人,同时也方便自己。
 
 ........................npm的两层含义?
 1.NPM 是一个 第三方模块的托管网站
 2.NPM 是Node的包管理工具,在我们安装Node时候,就已经顺便也安装了 NPM 这个管理工具

6.vue中computed 和 watch的异同

computed

  • 优先读取缓存
  • computed 计算属性只有在相关的数据发生变化时才会改变要计算的属性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花流雨

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值