Vue2基础面试总结

Vue的特点?

1、vue采用组件化模式,提高代码的复用率,维护性更好
2、声明式编码,无需直接操作dom,提高开发效率
3、使用虚拟DOM+diff算法,尽量复用dom节点。

Vue中的两种数据绑定的方式

1、单向数据绑定(v-bind):数据只能从data流向页面
2、双向数据绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data
  注意:
     (1):双向绑定一般应用在表单类元素上(input、select)
     (2):v-model:value="" 可以简写成 v-model="",v-model默认收集的就是value属性的值
     (3):v-model不能绑定props传过来的值,props传过来的值不能修改
     
3、v-model收集表单数据
     若:<input type="text"> v-model收集的是value值,输入的就是value值
     若:<input type="radio"> v-model收集的是value值,需要给标签设置value值
     若:<input type="checkbox"> 
        (1):没有配置value属性,那么收集的就是checked的值
        (2):有配置value属性
            1、v-model的初始值不为数组,收集的就是checked的值
            2、v-model的初始值为数组,收集的就是value的值组成的数组
    v-model的三个修饰符
        v-model.lazy : 失去焦点后在收集数据
        v-model.number: 收集的数据转换为数字
        v-model.trim : 删除首位的空客

怎样理解Vue中的MVVM模型?

MVVM模型分为三层部分:
1、M: 数据层(可能是我们自己写的固定数据,也可能是来自服务器的数据)
2、V: 视图层(DOM层,给用户展示数据)
3、VM:视图模型层:视图层和数据层沟通的桥梁,一方面实现了数据绑定,实时的将数据层中数据改变反应到视图层,
另一方面是实现了DOM监听,DOM发生了一系列的事件是,在一定的情况下对数据层中的数据进行对应的改变

Vue2基础面试总结

Vue中事件修饰符

1、prevent :阻止默认事件
2、stop: 阻止事件冒泡
3、once:只触发一次事件
4、capture: 使用事件的捕获模式
5、self: 只有event.target是当前操纵的元素时才触发事件
6、passive:事件的默认行为立即执行,无需等待事件回调执行完毕

计算属性

1、定义:要用的属性不存在,要通过已有的属性计算得来
2、原理:底层借助了Object.defineproperty方法提供的getter和setter
3、get函数的执行时机?
   (1)、初次读取时会被执行一次
   (2)、当依赖的数据发生改变时会再次调用
4、优点:与mmethods相比,内部有缓存机制,可复用,效率更高。
5、计算属性要被修改,必须写set函数去响应修改。计算属性会出现在vue的实例上,直接使用即可

深度监视

(1)、Vue中的watch默认不监测属性为对象时对象内部值的改变
(2)、配置deep:true可以监测属性为对象时对象内部值的改变(多层)

计算属性和监视属性的区别?

1、计算属性能完成的功能,监视属性也可以
2、监视属性能完成的功能,计算属性不可以(监视属性可以进行异步操作,计算属性不能)

React/Vue中的key有什么作用?(key的原理是什么?或为什么遍历列表时,key最好不要用index)

1、key的作用
当状态中的数据发生改变时,react会根据新数据生成新的虚拟DOM,随后react进行新虚拟DOM于旧虚拟DOM比较,
比较规则:1、旧虚拟DOM找到了与新虚拟DOM相同的key
           (1)、若虚拟DOM中的内容没变,直接用之前的真实的DOM。 
           (2)、若虚拟DOM的内容变了,则生成新的真实DOM,最后替换页面中之前的真实DOM
         2、旧虚拟DOM中未找到与新虚拟DOM相同的key
           (1)、根据数据创建的新的真实DOM,随后渲染到页面
2、用index做key时可能会引发的问题
   (1)、若对数据进行:逆序添加、逆序删除、等破环顺序的操作 会产生没必要的真实DOM的更新 效率较低
   (2)、如果结构中还包含输入类的DOM: 会产生错误的DOM更新
   (3)、如果不存在逆序对数据的操作,用index做key是没问题的
3、开发中如何选择key
   (1)、最好使用每条数据的唯一标识作为key

Vue中监测数据的原理

1、vue会检测data中所有层次的数据
2、对象数据的检测
  (1)、通过setter实现监测、要在创建vue的实例对象时要传入数据
  (2)、后续添加的属性,Vue默认不做响应式处理
  (3)、如需给后续添加的属性做响应式处理
      (1)、Vue.set(target,属性名,属性值)
      (2)、vm.$set(target,属性名,属性值)
3、数组数据的监测
  1、通过包装数组更新元素的方法实现监测
     (1)、调用原生数组的方法对数组进行更新
     (2)、重新解析模板,进而更新页面
  2、Vue中用以下方法对数组进行操作会做响应式的处理
     (1)、push(),pop(),shift(),unshift(),splice(),sort(),reverse()
     (2)、Vue.set(target,index,value)或vm.$set(target,index,value)
4、切记:Vue.set()和vm.$set(),不能给vm或vm的根数据对象(data),添加属性

v-xxx其他指令的作用

1、v-once指令(没有值): 
    (1)、v-once所在的节点在初次动态渲染后,就视为静态内容了
    (2)、以后数据的改变不会引起v-once所在的节点更新,可以用于优化性能
2、v-cloak指令(没有值):
    (1)、本质是一个特殊的属性,Vue实例创建完毕并接管DOM容器后会删除v-cloak属性
    (2)、与css配合可以解决因网速过慢而将未渲染好模板渲染到页面上
3、v-text指令:
    (1)、作用:向其所在的节点渲染文本内容(v-text的属性值)
    (2)、v-text会替换掉节点中的内容
4、v-html指令:
    (1)、作用:向其所在的节点渲染包含html结构的内容,识别html结构
    (2)、v-html会替换掉节点中的内容
    (3)、具有安全性问题
        1、在网站上动态渲染Html非常危险,容易导致xss攻击
        2、要在可信的内容上用v-html,永不要用在用户提交的内容上
5、v-pre指令(没有值): 
   (1)、跳过其所在的节点的编译过程
   (2)、可以用他跳过,没有使用指令语法,插值语法的节点,加快编译

自定义指令

1、定义语法
  (1)、局部指令:
      new Vue({
         directives: {
             指令名:{配置对象}
         }
     }) 
     或
     new Vue({
       directives: {
         指令名:回调函数
       }
     })
 (2)、全局指令:
    Vue.directive(指令名:{配置对象}) 或 Vue.directive(指令名,回调函数)
2、配置对象中常用的三个回调 this指向window
  (1)、bind(): 指令与元素绑定成功时调用
  (2)、inserted():指令所在的元素插入页面时调用
  (3)、update(): 指令所在的模板被重新解析时调用
3、例子:
 new Vue({
     directives: {
          fbind: {
            bind(element,binding) {
                element.value = binding.value * 10
            },
            inserted(element,binding) {
                element.focus()
            },
             update(element,binding) {
                 element.value = binding.value * 10
             }
         }
       }
     }) 
new Vue({
     directives: {
        big(element,binding){
            element.innerHTML = binding.value * 10
         }
      }
   }) 
Vue.directive('big',function(element,binding) {
      element.innerHTML = binding.value * 10
})
4、指令名不要用驼峰命名法,要用word-word的方法

生命周期

Vue2基础面试总结

webStorage(浏览器存储)

1、存储内容一般为5MB左右,不同的浏览器不同
2、浏览器通过window.localStorage和window.sessionStorage的属性来实现本地存储
3、API:
    (1): window.local(session)Storage.setItem('key','value') //接受一对键和值进行存储,
    key和value都为字符串
    (2): window.local(session)Storage.getItem('key') //返回键名对应的值,不存在返回null
    (3): window.local(session)Storage.removeItem('key') //删除该键值对
    (4): window.local(session)Storage.clear()//清空
4、
   (1)、sessionStorage存储的内容会随着浏览器的关闭而清空
   (2)、localStorage存储的内容,只有手动清除
   (3)、JSON.parse(null)的结果仍是null

消息的订阅与发布

1、一种组件间的通信方式
2、使用步骤
  (1):安装pubsub-js库 (npm install pubsub-js)
  (2):引入 import pubsun from 'pubsub-js'
  (3):接受数据,在接受消息的组件订阅消息
     mounted() {
       this.pubsubId = pubsub.subscribe('消息名',(msgName,data) => {
             //回调函数有两个参数,第二参数即为发送的数据
             //data即为发送过来的数据 
       })
    }
 (4):发送数据
     pubsub.publish('消息名',data)
3、最好在beforeDestory的周期函数中,用pubsub.unsubscribe(this.pubsubId)去取消订阅

$nextTick(回调函数)

作用:在下一次DOM更新结束执行其指定的回调
用的时机:当改变数据后,要基于更新后的DOM进行某些操作,要在$nextTick所指定的回调函数中执行

Vuex

1、环境搭建
  安装vuex(npm i vuex)
  在src文件夹下创建Store文件夹,并在其中创建一个index.js
  index.js的配置代码如下:
  import Vue from 'vue'
  import Vuex from 'vuex'
  Vue.use(Vuex)
  const actions = {}
  const mutations = {}
  const state = {}
  export default new Vuex.Store({
     actions, 
     mutations ,
     state
  })
  在main.js文件夹其中的配置 
  import store from './src/Store/index.js'
  new Vue({
  render: h => h(App),
  store
  }).$mount('#app')
  
2、mapSate方法从state中读取数据
   假如state中的数据如下:
   const state = {
      sum:0,
      school: '某某某大学',
      student: '某某某' 
   }
   //mapState
   computed: {
    ...mapState({sum:'sum',school:'school',student:'student'})  
    或
    ...mapState(['sum','school','student'])
   }
3、mapGetters方法从getters中读取数据
    假如getters中的数据如下:
    const getters = {
       bigSum(state) {
         return state.sum * 10 
       } 
    }
  //mapGetters
  computed:{
    ..mapState({bigSum:'bigSum'})  
    或
    ...mapState(['bigSum'])
  }
4、mapMutations 会帮助我们与mutations对话
const mutations = {
    increment(state,value) {
        state.sum += value
    },
    decrement(state,value) {
        state.sum -= value
    }
}
//mapMutations
methods:{
  ...mapMutations({increment:'increment',decrement:'decrement'}),
  或
  ...mapMutations(['increment','decrement']),
}
5、mapActions 会帮助我们与actions对话
const actions = {
    incrementOdd(context, value) {
        if (context.state.sum % 2 ) {
            context.commit('increment',value)
        }
    },
    delayIncrement(context,value) {
        setTimeout(() => {
            context.commit('increment',value)
        },1000)
    }
}
//mapActions
methods: {
   ...mapActions({incrementOdd:'incrementOdd',delayIncrement:'delayIncrement'}),
  或
  ...mapActions(['incrementOdd','delayIncrement']),
}
备注:mapActions与mapMutations使用参数时,若需要传递参数,在模板绑定事件时要传递好参数,否则传递的参数是事件对象

创建路由器并配置路由

1、npm i vue-router
2、在src文件夹下创建router文件,并在该文件内创建index.js
3、src/router/index.js的内容代码如下:
 import Vue from 'vue
 import VueRouter from 'vue-router'
 Vue.use(VueRouter)
 export default new VueRouter({
   routes: [
    {配置路径和对应的路由组件},
    {配置路径和对应的路由组件},
    {配置路径和对应的路由组件},
   ]
 })
4、main.js代码如下:
import router from './router/index'
new Vue({
  render: h => h(App),
  router
}).$mount('#app')
5、基本使用: 
  <router-link to="path(路径)"></router-link>//跳转组件
  <router-view></router-view> //组件显示的位置
6、路由传参:
  query参数:
	  (1):<router-link :to="`path(路径)?id=${参数}&name=${参数}`"></router-link>
	  (2):<router-link :to="{
	        path:'path(路径)',
	        query: {
	          id:'id',
	          name: 'name' 
	        }
	     }"></router-link>
 params参数:
  (1):在配置路由时要使用占位符声明接受params参数
     {
          path:'/home/:id/:title'
          component: Home 
     }
  (2):<router-link :to="`path(路径)/${id}/${title}`"></router-link>
  (3):<router-link :to="{
	        name:'路由的别名', //必须这样写
	        params: {
	          id:'id',
	          name: 'name' 
	        }
	     }"></router-link>
7、获取参数
   {{$route.query(params).id}}
   {{$route.query(params).name}}
8、路由的props配置:
  {
     path: 'detail',
     component: Detail,
    // props: {a:1,b:100}
    // props:true //值为true把该路由收到的所有参数以props的形式传递给Detail组件
     props(route) { //该函数返回的对象以props形式传递给Detai组件
          return {
              id: route.query.id,
              title: route.query.title
           }
       }
  }
9、router-link标签的replace属性
(1)作用:控制路由跳转时操作浏览器记录的模式
(2)浏览器历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录,默认为push
(3) 开启replace模式 <router-link replace></router-link>
10、编程式路由导航
  (1):不借助<route-link>实现跳转
  (2):
       this.$router.push({
            name: '路由的名字',
            params: {
              id: 'id',
              title: 'title' 
            } 
       })
       his.$router.replace({
            name: '路由的名字',
            params: {
              id: 'id',
              title: 'title' 
            } 
       })
   (3):this.$router.back() //后退
  (4):this.$router.forward()//前进
  (2):this.$router.go(number) //number为正前进,number为父后退。
 11、缓存路由组件
  作用:让不展示的路由组件保持挂载,不被销毁
  //包括在includes属性里的组件才会缓存,不写该属性,默认所有在下方展示的组件都会缓存。
  <keep-alive include="组件名">  //缓存一个
    <router-view></router-view> 
  </keep-alive>
  <keep-alive :include="['组件名','组件名']">  //缓存多个
    <router-view></router-view> 
  </keep-alive>
12、路由组件所独有的生命周期函数
 1、activated 路由组件激活时触发
 2、deactivated 路由组件失活时触发
13、路由守卫
   作用:对路由的权限进行控制
   1、全局守卫
      (1):全局前置守卫
         初始化时调用、切换之前调用
         //对路由的权限进行判断
         //成功进行跳转 否者不跳转
         router.beforeEach((to,from,next) => {
            if (to.meta.isAuth) {
                 if (localStorage.getItem('school') === 'atguigu') {
                     next() 
                 } else {
                    alert('暂无权限查看') 
                 }
            } else {
               next() 
            }
         })
	    (2):全局后置守卫
	    //初始化时调用、切换之后调用
	    router.afterEach((to,from) => {
	    //一般用的较少,但会用于路由跳转之后改变网页的title
	       if (to.meta.title) {
	           document.title =  to.meta.title
	       } else {
	         document.title =  项目名
	       }
	    })
  2、独享路由守卫(只有前置)在某个路由内部进行配置
   beforeEnter((to,from,next) => {
      if (to.meta.isAuth) {
                 if (localStorage.getItem('school') === 'atguigu') {
                     next() 
                 } else {
                    alert('暂无权限查看') 
                 }
            } else {
               next() 
            }
    })
 3、组件内路由守卫(在组件中进行配置)
 //通过路由规则进入该组件时,被调用
 beforeRouteEnter((to,from,next) => {
     if (to.meta.isAuth) {
                 if (localStorage.getItem('school') === 'atguigu') {
                     next() 
                 } else {
                    alert('暂无权限查看') 
                 }
            } else {
               next() 
            }
 })
  //通过路由规则离开该组件时,被调用
  beforeRouteLeave((to,from,leave) => {
     next()
  })
   

ElementUI按需引入样式的配置和使用的步骤

1、安装(npm i element-ui)
2、babel.config.js文件中的配置
  module.exports = {
	  presets: [
	    '@vue/cli-plugin-babel/preset',
	    ["@babel/preset-env", { "modules": false }]
	  ],
	  "plugins": [
	    [
	      "component",
	      {
	        "libraryName": "element-ui",
	        "styleLibraryName": "theme-chalk"
	      }
	    ]
	  ]
}
3、main.js文件代码
import {Button,Row,DatePicker} from 'element-ui' //引入所要用到的样式
Vue.component(Button.name,Button)
Vue.component(Row.name,Row)
Vue.component(DatePicker.name,DatePicker)
上一篇:Android SDK更新后Eclipse无法正常工作问题


下一篇:【vue】vue2+vue3数据监听