Vue - 面试大纲26问

1.Vue2.0生命周期DOM元素在哪个阶段挂载?组件中el是否会影响组件的渲染顺序?

在这里插入图片描述

问题一:

要处理生命周期几个函数
*new Vue 创建vue实例
*初始化:生命周期,事件,但代理数据还未开始。
beforeCreate : 此时:无法通过vm访问到data中得数据,methods中的方法。
*初始化:数据监听和数据代理。
created : 此时:可以通过vm访问到data中的数据,methods中的方法。
*此阶段Vue开始解析模板,生成虚拟DOM(内存中),页面还不能显示解析好的内容。
beforeMount : 此时:1.页面中呈现的是未经Vue编译的DOM结构,2.所有DOM的操作,最终都不奏效。
*将内存中的虚拟DOM转为真实DOM插入页面。
mounted : 此时:1.页面中呈现的是经历Vue编译的DOM。2.对DOM的操作均有效(尽可能避免)。至此初始化过程结束,一般在此进行:开启定时器,发送网络请求,订阅消息,绑定自定义事件,等初始化操作。
beforeUpdate
updated
beforeDestroy
destroyed

问题二:
有影响,
有el:问题一解释得流程是有el且没有template的流程会一直渲染到mouted;
没有el:就是没有告诉vm要执行哪个节点,vm迷失了,会走到created就不向下走了,需要调用vm.$mount(el)指定才会执行到mounted;

2.对MVVM理解

## MVVM模型
1.M : 模型(Model):对应data中的数据; 最终会出现再vm实例对象身上,所以可以直接被调用;
2.V : 视图(View) : 模板代码(页面);
3.VM : 试图模板(ViewModel): vue实例对象 ;实现页面监听和数据绑定;所以经常用vm这个字段代表vue实例;
## 观察发现:
data中所有属性,最后都出现在vm身上;
vm身上的所有属性及Vue原型上的所有属性,再vue模板中都可以直接使用。

在这里插入图片描述

3.简述v-model的作用,v-model和:value的区别和应用场景。

回答:v-model实现的是双向数据绑定,:value是展示默认值,所以,当一个input需要双向数据绑定的时候用v-model,只需要展示默认值的时候直接用value

<input v-model="searchText">

等价于

<input  :value="searchText"  @input="searchText = $event.target.value" />

4.如何侦听data中的数据变化?

## 普通监听

watch:{
    isHot(newVal,oldVal){
        console.log(newVal,oldVal);
    }
}

## 深度监听

watch:{
   isHot:{
       immediate:false, // 默认是否执行监视(页面加载的时候就执行)
       deep:true, // a:{b:c:{}}  如果是多层的那么需要开启deep
       handler(newVal,oldVal){
          console.log(newVal,oldVal);
      }
   }
}

## computed(计算属性)监听

computed:{
    fullName:{
        get(){
            return `${this.firstName}-${this.lastName}`
        },
        set(value){
            let arr        = value.split('-')
            this.firstName = arr[0]
            this.lastName  = arr[1]
        }
    }
 }

5.描述vue计算属性如何使用?

在这里插入图片描述
## 只获取不修改简写

 fullName(){
      return `${this.firstName}-${this.lastName}`
 }

## 又获取又修改需要用完整写法
get :1.初次读取数据时,被调用;2.所依赖的数据发生变化时;

computed:{
    fullName:{
        get(){
            return `${this.firstName}-${this.lastName}`
        },
        set(value){
            let arr        = value.split('-')
            this.firstName = arr[0]
            this.lastName  = arr[1]
        }
    }
 }

6.vue计算属性和侦听方法的应用区别?什么情况下使用计算属性?什么情况下使用侦听方法?

答:
wacth:监听date中的数据,
computed 计算属性是不需要,且不能再data中声明,可以想data一样使用;
1.computed能完成的功能watch一定都能完成;
2.watch能完成的功能,computed不一定能完成,例如:watch可以异步处理(定时器)
注意:computed能实现的时候都用computed ,couputed不能实现用watch;

7.class动态绑定分别为对象和数组两种语法,请分别简写另种语法代码段?两种语法是否可以共同应用?

1.字符串类型:data中有个属性叫classA:‘normal’,会汇总成为一个class,适用于样式的名称不确定,需要动态绑定;

class = 'a'  :class='classA'

2.数组类型:data中有个属性叫arr的数组[‘atgu1’,‘atgu2’,‘atgu3’],适用于要绑定的样式个数不确定,名字也不确定;

class = 'a'  :class='arr'

3.对象类型:data中有个属性叫classObj的对象{obj1:false,obj2:true},适用于要绑定的样式个数确定,名字也确定,但是要动态控制用不用;

class='a' :class='classObj'

4.数组和对象可以同时应用

class="[{ active: isActive }, errorClass]"

8.简述vue2.0中v-if 和v-show的区别,频繁切换(tab)用那种方式?两者对页面的性能有什么影响?

答:1.v-if 适用于切换频率比较低的场景,不展示的DOM直接被移除了;v-show适用于切换频率比较高的场景,不展示的DOM被隐藏了未移除;使用v-if的时候元素可能获取不到,使用v-show元素一定可以获取到;

2.切换频率较高用v-show;

3.频繁想vm插入清除节点,自然没有v-show隐藏来的好;
4.v-show在页面初次渲染时对于页面性能影响较大,因为需要同时把DOM内容渲染; v-if则在页面初次渲染时只渲染true部分DOM,所以对于页面性能影响较小;

9.在vue2.0中v-if和v-for在同一标签应用时,谁的优先级更高?

答:for 优先级更高,先遍历后根据遍历的条件进行判断if;(最好不要一起使用)要结合computed 遍历出来 符合条件的,再用v-for遍历;

10.在vue2.0中观察以下代码,用户输入用户名后切换到tab会造成input残余,如果实现切换时重新渲染表单?

答案:翻译过来就是如何让这两个表单切换后每次都是清空的,方法有很多 指定key 就会清空

<template v-if="loginType">
     <label>Username</label>
     <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>
<button type="button" @click='loginType = !loginType'>切换两个值</button>

11.请检查下列vue代码中存在的问题:

<ul>
	<li v-for="(item,index) in 10">{{index}}</li>
</ul>

正常写法:因为10遍历后是12345678910,看上图显示的index应该是1-9,不会出现重复数据,设立key也不会出现冲突,所以直接用一个item就可以解决代码key不一致的问题,具体情况具体分析,按照当前的这个结构的话,不用index是最明智的;

<ul>
	<li v-for="item in 10" :key="item">{{ item-1 }}</li>
</ul>

12.父组件向子组件的传参方式?

方法1,啥都接收不规定类型,不会有报错提示;

props:['name','age']

方法2,生命接收的参数的类型,会又报错提示;

props:{
	name:String,
	age:Number
}

方法3,生命接收的参数的类型,会又报错提示;

props:{
	name:{
		type:String,// 类型
		required:true, // 必须
	}
	age:{
		default:14, // 默认
		type:Number
	}
}

注意:不要尝试去修改props中的值;

13.如何监听子组件的事件变化?

方法一 父组件通过给子组件传一个函数类型的props来实现,父组件监听子组件事件的变化
父组件:

<child :getName = 'getName' />
//  在methods方法中定义getName方法监听子组件是否有变化val 就是子组件传过来的值
methods:{
	getName(val){
		console.log(val)  // 输出结果:张三
	}
}

子组件:

props:['getName'] , // 接收父组件传递过来的参数

// 比如说有个点击事件
methods:{
	sendName(){
		this.getName('张三')
	}
}

方法二 自定义事件来实现父组件监听子组件 v-bind: @
父组件:

<child @methodName = 'getName' />
//  在methods方法中定义getName方法监听子组件中是否触发了一个叫做methodName自定义事件;
methods:{
	getName(val){
		console.log(val)  // 输出结果:李四
	}
}

子组件:

// 比如说有个点击事件触发父组件的方法
methods:{
	sendName(){
		this.$emit('methodName','李四')
	}
}

方法三 子组件的ref事件监听子组件的事件变化
父组件:

<child ref='child' />
//  在methods方法中定义getName方法监听子组件中是否触发了一个叫做methodName自定义事件;
mounted(){
	this.$refs.child.$on('methodName',this.getName)
	this.$refs.child.$on('methodName',(val)=>{
		console.log(val)
	})  // 用这种方法就不要methods中的getName方法了;
},
methods:{
	getName(val){
		console.log(val)  // 输出结果:李四
	}
}

子组件:

// 比如说有个点击事件触发父组件的方法
methods:{
	sendName(){
		this.$emit('methodName','李四')
	}
}

方法四 全局事件总线,比说监听父组件了,任意组件全绝都可以监听
在这里插入图片描述

方法五 消息订阅与发布

在这里插入图片描述

14.组件的插槽的应用,子组件与父组件通讯如何应用?

1.默认插槽
如果子组件中,父组件中调用的子组件的开始标签和结束标签中间的内容将会展示再子组件slot中,
如果子组件没有定义slot,父组件中调用的子组件的开始标签和结束标签中间的内容将不会展示;

2.具名插槽
在子组件中声明插槽带名字
在这里插入图片描述
在父组件调用的地方用v-slot:header或者 #header
在这里插入图片描述
3.插槽作用域,插槽prop父组件定义的子组件想用子组件中的接到的某个参数某个参数
在父组件中:default要对应到子组件中的user要保持一致记得;
在这里插入图片描述
在子组件中,:user要根据父组件中的v-slot:user一致
在这里插入图片描述

总结:以上代码中的v-bind 可换成:
以上代码中的v-slot可换成#

15.简述VueRouter的功能。(SPA应用-单页面应用)

理解:是vue的一个插件库,专门用来实现SPA单页面应用的。
需要 npm i vue-router

SPA应用理解?
1.单页 web 应用(single page web application,SPA)。
2.整个应用只有一个完整的页面。
3.点击页面中的导航链接不会刷新页面,只做页面局部更新。
4.数据需要通过ajax请求获得。

什么是路由?
1.一个路由就是一组映射管理(key-value)
2.key为路径,value可能是fuc或component
前端路由:value是个component,用于展示页面内容,当路由器的路径变了,对应的组件就会显示。

总结:路由路由,根据你的路径,由我决定展示哪个组件;

** ## 使用: **
第1步:npm i vue-router
第2步:在main.js中引入并use vue-router(绿色框),第3步定义的路由引入(红色框)
在这里插入图片描述
第3步:创建一个router-》index.js 如下图编些router的配置项。
在这里插入图片描述
第4步:使用路由
// 1.实现路由的切换

<router-link :to='/about' active-class='action'>About</router-link>

// 2.指定组件的呈现位置

<router-view:to='/about' active-class='action'>About</router-view>

注意:切换路由组件,原路由组件被销毁的;

16.VueRouter监听页面跳转路由变化的方式有那种?

全局路由守卫
router.beforeEach:前置路由守卫 收到参数 to,from ,next;
router.afterEach:后置路由守卫 收到参数 to,from ;
组件路由守卫
beforeRouteEnter:通过路由规则进入组件,收到参数,to,from,next
beforeRouteUpdate:通过路由规则更新组件,收到参数,to,from,next
beforeRouteLeave:通过路由规则离开组件,收到参数,to,from,next
独享路由守卫 只有前置没有后置
beforeEnter:只对设置的组件进行监听,收到参数,to,from,next
** watch 监听 **

watch:{
  $route(to,from){
    console.log(to.path);
  }
},

17.vueRouter页面跳转方式有几种?

第一种跳转方式:
// 实现路由的切换

<router-link :to='/about' active-class='action'>About</router-link>

// 指定组件的呈现位置

<router-view></router-view>

注意:如果是跳转二级路由 to的时候要把它父亲的二级带出来;

第二种跳转方式编程

this.$router.push(name:'Hello',paramas:{name:'zhagnsan'})

18.请阅读一下代码中存在的问题并简述下列代码实现的功能

const router =  new VueRouter({...})
router.beforeEach(()=>{
	next()
})
router.afterEach(()=>{
	next()
})

回答:1.beforeEach前置路由守卫有3个参数,to,from,next
afterEach后置路由守卫有2个参数,to,from,没有next
2.全局前置路由守卫:初始化执行,每次路由切换之前执行,可以根绝to中的meta:{auth:true}去执行是否需要登录
写法 ,用to.meta.auth可以在这个位置判断一下处理跳转到登录页面还是直接跳转指定页面;
3.全局后置路由守卫:每次路由切换后执行。后置路由一般应用于设置页面标题,能成功跳转后再设置title;

const router =  new VueRouter({...})
router.beforeEach((to, from, next) => {
   console.log(to,from)
   next() // 放行就是可以跳转的意思
})
router.afterEach((to, from) => {
	console.log(to,from)
})

19.组件内路由守卫简述三种拦截器的作用与区别;

通过路由规则进入组件:举例不是通过路由规则的import一个组件;

区别:进入,更新,离开;
作用:通过路由规则,进入该组件被调用,更新该组件是被调用,离开该组件是被调用;

// 通过路由规则,进入该组件是被调用
beforeRouteEnter(to,from,next){
	console.log(to,from,next)
}
// 通过路由规则,更新该组件是被调用
beforeRouteUpdate(to,from,next){
	console.log(to,from,next)
}
// 通过路由规则,离开该组件是被调用
beforeRouteLeave(to,from,next){
	console.log(to,from)
}

20.网站url地址为『https://yuzhankeji.com/』,阅读下列代码,写出完整的表现:

const router = new VueRouter({
	routers: [{
		path: “/”,
		component: ()=> import(“@/pages/index/index”)
		alias: “/Index”
	}]
})

回答:http://yuzhankeji.com/Index

21.路由的传参方式有几种?简述各个传参方式的区别?

回答:router-link 和 编程式路由

**router-link 第1种 跳转路由并携带query参数 **
to的字符串写法

<router-link :to='`/about?name=${item.name}&age=${item.age}`' active-class='action'>About</router-link> // 传参

to的对象写法

<router-link :to="{path:'/about',query:{name:item.name,age:item.age}}" active-class='action'>About</router-link> // 传参

to的对象name跳转

<router-link :to="{name:'About',query:{name:item.name,age:item.age}}" active-class='action'>About</router-link> // 传参
mounted(){this.$route.query }    // 接收参数

** router-link 第2种 跳转路由并携带params参数 **

需要在js中配置

path:'detail/:id:name'

在这里插入图片描述
to的字符串写法

<router-link :to='`/about/${item.name}/${item.age}`' active-class='action'>About</router-link> // 传参

to的对象name跳转

<router-link :to="{name:'About',params:{name:item.name,age:item.age}}" active-class='action'>About</router-link> // 传参
mounted(){this.$route.params}    // 接收参数

总结:特别注意:路由携带params参数时,如使用to得对象写法,则不能使用path配置项,必须使用name配置!

** router-link 第3种 路由的props 配置 **
在这里插入图片描述

编程式路由传参

this.$router.push(name:'Add',params:{age:1})  // 跳转可返回
this.$router.replace(name:'Add',params:{age:1})  // 跳转不可返回
this.$router.back()  // 返回
this.$router.forward()  // 前进
this.$router.go()  // +数向前走,-数后退

//路由缓存:路由保持挂载不被销毁;Message是组件名组件名组件名;

<keep-alive include='Message'>   </keep-alive>
// 使用keep-alive 会触发如下两个方法,跟methods同级;
activated(){}
deactivated(){}

22.在当前路由变更,但组件被重复调用时,使用什么方法监听路由的变化?

区别:进入,更新,离开;
作用:通过路由规则,进入该组件被调用,更新该组件是被调用,离开该组件是被调用;

// 通过路由规则,进入该组件是被调用
beforeRouteEnter(to,from,next){
	console.log(to,from,next)
}
// 通过路由规则,更新该组件是被调用
beforeRouteUpdate(to,from,next){
	console.log(to,from,next)
}
// 通过路由规则,离开该组件是被调用
beforeRouteLeave(to,from,next){
	console.log(to,from)
}

23.简述VueX。

集中式状态(数据)管理的一个vue插件。
多个组件依赖统一状态。-共享
在这里插入图片描述

24.简述Vuex中state,actions,getters,mutations的作用。

搭建vuex环境
1.安装 npm i vuex
2. 引入store;
import store from ‘你的存放路径’
在new 中 写store使用store;
在这里插入图片描述

创建store的两种方式
src下创建store文件夹,新增一个index.js文件
编写index.js文件 创建三个对象分别是actions ,mutations,state

// 引入vuex
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
// 准备actions中的方法接到两个参数一个context一个value - 用于响应组件中的动作(服务员);
// 组件中调用actions  this.$store.dispatch('add',2)
const actions = {
	add(context,value){
		context.commit('ADD',value)
	}
}
// 准备mutations中的方法接到两个参数一个state一个value - 用于操作数据(state)(厨师);
// 组件中调用mutations   this.$store.commit('ADD',2)
const mutations = {
	ADD(state,value){
		state.sum += value
	}
}
// 准备state - 用于存储数据;
// 组件中调用state的值 ,this.$store.state.sum
const state= {
	sum:0
}
// 准备getters - 用于将state中的数据进行加工;有点像计算属性可以处理state中的值;
// 组件中调用getters中的值 this.$store.getters.bigSum方法名
const getters = {
	bigSum(state){
		return state.sum * 10
	}
}
//创建并暴露store
export default  new Vuex.Store({
	actions,
	mutations,
	state,
	getters 
})

方法1.组件中使用store,需要actions
第一步.需要异步处理或者需要判断之类需要调用actions,在组件中调用actions中名称为add的方法,

this.$store.dispatch('add',3)

第二步。在store.js的actions中使用的时候,要有add这个方法,接收两个参数一个context为整个store对象,一个value传过来的值,需要调用mutations中的ADD方法

add(context,value){
	context.commit('ADD',value)
}

第三步,在mutations中创建方法接受参数一个state 一个value

ADD(state,value){
	state.sum += value
}

方法2,不需要调用actions,在组件中直接调用;

this.$store.commit('ADD',3)

组件中简写store中的state和actions和mutations和getters


import { mapState ,mapGetters,mapMutations,mapActions} from ‘vuex’
在computed中

...mapState({he:‘sum’,scl:‘school’,sub:‘subject’})  //object写法
...mapState([‘sum’,‘school’,‘subject’])  //数组写法
...mapGetters({bigSum:‘bigSum’})  //object写法
...mapGetters([‘bigSum’])  //数组写法

在methods



@click = 'add(3)' // 必须传参。
...mapMutations({add:'ADD'}) // object
@click = 'ADD(3)' // 必须传参。
...mapMutations(['ADD'])  // 数组写法。

@click = 'add(3)' // 必须传参。
...mapActions({add:'add'}) // object
@click = 'add(3)' // 必须传参。
...mapActions(['add'])  // 数组写法。



在这里插入图片描述在这里插入图片描述注意:封装注意事项
1.namespaced:true
2.模块化后要用 :
在这里插入图片描述
3.指定名称;
在这里插入图片描述
4.如果用的commit方法请求的注意要这么写下图
在这里插入图片描述
最后的最后,分别把学生和数分别放到不同得文件夹,方便管理
新建js
在这里插入图片描述

在store中引入 名字自己定义就行了随便定义,保持一致就行;
在这里插入图片描述


总结一下:
1.在组件中调用store中的state $store.state.sum;

2.调用store中actions this.$store.dispatch(‘add’,2) ;

3.调用store中的mutations this.$store.commit(‘ADD’,2);

4.actions中的add方法接受两个参数,第一个参数是整个context,第二个是传过来的值value,context中必须要执行mutations中的方法 context.commit(‘ADD’,value)

5.state中存放的就是全局中的公用状态;

6.getter类似计算属性中的方法有一个参数就是state中的对象且方法必须又返回值必须又return,获取方法$store.getter.方法名。

25.简述Vuex中state.commit()的用法。

答案:两个地方需要用到他,
1.组件中.this.$store.commit (‘ADD’,2)
2.actions中使用 context.commit(‘ADD’,2)

26.阅读以下代码:

(1.)简述代码实现的功能?多个组件共享同一状态
(2.) 描述页面temp2.vue文件最终输出结果?
**vmVue.js文件**
import Vue from 'vue'
export default new Vue()

**Temp-1.vue文件**
<template>
  		<div>
    		<input v-model="name" placeholder="输入姓名">
    		<button @click="submit">提交</button>
  		</div>
	</template>
<script>
  		import vmVue from "@/pages/vmVue"
  		export default {
    		name: "tem-1",
    		data(){
      			return {
        			name: ""
      			}
    		},
    		methods: {
      		submit(){
        		vmVue.$emit("onName", this.name)
      		}
    	}
  	}
	</script>

**Temp-2.vue文件**
<template>
<div>
    	<input v-model="phone">
    	<p>姓名:{{name || "-"}}</p>
    	<p>手机:{{phone || "-"}}</p>
	</div>
</template>
<script>
	import vmVue from "@/pages/vmVue"
  	export default {
    	name: "tem-2",
    	data(){
      		return {
        		name: "",
        		phone: ""
      		}
    	},
    	mounted () {
      		vmVue.$on("onName", (val) => {
        		this.name = val
      		})
    	}
	}
</script>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值