2018-09-21 vue面试题

2018-09-21  本文已影响0人  X秀秀

计算属性如何使用

一般我们在写vue的时候,在模板内写的表达式非常便利,它运用于简单的运算,但是他也有一些复杂的逻辑,包括运算、函数调用等,那么就用到了计算属性,他依赖于data中数据变化的  data 中数据变化的时候    计算属性就会重新执行,视图也会更新。

计算属性的 set  get 如何使用

每一个计算属性都包含一个getter 和一个setter ;

绝大多数情况下,我们只会用默认的getter 方法来读取一个计算属性,在业务中很少用到setter,所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter 和setter 都声明。

但在你需要时,也可以提供一个setter 函数, 当手动修改计算属性的值就像修改一个普通数据那样时,就会触发setter 函数,

watch 如何使用

之前做一个H5的项目。需求是当用户在输入完了手机号和验证码之后,登录按钮才可以点击。 

在没有使用vue之前,我们可能是通过input的change事件来判断,用户是否输入了内容,然后修改按钮的状态。现在有了vue,就省事了很多,我们只需要在watch中,监听数据模型的值改变即可。

在input 上绑定一个v-mode="pass"绑定一个数据名, 在data里写入绑定的事件名,通过watch来监听输入内容的改变,但是如果,监听的是一个对象 里面有一个deep属性可以在选项参数中指定deep:true.也叫深度监听  

<input v-model="passw2" placeholder="请再次输入密码" />

计算属性和watch的区别

在我们运用vue的时候一定少不了用计算属性computed和watch 

computed计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。这个功能非常强大,它可以让你的代码更加声明式、数据驱动并且易于维护。 

watch监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。

就好在div写一个表达式name,data里写入num和lastname,firstname,在watch里当num的值发生变化时,就会调用num的方法,方法里面的形参对应的是num的新值和旧值,

而计算属性computed,计算的是Name依赖的值,它不能计算在data中已经定义过的变量。

prop 验证,和默认值

我们在父组件给子组件传值得时候,为了避免不必要的错误,可以给prop的值进行类型设定,让父组件给子组件传值得时候,更加准确,prop可以传一个数字,一个布尔值,一个数组,一个对象,以及一个对象的所有属性。

组件可以为 props 指定验证要求。如果未指定验证要求,Vue 会发出警告

比如传一个number类型的数据,用defalt设置它的默认值,如果验证失败的话就会发出警告。

prop 如何传一个对象的所有属性

方法一:使用不带参数的v-bind写法

v-bind中没有参数,而组件中的props需要声明对象的每个属性

方法二:使用带参数的v-bind写法

v-bind后跟随参数todo,组件中的props需要声明该参数,也就是v-bind后跟随参数todo,

组件就可以通过todo来访问对象的属性

插槽,具名插槽,插槽默认内容

单个插槽;在父组件写一个标签,在子组件通过slot来接受标签里的内容,他只能用一个slot。单个插槽可以放置在组件的任意位置,但是就像它的名字一样,一个组件中只能有一个该类插槽。

具名插槽:在父组件标签写入slot,子组件里面写name名字,他们两个名字要相对应,才能通过名字在找到对应的位置。相对应的,具名插槽就可以有很多个,只要名字(name属性)不同就可以了。

作用域插槽

举个例子,比如我写了一个可以实现条纹相间的列表组件,发布后,使用者可以自定义每一行的内容或样式(普通的slot就可以完成这个工作)。而作用域插槽的关键之处就在于,父组件能接收来自子组件的slot传递过来的参数,子组件与父组件的数据动态交互的一种常见案例

父组件中必须要有template元素,且必须有scope特性,scope特性中是临时变量名,

接收从子组件中传递上来的属性,属性可以是任意定义的。

动态组件

在我们平时使用vue中的模板的时候,许多时候都是直接定义成一个固定的模板,但是,vue中提供了一个动态模板,可以在任意模板中切换,就是用vue中<component>用:is来挂载不同的组件。

我们在components中注册了三个模板,当我们点击当前按钮的时候,就会将模板切换模板,可以说是非常方便了。如果要把组件切换过程中的将状态保留在内存中,可以添加一个 keep-  alive 指令参数,防止重复渲染DOM。

动态组件上使用keep-alive

<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。

11子组件访问父组件实例子 $parent

this.$parent

在子组件中判断this.$parent获取的实例是不是父组件的实例

在子组件中console.log(this.$parent)  打印出this.$parent

在父组件中console.log(this)  打印出this

看看打印出来的两个实例是不是同一个

如果是同一个  就可以在子组件中通过this.$parent.属性名和方法名,来调用父组件中的数据或者方法

12 父组件访问子组件变量  this.$refs.usernameInput

给子组件添加ref属性然后,通过vm.$refs来调用子组件的methods中的方法或者获得data

父组件: 在子组件中加上ref即可通过this.$refs.ref.method调用

13 vue双向数据绑定原理

view更新data其实可以通过事件监听即可,比如input标签监听 'input' 事件就可以实现了。所以我们着重来分析下,当数据改变,如何更新视图的。

数据更新视图的重点是如何知道数据变了,只要知道数据变了,那么接下去的事都好处理。如何知道数据变了,就是通过Object.defineProperty( )对属性设置一个set函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现data更新view了。

视图view到data  :可以通过事件监听即可,比如input标签监听 'onchange' 事件就可以实现了

data到view:通过Object.defineProperty( )对属性设置一个set函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这个set函数里面就可以实现data更新view了。

14 vue 组件通信

1) 父传递子

父:自定义属性名 + 数据(要传递)=> :value="数据"

子:props ["父组件上的自定义属性名“] =>进行数据接收

1) 子传递父

  子:this.$emit('自定义事件名称', 数据)  子组件标签上绑定@自定义事件名称='回调函数'

    父:methods: {    回调函数() {      //逻辑处理  }  }

1) 兄弟组件

  通过中央通信 let  bus  =  new  Vue()

          A:methods :{ 函数{bus.$emit(‘自定义事件名’,数据)}  发送

          B:created (){bus.$on(‘A发送过来的自定义事件名’,函数)}  进行数据接受

15 vue 生命周期

vue实例从被创建到销毁的一系列过程就叫vue生命周期.也就是从开始创建、初始化数据、编译模版、挂载DOM→渲染、更新、渲染、卸载等一系列过程。

BeforeCreate  实例创建之前调用

Created      实例创建成功,此时data中的数据已经初始化

beforeMount  挂载之前的状态

Mounted      已经挂载的状态

BeforeUpdate  数据更新前的状态

Updated      数据更 新完成时的状态

beforeDestory  在vue实例销毁之前调用,

Destoryed    在vue实例销毁之后调用,vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

16  vue webpack打包项目修改哪些配置

Config文件夹下面的index.js 设置里面的assetsPublicpath属性值为./ 

如果图片太大的话,可以设置bulid文件夹下面的webpack.base.conf.js,设置图片的limit将它的值设大点,

Utils.js添加publicpath为../../

17  vue路由传参数

使用query方法传入的参数使用this.$router.query接受

使用params方式传入的参数使用this.$router.params接受

一、用name传递参数

在路由文件src/router/index.js里配置name属性。

routes: [

    {

      path: '/',

      name: 'Hello',

      component: Hello

    }

]

模板里(src/App.vue)用$router.name的形势接收,比如直接在模板中显示:

<p>{{ $route.name}}</p>

二、通过<router-link> 标签中的to传参

<router-link>标签中的to属性进行传参,需要注意的是这里的to要进行一个绑定,写成:to。

<router-link :to="{name:xxx,params:{key:value}}">valueString</router-link>

18   路由导航守卫

全局钩子函数  : beforeEach()  每次每一个路由改变的时候都得执行一遍

组件内的钩子函数  :

to: (Route路由对象)  即将要进入的目标 路由对象     

from: (Route路由对象)  当前导航正要离开的路由

next: (Function函数)   一定要调用该方法来 resolve 这个钩子

beforeRouteEnter 路由之前调用

beforeRouteUpdate 复用时调用

beforeRouteLeave  离开路由时调用

19 什么是vuex,使用vuex的好处

Vuex是一个专为 Vue.js 应用程序开发的状态管理模式。

好处:

    可以做状态管理  采用localstorage保存信息,数据便一直存储在用户的客户端中

    使用场景:适合在巨大后复杂的项目中使用,

20 state,getter,mutation,action,module,plugins  各自的用途,和用法

State:{  count: 0  }  保存着所有的全局变量

Getter: 对state中的数据派生出一些状态,例如对数据进行过滤。(可以认为是store中的计算属性),会对state中的变量进行过滤再保存,只要state中的变量发生了改变,它也会发生变化,不变化的时候,读的缓存。

Mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

一条重要的原则就是要记住 mutation 必须是同步函数。

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

有点不同的是Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

Module: //模块,可以写很多模块,最后都引入到一个文件。分散管理。

生成实例的时候 都放在Store的modules中

plugins:插件(Plugins)是用来拓展webpack功能的,它们会在整个构建过程中生效,执行相关的任务。

21 vuex中使用persistedstate 插件进行长久储存 (需要自己写代码测试)

安装  npm install vuex-persistedstate --save

store.js引入

import VuexPersistence from "vuex-persist";

创建一个对象:

const vuexLocal = new VuexPersistence({

    storage:window.localStorage

})

安装进vuex插件:

export default new Vuex.Store({

    state:{

        info:{}

    },

    mutations:{

        setInfo(state,info){

            state.info=info;

        }

    },

    plugins:[VuexPersistence()]

})

默认存储到localStorage

想要存储到sessionStorage,配置如下

import createPersistedState from "vuex-persistedstate"const store = new Vuex.Store({

  plugins: [createPersistedState({

      storage: window.sessionStorage

  })]

})

22 vue开发中遇到的问题

1、setInterval路由跳转继续运行并没有及时进行销毁

 比如一些弹幕,走马灯文字,这类需要定时调用的,路由跳转之后,因为组件已经销毁了,但是setInterval还没有销毁,还在继续后台调用,控制台会不断报错,如果运算量大的话,无法及时清除,会导致严重的页面卡顿。

 解决方案:在组件生命周期beforeDestroy停止setInterval

beforeDestory() {

    clearInterval(this.timer);

    MessageBox.close()               

}

2、vuejs循环插入图片 

在写循环的时候,写入如下代码:

<div class="bio-slide" v-for="item in items"> 

    <img src="{{item.image}}"></div>

此时在控制台会出现警告 

[Vue Warn]: src=”{{item.image}}”: interpolation in “src” attribute will cause a 404 request. Use v-bind:src instead.这里意思是在“src”属性插值将导致404请求。使用v-bind:src代替。 

所以替换成如下:

<div class="bio-slide" v-for="item in items"> 

    <img v-bind:src="item.image">

</div>

这里需要主要,v-bind在写的时候不能再用{{}},

3、组件的异步加载(按需加载组件)

  在平时的demo中,你可能不会遇见这个需求,当页面很多,组件很多的时候,你会发现你的页面在首次加载的时候,异常的慢,这个是因为vue首次加载的时候把可能一开始看不见的组件也一次加载了,这个时候就需要对页面优化了,就需要异步组件了。如何去写异步组件呢,实际上很简单,只需要在你的路由index,js里加上require就可以了,像下面这样,这也是所谓的按需加载组件的实现原理。

4、vuex组件中访问state报错

  TypeError: Cannot read property ‘state’ of undefined”

  在组件中使用this.$store.state.test访问state的属性报错,是因为store的实例并未注入到所有的子组件,需修改main.js

  new Vue({

  el: '#app',

  store, //将store注入到子组件

  router,

  components: { App },

  template: '<App/>'

  })

上一篇下一篇

猜你喜欢

热点阅读