博主:_LJaXi Or 東方幻想郷
专栏: 前端面试题
开发工具:Vs Code
本题针对
Vue2
这些几乎把常用的都包括了,问别的就没意思了,毕竟工作拧螺丝嘛
我都好久不用Vue了,不过用了React再回看Vue感觉好简单啊…
其实工作上都很快能捡起来,就是面试问题是必须的(啥时候能结束这种无聊的面试问题环节啊…)接着往下看吧
面试官您好,我叫 ***,今年 ** 岁
目前在前端领域上有一定的工作经验,之前在 ** 公司 以及 ** 公司就职web前端 / 后端工程师
主要负责的项目有 *** 项目,*** 项目
主要负责了**模块开发
我的兴趣爱好是写博客,喜欢把自己工作遇到的问题或一些知识记录在博客中充实自己 | (根据自己的实际情况介绍爱好)闲暇之余也会 *******
今天来到贵公司面试深感荣幸,希望今后能与大家一起共事,自我介绍完毕,谢谢!
面试主打 真实情感,以及让面试官快速了解到你的基本情况,emm,其余的不便多说,看运气吧
父传子
或子传父
我们项目中常用到这两个功能,注意,父传子
传递数据为单向数据流传输,由props
接收
子传父
即是使用自定义事件实现的数据回调,这两个数据流是不同的
App.vue 父组件
<template>
<div id="app">
<HelloWorld msg="我是父组件传过来的值,用props接收~"/>
div>
template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
script>
HelloWorld.vue 子组件
<template>
<div class="hello">
{{ msg }}: props: { msg: String }
div>
template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
script>
父传子: 我们在父组件中引入子组件,然后通过子组件标签定义一个用于子组件可接收的变量
msg
= “我们要传递的值
”
然后再子组件中使用props
接收父组件中传递过来的变量,这就是父传子,可传递任意参数
HelloWorld.vue 子组件
<template>
<div class="hello">
<button @click="sonGiveFatherValue">传递数据给父组件button>
div>
template>
<script>
export default {
name: 'HelloWorld',
methods: {
sonGiveFatherValue() {
const data = '我是传递给父组件的一个字符串'
this.$emit('shuju', data)
}
}
}
script>
App.vue 父组件
<template>
<div id="app">
<HelloWorld @shuju="childData"/>
<div>接收子组件的数据: {{fatherOfChildValue}}div>
div>
template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
data() {
return {
fatherOfChildValue: ''
}
},
components: {
HelloWorld
},
methods: {
childData(val) {
this.fatherOfChildValue = val;
}
}
}
script>
子传父: 是不是顺序颠倒了,子传父,便于理解,先看子组件
举个例子,比如我们需要在父组件中添加一个按钮,但是点开按钮就是一个弹窗,这时候我们就可以把这个弹窗封装为一个子组件,正是因为封装,所以才会有的数据传输hhhh…
题外话
:Vue可是很好用的,至少比React的单向数据流好…
不闲扯,聊回正题,首先看
HelloWorld组件
我们需要把一个值,由子组件使用事件传递给父组件,注意点击事件下的this.$emit(传递的事件名,传递的值)
然后我们在父组件中的子组件标签中使用它
@shuju="childData"
这就是绑定一个自定义事件,然后事件参数就是你传递过来的那个值
主要看这两行你就能理解
<HelloWorld @shuju="childData"/>
<script>
childData(val) {
this.fatherOfChildValue = val;
}
script>
像我这种过目即忘但是会写的人,回顾面试题确实是有些痛苦的…
在实例初始化之前调用,此时组件的选项还未初始化
在实例创建完成后调用,
此时已经完成数据观测、属性和方法的运算
,但尚未生成真实的 DOM 并完成挂载
在组件挂载之前调用,此时已经生成了真实的 DOM,
但尚未挂载到页面中
在组件挂载完成后调用,
此时组件已经被渲染到页面中
在数据变化导致重新渲染之前调用,
此时页面尚未重新渲染
在数据变化导致重新渲染之后调用,
此时页面已经重新渲染完成
在组件实例销毁之前调用,
此时组件尚未被销毁
在组件实例销毁后调用,
此时组件已经被销毁
computed是计算属性,是基于已有的属性计算得出的新属性,只要依赖的属性不发生变化,计算结果也不会变化。watch是观察者,用来监听数据的变化,当数据发生变化时,执行相应的操作
computed
示例
<template>
<div>
<h2>计算属性示例h2>
<input v-model="firstNumber" type="number" placeholder="输入第一个数">
<input v-model="secondNumber" type="number" placeholder="输入第二个数">
<p>两数之和: {{ sum }}p>
<p>两数之差: {{ difference }}p>
div>
template>
<script>
export default {
data() {
return {
firstNumber: 0,
secondNumber: 0
};
},
computed: {
sum() {
return parseInt(this.firstNumber) + parseInt(this.secondNumber);
},
difference() {
return parseInt(this.firstNumber) - parseInt(this.secondNumber);
}
}
};
script>
watch
示例
<template>
<div>
<h2>监听数据示例h2>
<input v-model="message" type="text" placeholder="输入消息">
<p>消息长度: {{ messageLength }}p>
div>
template>
<script>
export default {
data() {
return {
message: '',
messageLength: 0
};
},
watch: {
message(newMessage) {
// newMessage 为新的消息值
this.messageLength = newMessage.length;
}
}
};
script>
Vue的路由有2种模式:hash模式、history模式
hash
在hash模式下,URL中的路径会以#符号开始,这种模式在旧版浏览器中很常见。它通过监听URL中hash值的变化来实现路由切换
// 在路由配置中使用hash模式
const router = new VueRouter({
mode: 'hash',
routes: [
// 路由配置
]
})
history
history模式:
在history模式下,URL中的路径不包含#符号,看起来更加直观和美观。它使用HTML5的history API来实现路由切换
// 在路由配置中使用history模式
const router = new VueRouter({
mode: 'history',
routes: [
// 路由配置
]
})
params
参数是用于传递动态路由参数的,即在路由路径中定义的参数,如/user/:id
中的id
使用params
传递参数时,参数会被编码到URL中,例如:/user/1
query
参数则是用于传递查询参数的,它会被附加在URL的末尾以查询字符串的形式,如/user? id=1
使用query
传递参数时,参数会以键值对的形式拼接在URL后面。
params参数可以在路由组件中通过 r o u t e . p a r a m s 来获取,而 q u e r y 参数可以通过 route.params来获取,而query参数可以通过 route.params来获取,而query参数可以通过route.query来获取
编程式 params
data:{
username: ''
},
login() {
...
this.$router.push({
name: 'home', //注意使用 params 时一定不能使用 path
params: { username: this.username },
})
}
声明式
<router-link :to="{ name: 'home', params: { username: username } }">
编程式 query
data:{
username: ''
},
login() {
...
this.$router.push({
path: '/home',
query: { username: this.username },
})
}
声明式
<router-link :to="{ path: '/home', query: { username: username } }">
router
用来访问 Vue 中的路由实例,可以进行路由跳转和路由信息的获取。
route
用来访问当前路由的信息,包括路由路径、参数、查询等。
Vue 自定义指令 ✨ 博主: pingting_
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
调试工具:vue devtools (Vue开发工具)
Vuex就像眼镜:您自会知道什么时候需要它。
详看我的这篇博客: Vuex 状态管理 ✨
当使用Vue框架时,mixins提供了一种机制,可以在多个组件之间共享可重用的逻辑
通过使用mixins,可以将特定的属性、方法、计算属性、钩子函数等混合到多个组件中,从而实现代码的复用和组件的扩展。
在
src
目录下创建一个mixins
文件夹,文件夹下新建自己要定义的混入对象js
文件。使用对象的形式来定义混入对象,在对象中可定义与vue组件一样的data、components、created、methods 、computed、watch
等属性,并通过export
导出该对象.
export const pageMixin = {
data() {
return {
page: { // 分页信息
pageNo: 1, // 当前页
limit: 10, // 每页行数
total: 0, // 列表总数量
},
tableList: [], // 列表数据
loading: false, // 加载列表数据的Loading
PAGE_SIZES: [5, 10, 20, 30, 50, 100], // 每页行数列表,用于切换每页行数
LAYOUT: "total, sizes, prev, pager, next, jumper" // Element表格组件中使用的功能
}
},
methods: {
// 查询列表数据
queryList() {},
// 修改当前页
handleCurrentChange(pageNo) {
this.page.pageNo = pageNo;
this.queryList();
},
// 修改每页行数
handleSizeChange(limit) {
this.page.pageNo = 1;
this.page.limit = limit;
this.queryList();
},
},
}
mixin的使用
在需要调用的组件页面中引入 pageMixin.js
文件
import {pageMixin} from "@/mixins/pageMixin"
export default {
mixins: [ pageMixin ],
data() {
return {
}
}
}
Modal(模型) - View(视图) - ViewModal(视图模型)
视图
与模型层
分离,并引入中间层视图模型
在MVVM模式中,视图通过数据绑定方式与视图模型进行通信。这意味着当视图模型中的数据发生变化时,视图会自动进行更新
好处:
实现代码的可维护性、灵活性和可重用性,尤其在构建大型、复杂的用户界面时非常有用
在前端开发中,Vue.js提供了一个特殊的组件
,用于在组件树中缓存组件的实例,以便在切换组件时保留其状态。我们可以使用
来优化性能,减少不必要的组件销毁和重建操作
v-show
通过css display
控制显示和隐藏,v-if
组件真正的渲染和销毁,而不是显示和隐藏,频繁切换状态使用v-show
否则v-if
快速查找到节点,减少渲染次数,提升渲染性能
v-html //html
v-text //元素里要显示的内容
v-bind:data //绑定动态数据 :data
v-on:click //绑定事件 @click
v-for
v-if //条件渲染指令
v-model //双向绑定,用于表单
以下为常用的 Vue 修饰符
.prevent
阻止默认行为,即调用事件的 event.preventDefault() 方法。常用于阻止表单提交或链接跳转等默认行为。
.stop
停止事件冒泡,即调用事件的 event.stopPropagation() 方法。当一个元素上触发了某个事件时,该事件会向上冒泡,影响到父元素中相同类型的事件。使用 .stop 修饰符可以阻止事件继续向上冒泡。
.capture
使用事件捕获模式,即在捕获阶段触发事件,而不是在冒泡阶段。默认情况下,事件是在冒泡阶段触发的。
.self
只有当事件是由当前元素本身触发时才会触发事件处理程序。当事件在当前元素之外的子元素中触发时,事件处理程序不会被调用。
.once
只触发一次事件处理程序,即事件处理程序只会执行一次,之后就会被移除。
.passive
指示监听器永远不会调用 event.preventDefault()。这个修饰符用于提高页面滚动的性能。但要注意,一旦对同一个事件同时使用了 .passive 和 .prevent 修饰符,.prevent 将会被忽略。