vue前端框架面试问题汇总

二叶草 2020年3月8日16:20:54前端框架评论阅读模式

1、Vue核心内容有哪些?

轻量级  虚拟DOM树 组件化开发 MVVM 自定义指令 生命周期

和vue相关的有vue-router vuex axios ui框架

2、单页Web应用优缺点

一、定义
单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用。它将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript和 CSS。一旦页面加载完成了,SPA不会因为用户的操作而进行页面的重新加载或跳转。取而代之的是利用 JavaScript 动态的变换HTML的内容,从而实现UI与用户的交互。由于避免了页面的重新加载,SPA 可以提供较为流畅的用户体验。

二、优缺点

单页Web程序的出现是富客户端发展的必然结果,但是该技术也是有些局限性,所以采用之前需要了解清楚它的优缺点。

1、优点:

1).良好的交互体验

用户不需要重新刷新页面,获取数据也是通过Ajax异步获取,页面显示流畅。

2).良好的前后端工作分离模式

单页Web应用可以和RESTful规约一起使用,通过REST API提供接口数据,并使用Ajax异步获取,这样有助于分离客户端和服务器端工作。更进一步,可以在客户端也可以分解为静态页面和页面交互两个部分。

3).减轻服务器压力

服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍;

4).共用一套后端程序代码
不用修改后端程序代码就可以同时用于Web界面、手机、平板等多种客户端;
2、缺点:

1).SEO难度较高

由于所有的内容都在一个页面中动态替换显示,所以在SEO上其有着天然的弱势,所以如果你的站点对SEO很看重,且要用单页应用,那么就做些静态页面给搜索引擎用吧。

2).前进、后退管理

由于单页Web应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理,当然此问题也有解决方案,比如利用URI中的散列+iframe实现。

3).初次加载耗时多

为实现单页Web应用功能及显示效果,需要在加载页面的时候将JavaScript、CSS统一加载,部分页面可以在需要的时候加载。所以必须对JavaScript及CSS代码进行合并压缩处理,如果使用第三方库,建议使用一些大公司的CDN,因此带宽的消耗是必然的

 

2、vue单页面除了用hashchang还能怎么实现?

用ifame

MVVM思想

1、使用MVVM 模式有几大好处:

1. 低耦合。View 可以独立于Model变化和修改,一个ViewModel 可以绑定到不同的View 上,当View 变化的时候Model 可以不变,当Model 变化的时候View 也可以不变。

2. 可重用性。可以把一些视图的逻辑放在ViewModel 里面,让很多View 重用这段视图逻辑。

3. 独立开发。开发人员可以专注与业务逻辑和数据的开发(ViewModel)。设计人员可以专注于界面(View)的设计。

4. 可测试性。可以针对ViewModel 来对界面(View)进行测试

II: 组件化

III 指令系统

IIII: vue2.0开始支持虚拟dom

虚拟dom:可以提升页面的刷新速度

2、mvvm框架是什么?它和其他框架(jQuery)区别是什么?

MVVM是Model-View-ViewModel的缩写。mvvm是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。

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

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

vue是MVVM模式。

MVC和MVVM的区别

mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当 Model 频繁发生变化,开发者需要主动更新到View 。

组件化开发(包含组件的传值)

1、使用props时如果子组件的值发生了改变父组件的值变化吗?

答:不变

2、怎么实现子组件的值发生改变父组件的值也发生改变 用.sync(2.3.0+ 新增)  新版本才有的属性

.sync 修饰符做了什么事,子组件修改了父组件的数据,实际上是:子组件修改数据后,自动让父组件中的数据更新

但是我们说过props是只读的,子组件只能读取props的值,不能修改props的值

其实vue内部也并没有修改props的值,它是单独保存了一份,最后去修改了父组件中对应的值

 

我的理解是他即绑定了给子组件的值 也给子组件传递了一个改变数据的方法

<text-document

:title="doc.title"

@update:title="doc.title =$event"></text-document>

 

<!-- .sync 是上述功能的简化语法

<text-document:title.sync="doc.title"></text-document>-->

3、Props里面的值可以修改吗?答:不可以

props是只读属性,因此不要尝试修改props的值,否则会报错

4、看props定义的是对象还是数组还是都可以?  都可以

props:{seller:{type:Object}}

5、vue 封装一个模态框弹出层?

那就是分装组件 引入到main中这样那个组件都可以使用

6、vue组件之间的传值:

也可以 通过$refs实现组件的传值

父组件向子组件传值:用属性绑定的方式,子组件中添加props属性用来接收父组件传过来的值,父组件的内容改变,子组件的值也会发生变化。

子组件向父组件传值:用方法来传值。先在父组件中定义一个方法,通过事件绑定的方式绑定给子组件,当子组件需要传数据给父组件的时候就可以触发这个事件,事件会调用父组件的方法(this.$emit(事件名称,参数)),在子组件中通过这个方法触发事件。父组件就可以拿到数据了(参数)。

子组件向父组件传智的过程

1 父组件提供一个方法

2 将方法传递给子组件

3 子组件调用fn方法 例如子组件通过this.$emit("fn","撩汉子")

非父子组件的传值(兄弟组件传值): 创建一个globaleventbus(就是一个空的vue实例),在一个组件里面创建一个用来接收数据的函数,在created钩子函数中把这个函数注册给globaleventbus。在另一个组件中触发globaleventbus绑定的事件。(globaleventbus.$emit(事件名称,数据))就可以把数据传给另一个组件了。

vuex传值:vuex可以让多个组件共享state的数据。因为如果多个组件进行传值用上面的方法就会很麻烦,但是把组件之间共享的数据提取出来操作就会变得简单一些。

自定义指令 (包含常见指令)

1、Vue常见指令

指令

解释:指令 (Directives) 是带有 v- 前缀的特殊属性

作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

常用指令v-text   v-html  v-bind   v-text v-if 和 v-show

v-on

作用:绑定事件

语法:v-on:click="say" or v-on:click="say('参数',$event)"

简写:@click="say"

事件修饰符

.stop 阻止冒泡,调用 event.stopPropagation()

.prevent 阻止默认事件,调用 event.preventDefault()

.capture 添加事件侦听器时使用事件捕获模式

.self 只当事件在该元素本身(比如不是子元素)触发时触发回调

.once 事件只触发一次

v-model

v-for

key属性

推荐:使用 v-for 的时候提供 key 属性,以获得性能提升。

说明:使用 key,VUE会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

样式处理 -class和style

说明:这两个都是HTML元素的属性,使用v-bind,只需要通过表达式计算出字符串结果即可

表达式的类型:字符串、数组、对象

语法:

!-- 1 -->

<div v-bind:class="{ active: true }"></div>===>

<div></div>

<!-- 2 -->

<div :class="['active','text-danger']"></div> ===>

<div class="active text-danger"></div>

<!-- 3 -->

<div v-bind:class="[{ active: true }, errorClass]"></div>===>

<div class="active text-danger"></div>

- style ---

<!-- 1 -->

<div v-bind:style="{ color:activeColor, fontSize: fontSize + 'px' }"></div>

<!-- 2 将多个 样式对象 应用到一个元素上-->

<div v-bind:style="[baseStyles,overridingStyles]"></div>

提升性能:v-pre

说明:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

<span v-pre>{{ this will not be compiled}}</span>

提升性能:v-once

说明:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

<span v-once>This will never change: {{msg}}</span>

2、v-model在表单checbox和textarea的含义

v-model 在checkbox这个表单元素元素助中控制选中状态 如果v-model的值为true以上可以看出来v-model对不同的标签操作的内容是不一样的 textarea就是获取具体的内容

3、Vue怎么取消闪烁?

{}}与v-text一样只不+过{{}}在渲染时可能有闪烁的 显示双大括号

所以可以用v-text   v-html v-bind避免{{}}的闪烁效果也可以用v-cloak指令(在style里面也要设置为diaplay:none)

4、Vue怎么组织默认事件?@click.prevent

5、Vue怎么实现使用enter键提交表单? @click.enter

想输入密码后直接提交数据,怎么做?

使用enter按键实现表单提交,直接加enter修饰就可以了,如果想在输入密码之后直接enter提交可以在输入密码的那一列添加@click.enter.native就行了,因为使用的是element-ui框架所以要加native

16、Vue的双向数据绑定原理是什么?

答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

具体步骤:

第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化

第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。

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

6、我们用v-for循环的时候为什么要加:key,你怎么处理的?

在2.0中使用 :key换了一种写法v-for = “(item,index) in data”我们只要把值写成唯一的就可以为index就可以了

另外在vue2.0中使用:key 其实不写数组有重复的也会显示出来,只是写了性能会比较好加上:key可以让虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。所以一句话,key的作用主要是为了高效的更新虚拟DOM

7、自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?

全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数。组件内定义指令:directives

钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新)

钩子函数参数:el、binding

在Vue 中可以把一系列复杂的操作包装为一个指令。

8、Vue中自定义指令有几个钩子函数? 5 个可选的钩子函数。

bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次,指令与元素解绑时调用。

bind和inserted的区别

update和componentUpdated的区别?

bind 只能对自己的元素操作不能对其父节点操作即无法获取el.parentNode

inserted 这个钩子调用的时候也就说可以对其父节点进行操作了即可以获取                       el.parentNode

update 是无法获取元素的内容或者叫值即无法获取innerHTML的值

componentUpdated可以获取元素的内容即可以获取innerHTML的值

9、vue自定义指令vue.dirctive(),以及钩子函数

除了默认设置的核心指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 里面,代码复用的主要形式和抽象是组件——然而,有的情况下,你仍然需要对纯 DOM 元素进行底层操作,这时候就会用到自定义指令。下面这个例子将聚焦一个 input元素,像这样:

当页面加载时,元素将获得焦点 (注意:autofocus 在移动版Safari 上不工作)。事实上,你访问后还没点击任何内容,input就获得了焦点。现在让我们完善这个指令:

// 注册一个全局自定义指令 v-focus

Vue.directive('focus', {

// 当绑定元素插入到 DOM 中。

inserted: function (el) {

// 聚焦元素

el.focus()

}

})

也可以注册局部指令,组件中接受一个 directives 的选项:

directives: {

focus: {

// 指令的定义

inserted: function (el) {

el.focus()

}

}

}

然后你可以在模板中任何元素上使用新的 v-focus 属性:

<inputv-focus>

钩子函数

指令定义函数提供了几个钩子函数 (可选):

bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

inserted:被绑定元素插入父节点时调用 (父节点存在即可调用,不必存在于 document 中)。

update:所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

componentUpdated:所在组件的 VNode 及其孩子的 VNode 全部更新时调用。

unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (包括 el,binding,vnode,oldVnode)

10、vue的过滤器用到了vue数据更新的什么特点?

只要数据改变,页面中所有的指令和表达式都会被重新计算一次

注意:1 一定是页面中的 2 事件除外

上面如果是这样的话其他任何一个有input框输入有变化那么整个的页面指令和表达式都会被重新计算一次,这样是比较消耗性能的

那么怎么解决呢?就是用commputed去监听这个输入框的数据,他发生变化让对应的数据也发生变化就可以了

11、v-show指令,v-if的区别

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

共同点:都是动态显示DOM元素

不同点:v-if是动态的向DOM树内添加或者删除DOM元素;

v-show是通过设置DOM元素的display样式属性控制显隐,只是简单的基于css切换;

v-if适合运营条件不大可能改变;

v-show适合频繁切换。

 

12、指令keep-alive 是做什么的?

在vue-router写着keep-alive,keep-alive的含义: 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个keep-alive指令

<component :is='curremtView' keep-alive></component>

也可以缓存用户输入的内容直接缓存下来或者你以前点击的位置返回的时候也是直接返回你当时点击的地方

keep-ailve设置缓存 就是你在表单写的内容也会被缓存下来,组件也可以缓存下来

keep-ailve也会保留一些状态,以前你点的是第二个菜单,那当你返回的时候就会还是第二个菜单

比如从A到b 不刷新 a到c刷新都会用到keep-alive在加上路由的钩子函数(beforeRouerLive)就行了

13、如何让css只在当前组件中起作用

在每一个vue组件中都可以定义各自的css,js,如果希望组件内写的css只对当前组件起作用,只需要在style中写入scoped,即:

<style scoped></style>
加上scoped为什么就可以实现在当前页面起作用了?因为他给里面标签样式上加上了随机字符串

14、Vue的渐变是怎么做的?

如何在vue中实现一般过渡动画,上面是组件的动画,这里是单个

元素的的动画

1 自定义类样式的方式

可以通过transition标签,将要实现动画效果的元素包裹起来

指定6个类样式

v-enter,v-enter-to,v-leave,v-leave-to,

v-enter-active,v-leave-avtive

如果不给transition标签添加name属性,那么vue会自动查找以v-开头的类样式

如果指定name属性,那么vue会找以name属性的值开头的样式

15、组件间的过渡动画是如何实现的? 例如登录组件和注册组件的过动画

<transition name="comp"mode="out-in">

<component :is="currComp"></component>

</transition>

.comp-enter{

margin-left: -200px;

}

.comp-enter-to,.comp-leave{

margin-left: 0;

}

.comp-leave-to{

margin-left: 200px;

}

.comp-enter-active,.comp-leave-active{

transition: all .3s linear;

}

16、Vue当中使用animate.css实现动画

<transitionenter-active-class="animated lightSpeedIn"

leave-active-class="animated rotateOut">

<div v-if="isShow"></div>

</transition>

只需要引入animate.css  根据官网改变进入的方式lightSpeedIn或者出去的方式rotateOut即可实现动画效果 就是这样简单

 

17、过渡动画的的钩子函数有8个?都是哪8个?一般在实现购物车动画的那个小球会用到

beforeEnter(el){ el.style.marginLeft ="200px";console.log("beforeEnter执行了")},

enter(el){ el.offsetWidth; el.style.marginLeft= "0px";el.style.transition = "all 1s linear"

this.isShow = false;console.log("enter执行了")},

afterEnter(){console.log("afterEnter执行了")},

enterCancelled(){console.log("enterCancelled执行了")},

beforeLeave(){console.log("beforeLeave执行了")},

leave(){console.log("leave执行了")},

afterLeave(){console.log("afterLeave执行了")},

leaveCancelled(){console.log("leaveCancelled执行了")

18、Vue的渐变是怎么做的?

首先在标签定义transition='fade'

然后在css里定义样式

transition:all 0.5

fade-transition:opacity:1

fade-enter,fade-leave:opacity: 0

19、vuejs中过渡动画

在vuejs中,css定义动画:

.zoom-transition{

width:60%;

height:auto;

position: absolute;

left:50%;

top:50%;

transform:translate(-50%,-50%);

-webkit-transition: all .3s ease;

transition: all .3s ease;

}

.zoom-enter, .zoom-leave{

width:150px;

height:auto;

position: absolute;

left:20px;

top:20px;

transform:translate(0,0);

}

其中动画在定的时候要注意上下对应,上面有什么,下面有什么,都要变化的,如果有不变化的,应该抽离出去,作为公共css样式,在上面的css中,如果我只写 transform: translate(-50%,-50%);而不写下面的transform:translate(0,0);则会导致上面的transform: translate(-50%,-50%);被添加到下面,认为这个是不变的

20、vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?

问题1

第一步:在components目录新建你的组件文件(smithButton.vue),script一定要export default {

第二步:在需要用的页面(组件)中导入:importsmithButton from ‘../components/smithButton.vue’

第三步:注入到vue的子组件的components属性上面,components:{smithButton}

第四步:在template视图view中使用,<smith-button></smith-button>
问题有:smithButton命名,使用的时候则smith-button。

问题2

1.在components(专门放组件的文件)下创建一个header.vue文件
2.在App.vue文件里添加如下代码

<my-head></my-head>

import myHead from './components/header'

components : {
myHead,}

由于vue-cli内部配置的原因,@等同于src,因此可以写成

@/components/header

此时header.vue组件就会被成功引入
如果 import myHead from'./components/header'    去掉前面的   ./      就会报错

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

答:assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件作用域插槽怎么获取子组件的数据

22、watch监听基本数据的变化直接监视就可以了

例如watch:{ data:function(){} }或者使用

watch: {

// 监视基本类型的变化:

// msg (curVal, oldVal) {},

msg: {

// 数据变化后,就可以执行这个方法中的代码

handler (curVal) {

console.log('监视到数据变化了', curVal)

},

// 立即监视数据变化

immediate: true

},}

用immediate:ture页面一进来就监听到数据的变化 来触发handler函数

23、watch怎么监听对象的变化?和监听基本数据有什么不一样?

watch:{user:{deep:true,handler:function(){},immediate:false }}

deep:true表示深度监  比基本数据类型多了一个deep参数 数据发生了变化就会触发handler函数

24、如果希望进入页面就立即执行一次监听变化怎么做?

使用该配置immediate:ture就可以,此时页面一加载完就会触发 handler函数

 

怎么页面一加载就监听到数据的变化用的就是immediate

25、使用computed有什么要注意的吗?

计算属性的名称不能和data中的名字冲突

26、计算属性是怎么用的?

计算属性的名称是直接使用的

例如computed:{c:function(){}}  使用的话就是{{c}} 而且计算属性的名称不能和data中的名字冲突 否则报错即data中不可以有c这个名字了

 

27、watch和computer methods的区别是什么?

1.watch和computed都是以Vue的依赖追踪机制为基础的,它们都试图处理这样一件事情:当某一个数据(称它为依赖数据)发生变化的时候,所有依赖这个数据的“相关”数据“自动”发生变化,也就是自动调用相关的函数去实现数据的变动。

watch擅长处理的场景:一个数据影响多个数据

computed擅长处理的场景:一个数据受多个数据的影响

 

而且computer是有缓存的 要没有缓存可以在methods里面定义方法

28、computed除了根据data中的参数进行计算还可以怎么使用

函数直接调用,还可以缓存数据

计算属性computed中其实是有get和set方法的,一直不过我们使用的时候直接调用默认就是使用的额get方法

29、computed和methods的区别?

答:(1)computed调用时不用加上();

(2)computed会对依赖的数据进行缓存,数据变,它才变。于是如果数据不变的情况下多次调用,用computed的缓存比methods执行函数更快;

(3)computed会在页面加载后自动执行。

30、怎么拿到整个vue实例的DOM?就用this.$el

可以通过this.$el获取到$el管理边界的DOM元素 然后也可以再通过children[0]获的它下面的DOM元素

31、Vue中怎么获取DOM元素

即在标签中定义ref=’aa’;然后在js中使用this.$refs.aa这样就获取到了DOM元素

32、Vue中为什么是一次更新DOM,而不是立即更新DOM??

为了提高vue渲染的性能,减少没必要的DOM更新

那怎么获取更新后的DOM里面的值 用$nextTick()

33、Vue怎么获取更新后的数据?因为有些数据是异步渲染的

Vue.nextTick([callback, context] )

34、在vue中给数据动态添加新数据怎么添加?

动态添加数据 添加一个可以使用vm.$set(obj,"name","jack")

动态添加多个可以使用object.assign({},vm.stu,{gender:"femle",height:100})

35、Vuejs在变化检测问题

1.检测数组

由于javascript的限制,vuejs不能检测到下面数组的变化:

1.    直接索引设置元素,如vm.item[0]={};

2.    修改数据的长度,如vm.item.length。

为了解决问题1,Vuejs扩展了观察数组,为它添加一个$set()方法:

// 与 `example1.items[0] = ...` 相同,但是能触发视图更新
example1.items.$set(0, { childMsg: 'Changed!'})

问题2,需要一个空数组替换items。

除了$set(),vuejs也为观察数组添加了$remove()方法,用于从目标数组中查找并删除元素,在内部调用了splice()。因此,不必:

var index = this.items.indexOf(item)
if (index !== -1) {
  this.items.splice(index, 1)
}

只需:

this.items.$remove(item);

2.检测对象

受ES5的显示,Vuejs不能检测到对象属性的添加或删除。因为Vuejs在初始化时候将属性转化为getter/setter,所以属性必须在data对象才能让Vuejs转换它,才能让它是响应的,例如:

var data = { a: 1 }
var vm = new Vue({
  data: data
})
// `vm.a` 和 `data.a` 现在是响应的
vm.b = 2
// `vm.b` 不是响应的
data.b = 2
// `data.b` 不是响应的

不过,有办法在实例创建之后添加属性并且让它是响应的。对于Vue实例,可以使用$set(key,value)实例方法:

vm.$set('b', 2)
// `vm.b` 和 `data.b` 现在是响应的

对于普通数据对象,可以使用全局方法Vue.set(object, key, value):

Vue.set(data, 'c', 3)
// `vm.c` 和 `data.c` 现在是响应的

有时你想向已有对象上添加一些属性,例如使用 Object.assign() 或 _.extend() 添加属性。但是,添加到对象上的新属性不会触发更新。这时可以创建一个新的对象,包含原对象的属性和新的属性:

// 不使用`Object.assign(this.someObject, { a: 1, b: 2 })`

this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

36、vue.use都干了什么?vue.use()的原理,为何可以挂载插件可直接用?

Vue.use的作用其实就是执行一个plugin函数或者执行pluign的install方法进行插件注册,并且向plugin或其install方法传入Vue对象作为第一个参数,use的其他参数作为plugin或install的其他参数。然后我们就可以直接在vue中直接使用这个插件了。

从源码中我们可以发现vue首先判断这个插件是否被注册过,不允许重复注册。

并且接收的plugin参数的限制是Function| Object两种类型。

Vue.use的作用其实就是执行一个plugin函数或者执行pluign的install方法进行插件注册,并且向plugin或其install方法传入Vue对象作为第一个参数,use的其他参数作为plugin或install的其他参数。

 

37、内容分发怎么做?什么是具名插槽

1内容分发 <my-component>

<h1>请输入用户名</h1>

</my-component>-->

Vue.component('my-component',{

template: `

<div>

<header>友情提示:</header>

<div>

<slot></slot>

</div>

<button>关闭</button>

</div>这样最后<h1>请输入用户名</h1>就会占用slot的位置渲染出来

2 具名插槽

<my-component>

<h1 slot="head">注意:</h1>

<p>请输入正确的手机号码{{aa}}</p>

<button slot="foot">取消</button>

</my-component>

</div>

Vue.component('my-component',{

template: `

<div>

<header>

<slotname="head"></slot>

</header>

<div>

<slot></slot>

</div>

<footer>

<slotname="foot"></slot>

</footer>

</div>

`,

})这样的话就会根据是slot的不同算然不同的标签 没有name的渲染没有name的

 

38、同样的的一个组件,希望这个组件里面的内容不一样,怎么处理?

可以使用父子通信或者插槽传递一个或者多个数据

 

39、怎么在vue中实现文本框的一刷新页面就获取焦点

用的是自定义指令

在vue中想使用jquery的插件此时就可以去自定义指令中调用jquery的方法

总之就是要通过操作DOM来实现的效果就要用到自定义指令

40、怎么实现页面之间切换的动画效果或者实现一个动画效果都是用tansition去包裹

<transition:name="transitionName">

<router-view></router-view>

</transition>

watch: {//使用watch 监听$router的变化

$route(to, from) {

//如果to索引大于from索引,判断为前进状态,反之则为后退状态

if(to.meta.index > from.meta.index){

//设置动画名称

this.transitionName = 'slide-left';

}else{

this.transitionName = 'slide-right';

}

}

生命周期

1、请详细说下你对vue生命周期的理解?

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

创建前/后:在beforeCreated阶段,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结构依然存在

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

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

3、请详细说下你对vue生命周期的理解?

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

创建前/后: 在beforeCreated阶段,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结构依然存在

4、vue想第一次一上来就请求数据怎么做?

即在钩子函数的created

5、第一次页面加载会触发vue生命周期的哪几个钩子?

第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

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

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

简单描述每个周期具体适合哪些场景?

生命周期钩子的一些使用方法: beforecreate : 可以在这加个loading事件,在加载实例时触发 created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用 mounted : 挂载元素,获取到DOM节点 updated : 如果对数据统一处理,在这里写上相应函数 beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom

vue-router

1、什么是“前端路由”?什么时候适合使用“前端路由”? “前端路由”有哪些优点和缺点

什么是前端路由

路由是根据不同的url地址展示不同的内容或页面。前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,之前通过服务端根据url的不同返回不同的页面实现的

什么时候使用前端路由

在单页面应用,大部分页面结构不变,只改变部分内容的使用

前端路由有什么优缺点

优点:

用户体验好,不需要每次都从服务器全部获取,快速展现给用户

缺点:

使用浏览器的前进,后退键的时候会重新发送请求,没有合理利用缓存

单页面无法记住之前滚动的位置,无法再前进,后退的时候记住滚动的位置

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

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

3、Router实现原理 vue-route功能如何自己实现?

前端路由

1. hash 模式

hash hashchange

2. history 模式

HTML5 API pushState 和 replaceState     已经 popstate 事件。

 

4、vue中如何去掉url上的"#"号?

exportdefault new Router({

//去掉地址中的哈希#

mode:"history",  还需要后台做一些配合

5、    定义子路由的参数在路由中用哪一个?chlidren

6、active-class是哪个组件的属性?嵌套路由怎么定义?
答:vue-router模块的router-link组件。用children定义

在实际项目中我们会碰到多层嵌套的组件组合而成,但是我们如何实现嵌套路由呢?因此我们需要在 VueRouter 的参数中使用 children 配置,这样就可以很好的实现路由嵌套。
index.html,只有一个路由出口

<div id="app">

<!-- router-view 路由出口, 路由匹配到的组件将渲染在这里 -->

<router-view></router-view>

</div>

main.js,路由的重定向,就会在页面一加载的时候,就会将home组件显示出来,因为重定向指向了home组件,redirect的指向与path的必须一致。children里面是子路由,当然子路由里面还可以继续嵌套子路由。

import Vuefrom 'vue'  import VueRouter from 'vue-router' Vue.use(VueRouter)

 

//引入两个组件

 

import home from "./home.vue" import game from "./game.vue"  //定义路由

constroutes = [

{ path: "/", redirect:"/home" },//重定向,指向了home组件

{

path: "/home",component: home,

children: [

{path: "/home/game",component: game }

]

}

]

//创建路由实例

constrouter = new VueRouter({routes})

 

new Vue({

el: '#app',

data: {

},

methods: {

},

router

})

home.vue,点击显示就会将子路由显示在出来,子路由的出口必须在父路由里面,否则子路由无法显示。

<template>

<div>

<h3>首页</h3>

<router-link to="/home/game">

<button>显示<tton>

</router-link>

<router-view></router-view>

</div>

</template>

game.vue

<template>

<h3>游戏</h3>

</template>

 

7、router-link的用法都有哪些?

<!-- 字符串 -->

<router-link to="home">Home</router-link>

<!-- 渲染结果 -->

<a href="home">Home</a>

 

<!-- 使用 v-bind 的 JS 表达式 -->

<router-link v-bind:to="'home'">Home</router-link>

 

<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->

<router-link :to="'home'">Home</router-link>

 

<!-- 同上 -->

<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->

<router-link :to="{ name: 'user' }}">User</router-link>

这个根据路由中name属性为user的进行跳转

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为/register?plan=private -->

<router-link :to="{ path: 'register', query: { plan: 'private' }}"> </router-link>

这个路径最后面会自动添加上?plan=private

<router-link :to="{ path: 'register', parmars: { plan: 'private' }}"> </router-link>

这个路径最后面会自动添加上/private,而且这个路径对应的路由也必须加上/:plan

结果就是path:”/ register/:plan”

8、在vue当中使用a标签和使用router-link有什么区别?

使用a标签在vue当中是可以跳转路径的但作用也就是跳转一个路径的作用,而router-link可以自动添加上类名,根据这个类名可以实现你想要的当前选中的样式

9、不用router-link跳转路径,怎么跳转到一个路径?

编程式导航利用this.$router.push(”list”)或者

this.$router.push({path:”list”})或者

this.$router.push({name:”list”})或者

this.$router.push({name:”list” ,query:{id:123}})或者

this.$router.push({name:”list”,query:{id:123}})或者

this.$router.push({name:”list”,parmars:{id:123}})最后的这个要注意路由中要加上:id,上面的都不用加

10、怎么定义vue-router的动态路由?怎么获取传过来的动态参数?
答: 在router目录下的index.js文件中,对path属性加上/:id。  使用router对象的params.id

11、vue-router有哪几种导航钩子?三种,它们有哪些参数?
第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子boforeRouterEnter: (to,from,next)=>{},boforeRouterLeave: (to,from,next)=>{}
第三种:单独路由独享组件 beforEnter:(to,from,next)=>{}

参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不用就拦截)最常用就这几种

12、vue-router有哪几种导航钩子?接受哪些参数,分别表示什么意思?

有三种方式可以植入路由导航过程中:

1 全局的2单个路由独享的3组件级的

1. 全局导航钩子:

全局导航钩子主要有两种钩子:前置守卫、后置钩子,

注册一个全局前置守卫:

const router = new VueRouter({ ... });

router.beforeEach((to, from, next) => {

//do someting

});

这三个参数 to 、from 、next 分别的作用:

to: Route,代表要进入的目标,它是一个路由对象

from: Route,代表当前正要离开的路由,同样也是一个路由对象

next: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数

next():进入管道中的下一个钩子,如果全部的钩子执行完了,则导航的状态就是 confirmed(确认的)

next(false):这代表中断掉当前的导航,即 to 代表的路由对象不会进入,被中断,此时该表 URL 地址会被重置到 from 路由对应的地址

next(‘/’) 和 next({path: ‘/’}):在中断掉当前导航的同时,跳转到一个不同的地址

next(error):如果传入参数是一个 Error 实例,那么导航被终止的同时会将错误传递给 router.onError() 注册过的回调

注意:next 方法必须要调用,否则钩子函数无法 resolved

 

对于全局后置钩子:

router.afterEach((to, from) => {

//do someting

});

不同于前置守卫,后置钩子并没有 next 函数,也不会改变导航本身

2. 路由独享的钩子

顾名思义,即单个路由独享的导航钩子,它是在路由配置上直接进行定义的:

 

cont router = new VueRouter({

routes: [

{

path: '/file',

component: File,

beforeEnter: (to, from ,next) => {

// do someting

}

}

]

});

1至于他的参数的使用,和全局前置守卫是一样的

3. 组建内的导航钩子

组件内的导航钩子主要有这三种:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是直接在路由组件内部直接进行定义的

我们看一下他的具体用法:

const File = {

template: `<div>This is file</div>`,

beforeRouteEnter(to, from, next) {

// do someting

// 在渲染该组件的对应路由被 confirm 前调用

},

beforeRouteUpdate(to, from, next) {

// do someting

// 在当前路由改变,但是依然渲染该组件是调用

},

beforeRouteLeave(to,from ,next) {

// do someting

// 导航离开该组件的对应路由时被调用

}

}需要注意是:

 

beforeRouteEnter不能获取组件实例 this,因为当守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例 this

但是并不意味着在 beforeRouteEnter 中无法访问组件实例,我们可以通过给 next 传入一个回调来访问组件实例。在导航被确认是,会执行这个回调,这时就可以访问组件实例了,如:

beforeRouteEnter(to, from, next) {

next(vm => {

//这里通过 vm 来访问组件实例解决了没有 this 的问题

})

}

注意,仅仅是 beforRouteEnter 支持给 next 传递回调,其他两个并不支持。因为归根结底,支持回调是为了解决 this 问题,而其他两个钩子的 this 可以正确访问到组件实例,所有没有必要使用回调

13、路由之间跳转

声明式(标签跳转) <router-link :to="index">

编程式(js跳转) router.push('home') //参数为字符串

router.push({path:'home'}) //参数为对象

router.push({name:'user',params:{userId:123}})//参数为命名的路由

// 带查询参数,变成 /register?plan=private

router.push({path:'register',query:{plan:'private'}

14、导航守卫和axios的拦截器哪个是处理token的? 导航守卫

15、修改默认类名的样式?

在配置路由routes里面有一个参数linkActiveClass可以修改默认的类名,这样点击那个链接就会给当前的这个链接加上这个类名

指定路由的入口:

类名匹配注意的问题

当哈希值为 #/find 的时候,

1 此时to="/" 能够匹配 #/find, 因为 #/find 中包含了 /, 所有匹配了 / (首页菜单)

2 此时to="/find" 能够匹配

所以如果routes里面有./find加样式类名那么./也会加上,有点像模糊匹配 那怎么解决这个问题就是在to="/" 加上exact表示精确匹配就没有问题了

16、在生命周期created中可以通过this.$route.params.id获取动态路由的变化的值,那么手动改变路由再次变化的时候,生命周期钩子函数就获取不到动态路由的值了,那怎么解决这个问题呢?

就是通过watch监听路由

watch:{$route:function(to,from){to.params就可以了}}

17、vue中在js中跳转一个页面用干什么?

this.$router.push("/home")

18、router的query和router 传参什么的有什么区别

1、用法上的

 

刚才已经说了,query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。

注意接收参数的时候,已经是$route而不是$router了哦!!

2、展示上的

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

19、$router和$route的区别?

$route用来获取路由信息比如路由的参数

$router表示路由的对象,一般就是通过js代码跳转路由的对象会用到这个对象

20、Vue-router中,怎么跳转页面?怎么传递参数?路由是否可以拦截,如果可以,拦截的方法是什么?

导航守卫拦截

21、导航守卫(用来判断用户是否登录)

router.beforeEach((to,from,next)=>{

//to表示:要去的路由对象

//from表示:要离开的路由对象

//next表示:执行下一步;    如果不调用这个方法,路由就一直处于等待状态,不会显示路由对应的组件内容

if(to.path ==='/login'){

next();

}else{

//判断用户是否登录;

//此处假设登录成功后,用户被存数到cookie中

if(document.cookie.indexOf('session_id')>0){

//如果cookie里面有一个session_id,则进行下一步操作

next();

}else{

//如果是未登录状态,则进入登录界面

next({ path:'/login' } );

}

}

})

 

22、顺便拓展下登录功能的实现思路:

1.在登录页面输入用户名和密码;

2.点击登录按钮,发动ajax请求,请用户名和密码传递给服务器的登录接口;

3.服务器的登录接口根据用户传过来的用户名和密码,到数据库中查询是否有该用户,

4.如果有该用户,就将用户信息存储到session文件中

5.服务器通过setCookie的响应头告诉浏览器,让浏览器来存储session_id到cookie中

6.每个页面跳转的时候都会经过设置好的导航守卫,进行登录状态的判断

 

token是有时间限制的 一定的时间你不操作token就会失效就会要求你重新登录

判断用户是否登录的怎么去拦截?导航守卫 to fromnext()都是什么意思

router.beforeEach(to,from,next){}

每次路由到写一个路由必然会经过导航守卫

怎么给你每次axios请求都加上一个请求的header就用的是axios的拦截器

只要是使用axios请求必须要经过axios的拦截器

请求拦截 axios.interceptors.request.use(function(config){

config.header.Authorization=localStrage.getItem('token')  return config

})

 

23、添加base url

axios.defaults.baseURL="http://localhost:8080/api"

axios

1、axios是什么?怎么使用?描述使用它实现登录功能的流程?

请求后台资源的模块。npm install axios -S装好,然后发送的是跨域,需在配置文件中config/index.js进行设置。后台如果是Tp5则定义一个资源路由。js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中

2、axios怎么实现数据的请求和拦截?

axios.interceptors.request.use(function(config){

// 在发送请求之前做些什么

给请求头中国添加Authorization请求头

Config.headers.Authorization=localStore.getItem(“token”)

return config;

},function(error){

// 对请求错误做些什么

return Promise.reject(error);

});

 

// 添加响应拦截器

axios.interceptors.response.use(function(response){

// 对响应数据做点什么

return response;

},function(error){

// 对响应错误做点什么

return Promise.reject(error);

});

 

3、axios+tp5进阶中,调用axios.post(‘api/user’)是进行的什么操作?axios.put(‘api/user/8′)呢?

跨域,添加用户操作,更新操作。  Tp5表示的是ThinkPHP5

4、用axios发送post请求数据时,后台往往拿不到数据

 

post提交数据有四种编码方式,表单提交默认是application/x-www-form-urlencoded 编码格式,表单上传文件时,必须使form表单的enctype属性或者ajax的contentType参数等于multipart/form-data。

axios默认提交就是使用这种格式:application/json ,那么传递到后台的将是序列化后的json字符串,而application/x-www-form-urlencoded上传到后台的数据是以key-value形式进行组织的,而application/json则直接是个json字符串。

如果在处理application/json时后台还是采用对付application/x-www-form-urlencoded的方式将会产生问题,

解决方案就有两种,一是后台改变接收参数的方法,

另一种则是将axios post方法的编码格式修改为application/x-www-form-urlencoded。具体情况还是要看情况而定。

5、ajax是怎么实现跨域的?和axios的区别?

vue-proxytable服务器代理跨域

我们在使用vue开发时,如果使用的是vue-cli脚手架webpack开发模板时,我们可以在生成的项目中找到文件夹名为config,这个文件是与webpack配置相关,其中包括使用nodejs生成的服务器,在该文件夹下可以找到index.js文件,这个文件就是webpack的最基本配置,proxytable就在这个文件里面。

6、vue里面是怎么实现ajax请求的,跨域问题是怎么解决的?

axios实现跨域的问题

1.开始进行跨域时,知道vue2.0官方推荐axios进行ajax请求,大致看一下https://www.npmjs.com/package/axios axios的用法,感觉挺好理解嘛,封装的挺好,用时发现,不对啊。跨域设置在哪?最后找到了它

proxyTable:{

'/shopping':{//此处并非一定和url一致。

target:'https://mainsite-restapi.ele.me/shopping',

changeOrigin:true,//允许跨域

pathRewrite:{

'^/shopping': ''

}

}

}

此段代码表示,如果请求地址以/login开头,则自动加上target。

如:/shopping/v2/restaurant/category  等于

https://mainsite-restapi.ele.me/shopping/v2/restaurant/category

设置成功,感觉axios就是方便。走着走着发现。。。不对

2.get请求成功,换成post请求。坑爹啊

:8000/#/login:1XMLHttpRequest cannot loadhttp://cunguan.com/index.php?user&q=action/login. No'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'http://localhost:8000' is therefore not allowed access.

查了半天发现直接访问接口时,要对后端响应头进行设置(最后发现如果用1中的方法进行跨域访问设置则不需要在后端添加响应头)

复制代码

// 指定允许其他域名访问

header("Access-Control-Allow-Origin:*");

// 响应类型

header("Access-Control-Allow-Methods:POST");

// 响应头设置

header("Access-Control-Allow-Headers:x-requested-with,content-type");

添加完毕,好了错没了,可发现数据好像有问题啊。我访问的是自己的接口,因为是以前的老接口,不能改所以只有硬着头皮改前台了

复制代码

3.以前的请求参数为form data怎么这次请求神奇的变为request payload,崩溃中,最后找到要添加Content-Type:application/x-www-form-urlencoded

复制代码

headers: {

'Content-Type':'application/x-www-form-urlencoded'

}

this.$http.post('/login/index.php?user&q=action/login',{'a': 'test', 'b': '123456'}), {

headers: {

'Content-Type':'application/x-www-form-urlencoded'

}

})

.then(function (response) {

console.log(response)

})

.catch(function (error) {

console.log(error)

})

好吧  请求默认的需要修改我认了,改过之后发现。。。我参数呢?这次好了,参数都丢了

4.Content-Type:application/x-www-form-urlencoded时参数格式的问题下面摘自

https://github.com/mzabriskie/axios/blob/master/README.md#using-applicationx-www-form-urlencoded-format.下面三种技能,我用了一种,轻松搞定。

7、axios的特点有哪些?

答:一、Axios是一个基于 promise 的 HTTP 库,支持promise所有的API

二、它可以拦截请求和响应

三、它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据

四、安全性更高,客户端支持防御 XSRF

8、axios有哪些常用方法?

答:一、axios.get(url[,config])   //get请求用于列表和信息查询

二、axios.delete(url[,config])  //删除

三、axios.post(url[,data[, config]])  //post请求用于信息的添加

四、axios.put(url[,data[, config]])  //更新操作

9、说下你了解的axios相关配置属性?

答:`url`是用于请求的服务器URL

`method`是创建请求时使用的方法,默认是get

`baseURL`将自动加在`url`前面,除非`url`是一个绝对URL。它可以通过设置一个`baseURL`便于为axios实例的方法传递相对URL

`transformRequest`允许在向服务器发送前,修改请求数据,只能用在'PUT','POST'和'PATCH'这几个请求方法

`headers`是即将被发送的自定义请求头

headers:{'X-Requested-With':'XMLHttpRequest'},

 

`params`是即将与请求一起发送的URL参数,必须是一个无格式对象(plainobject)或URLSearchParams对象

params:{

ID:12345

},

`auth`表示应该使用HTTP基础验证,并提供凭据

这将设置一个`Authorization`头,覆写掉现有的任意使用`headers`设置的自定义`Authorization`头

auth:{

username:'janedoe',

password:'s00pers3cret'

},

 

vuex

1、Vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex, 一个简单的 global eventbus 就足够您所需了。但是,如果您需要构建是一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择

vuex和localsrage结合使用

 

10、vuex是什么?怎么使用?哪种功能场景使用它?

答:vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,….. export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车

2、你是怎么认识vuex的?

答:vuex可以理解为一种开发模式或框架。比如PHP有thinkphp,java有spring等。
通过状态(数据源)集中管理驱动组件的变化(好比spring的IOC容器对bean进行集中管理)。

应用级的状态集中放在store中;改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。

3、vuex是怎么实现的,介绍一下vuex

vuex就是一个仓库,它的状态(数据)存储是响应式的,当 Vue 组件从 store 中读取状态(数据)的时候,若 store 中的状态(数据)发生变化,那么相应的组件也会相应地得到高效更新。但是我们不能直接改变 store 中的状态(数据),改变 store 中的状态(数据)的唯一途径就是显式地提交 (commit) mutation。

访问store中的数据,可以直接通过:this.$store.state.数据名称 进行获取。

如果要修改store中的数据,需要通过:this.$store.commit(mutation名称,参数)修改数据。

4、vuex有哪几种属性?

有五种,分别是 State、 Getter、Mutation 、Action、 Module

5、这5个属性分别是做什么的?什么意思?

State 主要用来存储数据

Mutation 用来操作state中的数据

Getter  是state的计算属性

Action 也是操作state中的数据但是是异步的他的方法也写到mutation中

Module模块可以定义多个模块

vuex映射到组件中在compute中写 mapstate mapGetter

vuex映射到组件中在methods中写 mapMutation

mapAction

6、vuex的State特性

A、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data

B、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新

C、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中

7、vuex的Getter特性

A、getters可以对State进行计算操作,它就是Store的计算属性

B、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用

C、 如果一个状态只在一个组件内使用,是可以不用getters

vuex的Mutation特性

Action 类似于mutation,不同在于:Action 提交的是mutation,而不是直接变更状态;Action 可以包含任意异步操作。

 

怎么修改vuex中的state的数据呢?只能用mutations

怎么触发mutations中的方法用的就是commit

const store= new Vuex.Store({

state:{count:1},

mutations:{

下面参数state就是上面添加的state属性

应该从 参数state中获取到状态,然后修改

addCount (state){ state.count+=1},

addCount3 (state,num){state.count+=num}

state还是那个state,num是传递进来的参数

}

})

修改state,需要通过一下代码形式调用addCount

store.commit("addCount")

传递参数的做法

store.commit("addCount3",3)

用store.commit("addCount3",3)传递参数是没有问题的但是更推荐对象的行事传递参数即store.commit("addCount3",{num:3})

当然上面的方法也相应的改成

addCount3(state,num){state.count+=num.num}

8、vuex 的 mutation 特性是什么

action 类似于muation, 不同在于:action 提交的是mutation,而不是直接变更状态

action 可以包含任意异步操作

9、mutation和action区别

其实两者区别不大,即使异步的其实写在mutation中也可以实现,只是在调试工具中看不到数据的变化,就是追踪数据不方便

10、vue 中 ajax 请求代码应该写在组件的methods中还是vuex 的action中

如果请求来的数据不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入 vuex 的 state 里

如果被其他地方复用,请将请求放入 action 里,方便复用,并包装成 promise 返回

 

其他与vue相关的技术点

1、你vue项目是怎么优化的你就可以说

1懒加载文件 2cdn缓存

1懒加载的方法

//  前提:结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

//  具体的操作过程:

//   将所有使用 import 导入组件的地方,修改为: const Login = ()=import('Login')

修改后每个()=>import()都会生成一个独立的js文件,也就是说只要使用这个语法webpack这就是一个代码分割点,这样生成一个独立的js文件,等到需要的时候按需加载功能

2cdn缓存

CDN缓存 就是第一次去主服务器访问后的一些文件会缓存到cdn上 下次直接去cdn缓存那就可以了 这就是cdn缓存

使用CDN优化代码的步骤:

// 1 找到第三方文件的CDN地址

// vue/vue-router 官方都提供了

//  如果没有提供的,就通过 https://www.bootcdn.cn/ 查找即可

// 2 在 index.html 页面中通过 script 标签,引入 CDN JS文件

// 3 在 /build/webpack.base.conf.js文件的 resolve 配置项前面添加 externals 配置项

// 4 在配置项中,配置

// vue: 'Vue'

//  键(vue):表示 import 时,导入包的名称

// import Vue from 'vue' 中的 'vue'

//  值('Vue'):表示 window.Vue(在 index.html 中引入 script 标签暴露在全局环境中的)

2、聊聊你对Vue.js的template编译的理解?

简而言之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点)

详情步骤:

首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。

然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)

3、Angular和vue的优缺点,你是怎么看待的

①   Vue:

优点: 1. 简单:官方文档很清晰,比 Angular 简单易学。

2. 快速:异步批处理方式更新 DOM。

3. 组合:用解耦的、可复用的组件组合你的应用程序。

4. 紧凑:~18kb min+gzip,且无依赖。

5. 强大:表达式 & 无需声明依赖的可推导属性 (computed properties)。

6. 对模块友好:可以通过 NPM、Bower或 Duo 安装,不强迫你所有的代码都遵循 Angular               的各种                   规定,使用场景更加灵活。

缺点: 1. 新生儿:Vue.js是一个新的项目,没有angular那么成熟。

2. 影响度不是很大:google了一下,有关于Vue.js多样性或者说丰富性少于其他一些有名库。

3. 不支持IE8:

②angularJS:

优点:1.  模板功能强大丰富,自带了极其丰富的angular指令。

2. 是一个比较完善的前端框架,包含服务,模板,数据双向绑定,模块化,路由,过滤器,      依赖注入等所有功能;

3. 自定义指令,自定义指令后可以在项目中多次使用。

4. ng模块化比较大胆的引入了Java的一些东西(依赖注入),能够很容易的写出可复用的     代码,对于敏捷开发的团队来说非常有帮助。

5.angularjs是互联网巨人谷歌开发,这也意味着他有一个坚实的基础和社区支持。

缺点:1. angular 入门很容易 但深入后概念很多, 学习中较难理解.

2. 文档例子非常少, 官方的文档基本只写了api, 一个例子都没有, 很多时候具体怎么用都是   google来的, 或直接问misko,angular的作者.

3. 对IE6/7 兼容不算特别好, 就是可以用jQuery自己手写代码解决一些.

4. 指令的应用的最佳实践教程少, angular其实很灵活, 如果不看一些作者的使用原则,很容易               写出四不像的代码, 例如js中还是像jQuery的思想有很多dom操作.

5. DI 依赖注入 如果代码压缩需要显示声明.

4、基于vue的ui框架? 1 Mui    2 mint-ui   3 element

5、mint-ui是什么?怎么使用?说出至少三个组件使用方法?

基于vue的前端组件库。npm安装,然后import样式和js,vue.use(mintUi)全局引入。在单个组件局部引入:import {Toast} from‘mint-ui’。
组件一:Toast(‘登录成功’);
组件二:mint-header;
组件三:mint-swiper

6、vuejs与angularjs以及react的区别?

1.与AngularJS的区别

相同点:

都支持指令:内置指令和自定义指令。

都支持过滤器:内置过滤器和自定义过滤器。

都支持双向数据绑定。

都不支持低端浏览器。

不同点:

1.AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观。

2.在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢。

Vue.js使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。

对于庞大的应用来说,这个优化差异还是比较明显的。

2.与React的区别

相同点:

React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。

中心思想相同:一切都是组件,组件实例之间可以嵌套。

都提供合理的钩子函数,可以让开发者定制化地去处理需求。

都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载。

在组件开发中都支持mixins的特性。

不同点:

React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。

Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作DOM。

 

7、什么时候用到过销毁的钩子函数?

在其他组件中有定时的会用到销毁的钩子函数

 

本文来源于:vue前端框架面试问题汇总-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...

发表评论