Vue十五个常见面试题(一)
1. 父子组件之间如何传值?
父传子:通过
props
进行传值
①传递静态值
//父组件
<template>
<div id="app">
<child message="hello"></child>
</div>
</template>
<script>
import child from './components/Child'
export default {
name: "app",
components:{
child
}
}
</script>
//子组件
<template>
<div>
<h2>{{message}}</h2>
</div>
</template>
<script>
export default {
props: ["message"] //使用props接受父组件的值
}
</script>
②传递动态值:把上述父组件修改成如下即可。
//父组件
<template>
<div id="app">
<child :message="parentMsg"></child>
</div>
</template>
<script>
import child from './components/Child'
export default {
name: "app",
data() {
return {
parentMsg:'hello,world!'
}
},
components: {
child
}
}
</script>
子传父:通过
$emit
来调用父组件的方法并传递数据
//子组件
<template>
<div>
<button @click="sendMsgToParent">向父组件传值</button>
</div>
</template>
<script>
export default {
methods: {
sendMsgToParent:function () {
this.$emit("childMsg","hello world!");
}
}
}
</script>
//父组件
<template>
<div id="app">
//@childMsg 与子组件中this.$emit("childMsg","hello world!")起的名字一致
<child @childMsg="showChildMsg"></child>
</div>
</template>
<script>
import child from './components/Child'
export default {
name: "app",
components: {
child
},
methods:{
showChildMsg:function (data) {
console.log(data);
}
}
}
</script>
2. 父子组件之间如何相互使用对方的方法与属性?
父组件调用子组件:
$children
和$refs
- 使用
$children
:返回的是一个数组类型,它包含所有子组件对象。 - 使用
$refs
:通过$children
访问子组件时,是一个数组类型,访问其中的子组件必须通过索引值。当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至还可能会发生变化。想明确获取其中一个特定的组件,这个时候就可以使用$refs
。
子组件调用父组件:
$parent
整合示例如下:
//父组件
<template>
<div id='parents'>
<p>我是父组件
<button @click="click1hanlde">获取子组件1的数据与方法</button>
<button @click="click2hanlde">获取所有子组件的数据和方法</button></p>
<children1 ref="children1"></children1>
<children2 ref="children2"></children2>
</div>
</template>
<script>
import children1 from './children1.vue'
import children2 from './children2.vue'
export default {
components:{
children1,
children2
},
data() {
return {
ParentData:'AAA'
};
},
methods:{
click1hanlde(){
console.log(this.$refs.children1.children_data)
this.$refs.children1.children_fun();
},
click2hanlde(){
for(let i=0;i<this.$children.length;i++){
console.log(this.$children[i].children_data);
this.$children[i].children_fun();
}
},
showParentData(){
console.log(this.ParentData)
}
}
};
</script>
//子组件1
<template>
<div id='children1'>
<p>我是子组件1: <button @click="getParent_fun">获取父组件的数据和方法 </button></p>
</div>
</template>
<script>
export default {
data() {
return {
children_data:'children_data1',
};
},
methods:{
children_fun(){
console.log('我是子组件1的方法')
},
getParent_fun(){
this.$parent.showParentData();
}
}
};
</script>
//子组件2
<template>
<div id='children2'>
<p>我是子组件2</p>
</div>
</template>
<script>
export default {
data() {
return {
children_data:'children_data2',
};
},
methods:{
children_fun(){
console.log('我是子组件2的方法')
}
}
};
</script>
注意:不会存在多个父组件共用一个子组件的情况。如果多个父组件引用相同子组件的话,实际上是每个父组件下都实例化了一个相同的子组件。
3. 爷孙组件之间如何通信?
爷孙组件是没有办法直接通信的,但是它们可以分解为两个父子组件通信,即爷爷和父亲看成是一个父子组件, 而父亲和孙子看成是一个父子组件。这样它们之间就可以进行通信了。
4. 兄弟组件之间如何通信?
- 使用Vuex
关于Vuex的具体使用,可见文章Vuex 使用详解 。
- 创建一个事件总线(eventbus):使用
$on
和$emit
进行传值
因为$on
和$emit
的事件必须是在一个公共的实例上才能触发。那么新建一个Vue 实例当作事件总线,达到兄弟组件之间如何通信的目的:
首先新建一个eventBus.js:
import Vue from 'vue'
export default new Vue()
component1.vue 里监听事件:
import eventBus from './eventBus'
created () {
eventBus.$on('my-event', args => {
})
}
component2.vue 中触发事件:
import eventBus from './eventBus'
watch: {
list(newValue, oldValue) {
eventBus.$emit('my-event', newValue)
}
}
5. Axios是什么,描述使用它实现登录功能的流程。
- Axios是一个基于ES6 Promise的HTTP 库,支持Promise所有的API
- 它可以拦截请求和响应
- 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成JSON 类型的数据
- 安全性更高,客户端支持防御XSRF
实现登录流程:
- 第一次登录的时候,前端调后端的登陆接口,使用
axios
发送用户名和密码
- 后端收到请求,验证用户名和密码,验证成功,就给前端返回一个
token
- 前端拿到
token
,将token
存储到localStorage
中,并跳转路由页面
然后进行完善:
- 前端每次跳转路由,都要判断
localStroage
中有无token
,没有就跳转到登录页面,有则跳转到对应路由页面
- 后端拿到token后要进行验证,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401。
- 如果前端拿到状态码为401,就清除token信息并跳转到登录页面
6. Vuex 是什么?怎么使用?哪种功能场景使用它?
Vuex 是一个专门为Vue 构建的状态集管理,为了解决组件间状态共享的问题。本质上是存储共享数据的仓库。
不是所有的项目都适合用Vuex,如果不是构建大型项目,使用Vuex 反而使你的代码繁琐多余。
Vuex核心为:
state
、mutations
、getters
、actions
、modules
7.导航钩子有哪些?它们有哪些参数?
导航钩子(导航守卫):翻译过来就是路由的生命周期函数,主要分为全局的钩子函数和局部的钩子函数。
- 全局的钩子函数
beforeEach
:在路由切换开始时调用
afterEach
:在路由切换离开时调用
- 局部的钩子函数
局部到单个路由:
beforeEnter
组件的钩子函数:beforeRouterEnter
、beforeRouterUpdate
、beforeRouterLeave
示例:
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = () => import('../views/home/Home');
const Login = () => import('../views/category/Login');
Vue.use(VueRouter);
const routes = [
{
path: '/home',
name: '/home',
component: Home
// 局部到单个路由钩子函数
beforeEnter: function(){
}
},
{
path: '/login',
name: '/login',
component: Login
}
];
const router = new VueRouter({
routes:routes
});
// 路由全局钩子函数
router.beforeEach((to,from,next)=>{
// to:即将进入的目标对象
// from:当前导航要离开的导航对象
// next:是一个函数调用resolve 执行下一步
})
8. 说出4个Vue 当中常用的指令和它的用法。
-
v-if
:条件渲染指令,代表存在或者销毁 -
v-bind
:绑定指令,用来绑定属性(语法糖是:
) -
v-on
:监视事件指令(语法糖是@
) -
v-for
:循环指令
<ul>
<li v-for="data in datalist">{{data}}</li>
</ul>
9. v-model是什么?Vue中标签怎么绑定事件?
Vue 利用v-model来进行表单数据的双向绑定,实际上,它做了两个操作:利用v-bind
,绑定一个value
属性;利用v-on
把当前元素绑定到一个事件上。
10. Vue 生命周期函数是哪些?(主要考察的是Vue 实例创建过程)
Vue 生命周期分为四个阶段,8个函数。
- 组件创建时(creating):
beforeCreate
、created
- 模板渲染时(mounting):
beforeMount
、mounted
- 数据更新时(updating):
beforeUpdate
、updated
- 组件销毁时(destroying):
beforeDestroy
、destroyed
后面题目见 Vue十五个常见面试题(二)