vue整理笔记

什么是vue生命周期?

Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

vue生命周期的作用是什么?

它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑

vue生命周期总共有几个阶段?

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

第一次页面加载会触发哪几个钩子?

会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

DOM 渲染在 哪个周期中就已经完成?

DOM 渲染在 mounted 中就已经完成了。

vue获取数据在哪个周期函数

一般 created/beforeMount/mounted 皆可.
比如如果你要操作 DOM , 那肯定 mounted 时候才能操作.

created和mounted的区别

答:created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。

mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

vue初始化页面闪动问题

答:使用vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{ {message}}的字样,虽然一般情况下这个时间很短暂,但是我们还是有必要让解决这个问题的。

css样式里:
[v-cloak] {
display: none;
}。

如果没有彻底解决问题,则在根元素加上
style="display: none;" :style="{display: 'block'}"

Vue2中注册在router-link上事件无效解决方法

使用@click.native。原因:router-link会阻止click事件,.native指直接监听一个原生事件

RouterLink在IE和Firefox中不起作用(路由不跳转)的问题

  • 只用a标签,不适用button标签;
  • 使用button标签和Router.navigate方法

Vue里面router-link在电脑上有用,在安卓上没反应怎么解决?

Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决。

你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?

根据vue-cli脚手架规范,一个js文件,一个CSS文件。

vue slot

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

如何获取dom?

ref=“domName” 用法:this.$refs.domName

vue-loader是什么?

vue文件的一个加载器,将template/js/style转换成js模块。

用途:js可以写es6、style样式可以scss或less;template可以加jade等;

请说出vue.cli项目中src目录每个文件夹和文件的用法?

assets文件夹是放静态资源;

components是放组件;

router是定义路由相关的配置;

app.vue是一个应用主组件;

main.js是入口文件。

Vue-router跳转和location.href有什么区别

使用location.href=’/url’来跳转,简单方便,但是刷新了页面

使用history.pushState(’/url’),无刷新页面,静态跳转

引进router,然后使用router.push(’/url’)来跳转,使用了diff算法,实现了按需加载减少了dom的消耗

其实使用router跳转和使用history.pushState()没什么差别的,因为vue-router就是用了history.pushState(),尤其是在history模式下。

Vue中双向数据绑定是如何实现的?

数据劫持 结合 发布订阅模式

VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;

说一下vue的生命周期

  • beforeCreate(创建前)
    是new Vue()之后触发的第一个钩子,在当前阶段data,methods,computed以及watch上的数据和方法都不能被访问

  • created(创建后)
    在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发update函数。可以做一些初始数据的获取。在当前阶段无法与DOM进行交互,如果非要想,可以通过vm.$nextTick来访问dom

  • beforeMount(载入前)
    发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟DOM已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated

  • mounted(载入后)
    挂载完成后发生,在当前阶段,真实的DOM挂载完毕,数据完成双向绑定,可以访问到DOM节点,使用$refs属性对DOM进行操作

  • beforeUpdate(更新前)
    发生在更新之前,也就是响应式数据发生更换,虚拟DOM重新渲染之前被触发,可以在当前阶段进行更改数据,不会造成重渲染。

  • updated(更新后)
    发生在更新完成之后,当前阶段组件DOM已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

  • beforeDestroy(销毁前)
    在实例销毁之前调用。实例仍然完全可用。

  • destroyed(销毁后)
    在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

你的接口请求一般放在哪个生命周期中?

接口请求一般放在mounted中,但需要注意的是服务端渲染时不支持mounted,需要放到created

说一下computed和watch?

Computed本质是一个具备缓存的watcher,依赖的属性发生变化就会更新视图。适用于计算比较消耗性能的计算场景。当表达式过于复杂时,在模板中放入过多逻辑会让模板难以维护,可以将复杂的逻辑放入计算属性中处理。(购物车商品结算的时候)

Watch没有缓存,更多的是观察的作用,可以监听某些数据进行回调。当我们需要深度监听对象中的属性时,可以打开deep:true选项,这样便会对对象中的每一项进行监听。这样会带来性能问题,优化的话可以使用字符串形式监听,如果没有写到组件中,不要忘记使用unWatch手动注销。,当一条数据影响多条数据的时候就需要用watch(搜索数据)

v-if和v-show的区别

  • 当条件不成立时,v-if不会渲染DOM元素,v-show操作的是样式(display),切换当前DOM的显示和隐藏
  • 使用频繁切换时用v-show,较少改变时用v-if
  • v-if是动态的向DOM树内添加或者删除DOM元素,消耗性能,而v-show的话,只会编译一次

组件中的data为什么是一个函数?

一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。

说一下v-model的原理

v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:
v-bind绑定一个value属性;
v-on指令给当前元素绑定input事件。

text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。

//  等同于
 //自html5开始,input每次输入都会触发oninput事件,所以输入时input的内容会绑定到sth中,于是sth的值就被改变;
//$event 指代当前触发的事件对象;
//$event.target 指代当前触发的事件对象的dom;
//$event.target.value 就是当前dom的value值;
//在@input方法中,value => sth;
//在:value中,sth => value;

vue的事件绑定原理

原生事件绑定是通过assEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的(可以用event来触发)。

  • [x]
想在组件监听原生事件怎么办呢?可以,在绑定原生事件的时候告诉vue,它是原生事件

  

虚拟DOM的作用

由于在浏览器中操作DOM是很昂贵的。频繁的操作DOM,会产生一定的性能问题。这就是虚拟DOM的产生原因

虚拟DOM本质就是用一个原生的JS对象去描述一个DOM节点。是对真实DOM的一层抽象

虚拟DOM映射到真实DOM要经历VNode的create.diff,patch等阶段

key属性的作用(两方面)

1.渲染列表时

vue整理笔记_第1张图片 我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的: vue整理笔记_第2张图片

2.使用key属性强制替换元素


  {
    {text}}


这里如果text发生改变,整个元素会发生更新,因为当text改变时,这个元素的key属性就发生了改变,在渲染更新时,Vue会认为这里新产生了一个元素,而老的元素由于key不存在了,所以会被删除,从而触发了过渡。

总的来说

  • 当使用列表渲染时,永远添加key属性,可以给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点,这样可以提高列表渲染的效率,提高了页面的性能
  • key属性被用在组件上时,当key改变时会引起新组件的创建和原有组件的删除,此时组件的生命周期钩子就会被触发

3.Vue中,Object.defineProperty方式挂载全局方法优点?

  • defineProperty可以自定义,设置了不可写,防止了误操作,更安全。
  • 如果用vue.prototype方式挂载,会造成全局污染,一个地方改了值,全部调用都被改动了,不安全。

什么是MVVM?

MVVM 是 Model-View-ViewModel 的缩写。

Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。

View 代表UI 组件,它负责将数据模型转化成UI 展现出来。

ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model和 ViewModel 之间的交互是双向的 , 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上

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

简单明了一句话:就是View的变化能实时让Model发生变化,而Model的变化也能实时更新到View。
vue整理笔记_第3张图片

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路由的钩子函数

  • 全局钩子:beforeEach,afterEach

beforeEach主要有3个参数to,from,next:

to:route即将进入的目标路由对象,

from:route当前导航正要离开的路由

next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转

  • 组件内的导航钩子 beforeRouteEnter
    beforeRouteUpdate (2.2 新增)
    beforeRouteLeave
  • 单独路由独享组件(beforeEnter)

r o u t e 和 route和 routerouter的区别

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

怎么定义 vue-router 的动态路由? 怎么获取传过来的值

在 router 目录下的 index.js 文件中,对 path 属性加上 /:id,使用 router 对象的params.id获取。

单页面应用及多页面应用及其优缺点

  • 单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。

  • 多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
    单页面的优点:

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

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

计算属性的含义及优点

模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式

优点:

①使得数据处理结构清晰;

②依赖于数据,数据更新,处理结果自动更新;

③计算属性内部this指向vm实例;

④在template调用时,直接写计算属性名即可;

⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;

⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

keep-alive

一般情况下,组件进行切换的时候,默认会进行销毁,如果有需求,某个组件切换后不进行销毁,而是保存之前的状态,防止重复渲染DOM。那么就可以利用keep-alive来实现

进行到这一步,就是所有的路由组件都被缓存了,严重浪费性能,而且也不符合需求,我们现在只想缓存我想缓存的组件,那么就有以下两种方法

具体有两种方法

  • include: 字符串或正则表达式。只有匹配的组件会被缓存
  • exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
第一种方法:组件
// 组件
export default {
  name: 'test-keep-alive',
  data () {
    return {
        includedComponents: "test-keep-alive"
    }
  }
}


  
  



  
  




  




  



  
  

第二个方面:路由可以利用路由中的meta属性来控制
{
      path: '/',
      name: 'home',
      meta:{
        keepAlive:true
      },
      component: Home
}

keep-alive代码可以结合v-if进行包裹,如果meta中的keepAlive为true进行缓存,否侧不进行缓存,这样可以更灵活一些


      


这样组件的缓存是实现了,但是还是会有一些问题,就是因为组件被缓存,并没有被销毁,所以组件在切换的时候也就不会被重新创建,自然也就不会调用created等生命周期函数,所以此时要使用activated与deactivated来获取当前组件是否处于活动状态

在其中一个组件中组件里面写入了activated与deactivated生命周期函数

activated(){
    console.log("哎呀看见我了")
    console.log("----------activated--------")
  },
  deactivated(){
    console.log("讨厌!!你又走了")
    console.log("----------deactivated--------")
  }

css只在当前组件起作用

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

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

数据驱动、组件系统

数据驱动:ViewModel,保证数据和视图的一致性。

组件系统:应用类UI可以看作全部是由组件树构成的。

assets和static的区别?

相同点
assets和static两个都是存放静态资源文件。项目中所需要的资源文件图片字体图标样式文件等都可以放在这两个文件下

不相同点

  • assets中存放的静态资源文件在项目打包时,也就是运行npm run build时会将assets中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在static文件中跟着index.html一同上传至服务器

  • static中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上传,在打包时会提高一定的效率

  • 但是static中的资源文件由于没有进行压缩等操作,所以文件的体积也就相对于assets中打包后的文件提交较大点。在服务器中就会占据更大的空间。

建议:将项目中template需要的样式文件js文件等都可以放置在assets中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css等文件可以放置在static中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。

vue常用的修饰符?

.prevent: 提交事件不再重载页面;

.stop: 阻止单击事件冒泡;

.self: 当事件发生在该元素本身而不是子元素的时候会触发

.capture: 事件侦听,事件发生的时候会调用

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

可以
例子:

vue中 key 值的作用?

Vue.js 用 v-for 正在更新已渲染过的元素列表时,

它默认用“就地复用”策略。

如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,

而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

key的作用:

      ①Diff算法就可以正确的识别此节点,主要是为了高效的更新虚拟DOM。
      
      ②给渲染出来的每一项数据一个唯一标识

vue-router 是什么?它有哪些组件

vue用来写路由一个插件。router-link、router-view

params和query的区别

  • 用法:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this. r o u t e . q u e r y . n a m e 和 t h i s . route.query.name和this. route.query.namethis.route.params.name。

  • url地址显示:query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示

  • 注意点:query刷新不会丢失query里面的数据
    params刷新 会 丢失 params里面的数据。

query:
//query传参,使用path跳转
this.$router.push({
    path:'second',
    query: {
        queryId:'20180822',
        queryName: 'query'
    }
})

//query传参接收
this.queryName = this.$route.query.queryName;
this.queryId = this.$route.query.queryId;



params:
//params传参 使用name
this.$router.push({
  name:'second',
  params: {
    id:'20180822',
     name: 'query'
  }
})

//params接收参数
this.id = this.$route.params.id ;
this.name = this.$route.params.name ;

mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?

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

区别:vue数据驱动,通过数据来显示视图层而不是节点操作

场景:数据操作比较多的场景,更加便捷

vue的优点是什么?

轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;

简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;

双向数据绑定:保留了angular的特点,在数据操作方面更为简单;

组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;

单页面应用:视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;

虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;

运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。

vue的缺点是什么?

很缺乏高阶教程与文档

VUE不支持IE8

生态环境差不如angular和react

社区不大
如果有问题可以读源码。功能仅限于 view 层,Ajax 等功能需要额外
的库。对开发人员要求较高。开发的话,需要 webpack,不然很难用,最好配合 es6。不过Vue-cli把webpakc也隔离的差不多了

vue如何实现按需加载配合webpack设置

webpack中提供了require.ensure()来实现按需加载。以前引入路由是通过import 这样的方式引入,改为const定义的方式进行引入。

不进行页面按需加载引入方式:import home from ‘…/…/common/home.vue’

进行页面按需加载的引入方式:const home = r => require.ensure( [], () => r (require(’…/…/common/home.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变更双向绑定效果。


    

$nextTick

含义:Vue在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
所以,$nextTick就像是一个延迟机制一样。来保证数据永远最新

理解:你到js已经执行了,但是你dom还没这个盒子。比如你使用document.getElementById去选择一个id,这时候dom节点没这个id呢还,这时候你需要延迟一下。然后才可以获取到。

所以,如果直接获取的话就会报错,此时应该用$nextTick

思路:点击按钮出现input框,并且主动获取焦点

插槽slot

  • 含义:插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码
默认插槽:当父组件中和子组件的插槽中都有值时,则默认使用父组件自己的

子组件中:
vue整理笔记_第4张图片

父组件中:
vue整理笔记_第5张图片

展示的效果:
vue整理笔记_第6张图片

具名插槽(有名字的插槽)

在子组件中
vue整理笔记_第7张图片

在父组件中
vue整理笔记_第8张图片

效果:
vue整理笔记_第9张图片

过滤器

含义格式化变量内容的输出

简单通俗的来说:(日期格式化,字母大小写,数值再计算)

{ {message}}

//讲message传给toUpper方法

{ {message | toUpper}}

// |是管道符 打印结果:HELLO WELCOME TO MY HOME

现在vue的学习进度是:{ {count}} ({ {count | topercentage}})

//0.3(30%) data(){ return{ message:"hello welcome to my home", count:0.3 } } filters:{ //将所有字符全部转为大写 toUpper:function(value){ //value为上面的message return value.toUpperCase() } //将所有数字转为百分号 topercentage:function(value){ return value*100+"%" } }

自定义指令(图片懒加载和获取input光标)

全局指令 与 局部指令 2种
作用:不仅可用于定义任何的DOM操作,并且是可复用的。
钩子函数:
  • bind 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  • inserted被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  • update所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
  • componentUpdated指令所在组件的 VNode 及其子 VNode 全部更新后调用
  • unbind只调用一次,指令与元素解绑时调用
参数
  • el 指令所绑定的元素,可以用来直接操作 DOM

  • binding 一个对象

  • vnodeVue 编译生成的虚拟节点

  • oldVnode上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

vue2.x和vue3.x响应式数据原理的区别

vue2.x

核心函数Object.defineProperty,

核心是给对象的属性做一些配置,只不过里面的set和get实现了响应式

缺陷只能监听一个属性,所以要想监听一个对象,vue2的内部做了一个for in处理

vue3.x

proxy代替了Object.defineProperty,proxy可以监听整个对象。省去for in提升效率,并且可以监听数组,不用再去单独的对数组做特异性操作

你可能感兴趣的:(vue.js,面试)