欢迎参加2023年的Vue面试。以下是40道关于Vue的面试题,每道题附带有详细的答案和代码讲解。
请解释Vue.js是什么。它的核心功能是什么?
Vue.js是一款流行的JavaScript前端框架,用于构建用户界面。它的核心功能是通过封装了核心库和插件生态系统,实现了声明式渲染、组件化开发和响应式数据绑定。
请解释Vue的双向数据绑定原理。
Vue的双向数据绑定是通过Vue的响应式系统实现的。当数据发生改变时,Vue会自动识别到这一变化,并将变化的数据同步到视图中。同时,当用户与视图交互时,Vue也能够将用户的输入动态地反映到数据上。
代码讲解
你输入的文字是:{{ message }}
在上述示例中,我们使用v-model指令实现了双向数据绑定。元素的值会自动与message数据属性进行双向绑定,任何对message数据的更改都会同步到输入框中,反之亦然。
定义一个Vue组件可以通过Vue.component方法。
代码讲解
<template id="hello-template">
<div>
<h2>Hello {{ name }}!</h2>
<button @click="greet">Greet</button>
</div>
</template>
<script>
Vue.component('hello', {
template: '#hello-template',
data() {
return {
name: 'Vue'
}
},
methods: {
greet() {
alert('Hello!')
}
}
})
</script>
在上述示例中,我们定义了一个名为Hello的Vue组件。该组件的模板是通过外部的元素定义的,将其内容作为组件的模板。该组件还定义了一个name数据属性和一个greet方法,可以在模板中使用。
v-if会根据表达式的真假来动态添加或删除元素,而v-show则只是控制元素的显示与隐藏。
代码讲解
<div id="app">
<button @click="toggle">Toggle</button>
<p v-if="visible">这是一个可见的段落。</p>
<p v-show="visible">这是另一个可见的段落。</p>
</div>
<script>
new Vue({
el: '#app',
data: {
visible: true
},
methods: {
toggle() {
this.visible = !this.visible
}
}
})
</script>
在上述示例中,我们使用v-if和v-show指令根据visible数据属性的真假来控制两个段落元素的可见性。点击按钮后,visible的值将被取反,从而触发条件渲染。
代码讲解
<div id="app">
<button @click="handleClick">点击我</button>
<input @input="handleInput" placeholder="输入一些文字">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: ''
},
methods: {
handleClick() {
alert('按钮被点击!')
},
handleInput(event) {
this.message = event.target.value
}
}
})
</script>
在上述示例中,我们使用@click指令监听按钮的点击事件,并在handleClick方法中弹出提示框。另外,我们还使用@input指令监听输入框的输入事件,并在handleInput方法中更新message数据。
代码讲解
<div id="app">
<button @click="fetchData">获取数据</button>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
new Vue({
el: '#app',
data: {
items: []
},
methods: {
fetchData() {
// 使用vue-resource发送GET请求
this.$http.get('/api/data')
.then(response => {
this.items = response.data
})
.catch(error => {
console.error(error)
})
}
}
})
</script>
在上述示例中,我们使用vue-resource库发送GET请求,并在请求成功后将返回的数据赋值给items数组。这样,我们就可以在模板中使用v-for指令渲染出数据列表。
常用的生命周期钩子函数有:beforeCreate、created、mounted、updated和destroyed等。
代码讲解
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
mounted() {
console.log('mounted')
},
updated() {
console.log('updated')
},
destroyed() {
console.log('destroyed')
}
})
</script>
在上述示例中,我们通过控制台打印来展示每个生命周期钩子函数被调用的顺序。你可以在浏览器的开发者工具中查看输出结果。
computed是基于它的依赖进行缓存的,只有当依赖的数据发生变化时,才会重新计算,而不是每次访问时都重新计算。
watch是观察一个特定的数据,并在数据发生变化时执行回调函数。它更适合处理一个数据变化时需要执行异步或开销较大的操作。
代码讲解
<div id="app">
<input v-model="message" placeholder="输入一些文字">
<p>你输入的文字是:{{ message }}</p>
<p>计算属性:{{ reversedMessage }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: ''
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('')
}
},
watch: {
message(newValue, oldValue) {
console.log(`message 发生变化:${oldValue} → ${newValue}`)
}
}
})
</script>
在上述示例中,我们定义了一个计算属性reversedMessage,用于将message的内容进行反转。当用户输入文字时,message会发生变化,reversedMessage将重新计算并显示。同时,我们使用watch来观察message的变化并打印出变化的值。
要配置路由,我们需要引入vue-router库,并根据页面需求定义一组路由规则。
代码讲解
<div id="app">
<router-link to="/home">主页</router-link>
<router-link to="/about">关于</router-link>
<router-view></router-view>
</div>
<script>
const Home = { template: '这是主页' }
const About = { template: '这是关于页面' }
const routes = [
{ path: '/home', component: Home },
{ path: '/about', component: About }
]
const router = new VueRouter({
routes
})
new Vue({
el: '#app',
router
})
</script>
在上述示例中,我们通过标签创建了两个导航链接,指向主页和关于页面。使用标签来显示当前激活的组件。
代码讲解
<div id="app">
<p>计数器:{{ count }}</p>
<button @click="increment">增加</button>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
new Vue({
el: '#app',
store,
computed: {
count() {
return this.$store.state.count
}
},
methods: {
increment() {
this.$store.commit('increment')
}
}
})
</script>
在上述示例中,我们创建了一个简单的计数器,并使用vuex进行状态管理。我们通过this. s t o r e . s t a t e 来获取状态,通过 ‘ t h i s . store.state来获取状态,通过`this. store.state来获取状态,通过‘this.store.commit`来提交变更。
在使用动态组件时,我们通过元素和is特性来指定要渲染的组件。
代码讲解
<div id="app">
<button @click="toggle">切换组件</button>
<component :is="currentComponent"></component>
</div>
<script>
const ComponentA = { template: '组件A' }
const ComponentB = { template: '组件B' }
new Vue({
el: '#app',
data: {
currentComponent: 'ComponentA'
},
methods: {
toggle() {
this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA'
}
},
components: {
ComponentA,
ComponentB
}
})
</script>
在上述示例中,我们通过点击按钮来切换ComponentA和ComponentB组件的展示。点击按钮会触发toggle方法,动态更改currentComponent的值。
代码讲解
<div id="app">
<button @click="toggle">切换</button>
<transition name="fade">
<p v-if="visible">这是一个带有过渡效果的段落。</p>
</transition>
</div>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
<script>
new Vue({
el: '#app',
data: {
visible: false
},
methods: {
toggle() {
this.visible = !this.visible
}
}
})
</script>
在上述示例中,我们使用元素包裹要过渡的元素,并添加了一个name特性,用于指定过渡效果名字。通过指定fade-enter-active、fade-leave-active、fade-enter和fade-leave-to这四个CSS类,我们定义了一个渐变的过渡效果。