vue面试题
2020-06-16 10:34:49 0 举报
AI智能生成
vue的面试题,基础必会内容
作者其他创作
大纲/内容
vue基础使用
基本使用
模板(插值,指令)
插值、表达式
{{message}}
{{flag ? "hello" : "world"}}
指令、动态属性
指令
v-html
v-if
v-bind
v-show
...
动态属性
:id="user_id"
user_id存在于data当中
v-html会存在xss风险,会覆盖子组件
computed和watch
watch监听
watch处于浅监听的状态,如果监听的数据是引用类型,是拿不到oldValue(虽然oldval和newval是两个变量,但是却因为是引用类型,指向的都是堆的地址)
监听不支持异步,数据发生变化,就会直接出发监听函数。
一般监听函数存在两个值,一个是之前的值,一个是新的值
如果一个属性发生变化,需要执行对应的操作,建议使用监听函数
开启深度监听
user: {
handler (oldval, newval) {
console.log(oldval, newval)
},
deep: true // 开启深度监听
}
handler (oldval, newval) {
console.log(oldval, newval)
},
deep: true // 开启深度监听
}
用法
watch: {
user: { handler(oldval, newval) {}, deep: true }
}
user: { handler(oldval, newval) {}, deep: true }
}
watch: {
user(oldval, newval) {}
}
user(oldval, newval) {}
}
computed计算属性
计算属性不支持异步,数据会默认走缓存,只有当依赖的数据发生变化的时候,才会触发计算属性
计算属性本身并不支持异步,如果存在异步,则无法监听变化
如果一个属性依赖于其他的属性(例如由其他属性计算而来),那么就可以使用计算属性
当computed为一个函数的时候,默认会走get方法。返回值就是属性的属性值
如果是一个对象,则可以手动的设置get和set方法,当修改数据的时候就会触发set方法
computed: {
mynum1: function () {
return this.num * 2
},
mynum2: function () {
return this.num * 2
},
mynum3: { // 如果要设置get和set,需要设置为对象而不是一个函数
get: function () { return this.num * 2 },
set: function (newVal) { return this.num * newVal }
}
}
mynum1: function () {
return this.num * 2
},
mynum2: function () {
return this.num * 2
},
mynum3: { // 如果要设置get和set,需要设置为对象而不是一个函数
get: function () { return this.num * 2 },
set: function (newVal) { return this.num * newVal }
}
}
class和style
动态的类
<div :class="{ base: isBase, bg: isbg }"></div>
<div :class="[base, bg]"></div>
<div :style="baseData"></div>
data
data () {
return {
baseData: {
width: '100px',
height: '200px',
'backgroundColor': 'red'
},
base: 'base',
bg: 'bg',
isBase: true,
isbg: true,
}
}
return {
baseData: {
width: '100px',
height: '200px',
'backgroundColor': 'red'
},
base: 'base',
bg: 'bg',
isBase: true,
isbg: true,
}
}
条件
v-if
<b v-if="status === 'A'">aaaa</b>
<b v-else-if="status === 'B'">bbbb</b>
<b v-else>cccc</b>
<b v-else-if="status === 'B'">bbbb</b>
<b v-else>cccc</b>
v-show
<b v-show="status==='A'">aaaaa</b>
<b v-show="status==='B'">bbbbb</b>
<b v-show="status==='B'">bbbbb</b>
v-if和v-show的区别
v-show本质来说就是在一个节点上设置display,从而做到让元素显示或者隐藏
v-if条件为true,才会创建节点,false则会销毁节点
二者的使用场景
如果节点的操作切换频率比较高,那么从效率的角度考虑应该使用v-show,其他时候应该使用v-if
循环
v-for
需要设置key
key不能乱写,应该是一个与业务相关的值
不能在一个节点上和v-if共同使用,如果需要判断,可以放在父节点上
事件
event对象
在节点上绑定事件,如果在事件处理函数上没有传递参数,那么默认函数的第一个参数表示的就是event对象
而切这个对象是原生的js对象
但是如果在节点上绑定事件处理函数的时候传递了参数,那么就需要显示的传递event参数,参数为$event
常用属性
event.target事件在哪里监听
event.currentTarget事件在哪里触发
事件修饰符
.stop
.prevent
.capture
添加事件监听器时使用事件捕获模式
.self
只有event.target是当前自身元素时才会触发事件处理函数
Tip:
修饰符可以串联使用
例如 .stop.prevent
按键修饰符
.ctrl
.ctrl.exact
有且仅有ctrl键按下的时候才触发
@click.exact
没有任何系统修饰符被按下时才触发
表单
v-model
语法糖
相当于@input和:value
表单项
常见表单项
textarea
checkbox
radio
select
修饰符
lazy
将input事件变为change事件
number
trim
组件使用
生命周期
组件周期
创建
beforeCreate
组建的data和el还没有被创建
created
data存在,但是el还没创建
挂载
beforeMount
el创建完毕,但是data还没有被渲染到组件中
mounted
组件挂在完毕,数据渲染完毕
更新
beforeUpdate
updated
销毁
beforedestory
一般都会在销毁阶段取消一些事件处理函数或者一些其他的操作,从而形成操作的闭环
destoryed
created和mounted之间发生的事
检测是否存在el
检测template
父子组建的生命周期
每一个周期环节,先执行伏组件的第一步,然后子组建走完,父组件走完
例如
父beforecreate->子beforecreate->子created->父created
组件通讯方式
props和$emit
$parent或者$root 事件派发
this.$parent.$emit('事件',值)
this.$parent.$on('监听')
$bus
$refs
$parent和$children
provide和inject
vuex
props(类型和默认值)
props:['a','b']
props: {
user: {
type: String,
default: ""
}
}
user: {
type: String,
default: ""
}
}
default也可以是一个函数,return返回默认值
v-on和$emit
自定义事件
$bus.$emit('事件')
$bus.$on(‘事件’)
$bus.$off('事件')
vue-cli
vue create 项目名称
npm run serve
npm run build
vue高级特性
自定义v-model
子组件
model: {
prop: props里面接受的属性,
event:事件,需要和$emit发送的事件对应起来
}
prop: props里面接受的属性,
event:事件,需要和$emit发送的事件对应起来
}
props: {
接受的属性: 类型
default 默认值,可以是函数也可以是一个值
}
接受的属性: 类型
default 默认值,可以是函数也可以是一个值
}
$nextTick
需要了解
vue是异步渲染
data改变之后,dom不会立刻渲染
$nextTick会在dom渲染之后触发,获取最新dom节点
页面渲染时会将data的修改整合,多次的data修改只会渲染一次
使用
通过$nextTick触发异步渲染完的回调
this.$nextTick(() => {
let ul = this.$refs.ul
console.log(ul.children.length)
})
let ul = this.$refs.ul
console.log(ul.children.length)
})
refs
this.$refs.组件ref的值就可以获得该组件
slot
匿名插槽
作用域插槽
具名插槽
动态组件
场景
当我们在开发的过程中不能确定到底使用哪个组件的时候,可以使用动态组件
根据实际的业务变化来动态的切换组件
使用
<component :is="my"></component>
my是data当中的一个数据,可以动态的发生变化,当my的值发生变化后,组件也会被切换
异步组件
场景
当组件单个过大的时候,为了避免阻塞就可以使用异步组件的加载方式
异步加载可以提高首屏响应速度
使用方式
通过import()函数
components: {
// MyTest3
MyTest3: () => import('./components/MyTest3')
}
// MyTest3
MyTest3: () => import('./components/MyTest3')
}
keep-alive
场景
当切换组件的时候,前一个组件就会被销毁,当再次切换回来的时候,组件就会重新创建,之前的状态就会消失,恢复初始状态
如果希望组件在切换的时候不去销毁或者说保持组件的状态,那么就可以使用keep-alive
当处于频繁切换组件的时候,也可以使用,这样能够避免重复渲染
简单的应用场景可以使用v-show,复杂一点的可以使用keep-alive
使用方式
<keep-alive>组件</keep-alive>
mixin
场景
当多个组件存在相同的逻辑时,可以通过mixin将代码抽离出来
问题
mixin并不是完美的,也同样存在着一些问题
变量来源不明确,可读性差
多个mixin可能造成命名冲突
mixin和组建可能产生多对多的关系,复杂度较高
vue3的解决方案
vue3提出的Composition API旨在解决这个问题
使用
export default {
data() {
return {
hello: '这是mixin1 里面的hello属性',
}
},
}
data() {
return {
hello: '这是mixin1 里面的hello属性',
}
},
}
父组件中引入mixin,然后在mixins里面注册
mixins: [Mixin1],
注意
mixin引入并且注册后,里面的数据,方法等一系列的东西都会和当前组建相对应的内容进行合并,如果发生命名冲突,则会产生覆盖
vue周边
vuex
状态管理工具
关键点
state
getter
action
mutation
用于vue
dispatch
调用mutation里面的方法
commit
调用mutation里面的方法
mapState
mapGetters
mapActions
mapMutations
vue-router
路由模式
hash
history
需要服务端支持。没有特殊情况的,建议选择hash模式
页面导航
router-link
通过to属性实现跳转地址的设置
router-view
路由匹配的组建将会渲染在这里
$router和$route
$router
是VueRouter的一个实例对象,通过Vue.use(VueRouter)和vue的构造函数得到一个router的实例对象
这个对象是一个全局对象,包含所有的路由,包含了许多关键的对象和属性。
使用
跳转到不同的地址
this.$router.push({path:`/user/${userId}`})
路由中的配置
{
path: '/user/:userId',
name: '***',
component: ***
}
path: '/user/:userId',
name: '***',
component: ***
}
这种接收参数的方式是this.$route.params.userId。
使用params传递参数
this.$router.push({name:'Login',params:{id:'leelei'}})
使用query传递参数
this.$router.push({path:'/login',query:{id:'leelei'})
//带查询参数变成 ip/login?id=leelei
//带斜杠/代表从根目录出发,不会嵌套之前的路径
//带查询参数变成 ip/login?id=leelei
//带斜杠/代表从根目录出发,不会嵌套之前的路径
query传参是针对path的,params传参是针对name的。。接收参数的方式都差不多。。this.和route.params.
返回上一层
$router.go()
需要注意的事
使用query传参的话,会在浏览器的url栏看到传的参数类似于get请求,使用params传参的话则不会,类似于post请求。
如果提供了path,params将会被忽略(即如果要使用params传参,则一定要使用name),但是query不属于这种情况。如果使用完整路径和query传参,刷新页面时不会造成路由传参的参数丢失。
router.push和router.replace的区别是:replace不会向 history 添加新记录,而是替换掉当前的 history 记录,即使用replace跳转到的网页‘后退’按钮不能点击。
$route
route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等
动态路由
在地址的后面设置参数
{ path: '/user/:userId', component: User}
接收参数:
this.$route.params.userId
路由懒加载
通过import函数来加载
嵌套路由
可以通过children属性来设置嵌套路由
children的值是一个数组,在数组当中每一条嵌套的路由规则都是一个对象
0 条评论
下一页