【面试】Vue基础

Vue基础


1.差值表达式可以放值和表达式

{{message}}
{{if(flag)?yes:no}}

2.v-html

​ 会将其子元素覆盖,有xss攻击风险。

3.computed与watch的区别

computed有缓存;watch没有

computed: {
  now: function () {
    return Date.now()
  }
}

computed是用来属性直接计算,而watch是监听属性的。

比如姓和名组成名字

computed:{
	姓名:function(){
		return 姓+名
	}
}
watch:{
	姓:function,
	名:function
}

watch还有几个属性

watch:{
	某属性:{
		handler:fun => 改变时会执行的函数
		immediate: true/false(默认) =>是否一刷新就执行handler
	}
}

4.watch如何监听引用类型

​ 要用深度监听,但引用类型是拿不到oldValue的

user:{
	name:'xxx',
	info:{
		age:'222',
		city:'xxx',
		...
	}
}

watch:{
	info:{
		handler(o,v){
			watch info
		}
		deep:true
	}
}

5.v-if 和v-show有什么区别

v-if可以跟v-else配合使用

v-if="false"的时候 会将组件从DOM树上移除,更新不频繁的时候用。

v-show="false"的时候会将组件display属性设置为none

只是隐藏显示组件的话,还可以使用动态组件

6.v-for

遍历对象

<li v-for="(item,index) in List" :key="唯一的值就行">{{item}}</li>

如果要使用v-if 在li的父元素上用,不要在li上用。

List可以是数组、对象

7.事件

<div @click="noParam">不带形参</div>
<div @click="haveParam(123,$event)">带形参</div>
methods: {
		noParam(e) {
			console.log(e.target)
		},
		haveParam(num) {
			console.log(num, event.target)
		},
}

8.父子组件通信

props和$emit

const TestComponent = {
	name: "TestComponent",
	props: ["count"],
	emit: ["update:count"],
	methods: {
		handleClick() {
			this.$emit("update:count", this.count + 1)
		},
	},
	template: `<div>
					<p @click="handleClick">{{count}}</p>
				</div>`,
}
const app = Vue.createApp({
	components: { TestComponent },
	data() {
		return {
			count: 1,
		}
	},
	template: `
				<div>
					<test-component v-model:count="count" />
				</div>`,
})
const vm = app.mount("#root")

自定义事件

<sub-component @myevent="handleEvent"></sub-component>

//in sub-component
this.$emit("myevent",param)
//in app
handleEvent(param){
	//do sth
}

另一种方法,event.js

return new Vue()
import event from "event.js"
//in sub-component
event.$emit("myevent",param)
//在app的mounted()里绑定
event.$on("myevent",this.handleEvent)
//记得在销毁组件的时候,解绑自定义事件,否则会造成内存泄漏
beforeDestroy(){
	event.$off("myevent",this.handleEvent)
}

9.组件生命周期

单个组件:4个阶段,8种。

/*
生成vue实例
*/
//生成之前
beforeCreate() {
	console.log("beforeCreate->", root.innerHTML)
},
//生成之后
created() {
	console.log("create->", root.innerHTML)
},
/*
 编译template(若有)/编译innerHTML
*/
//将页面内容替换为template之前
beforeMount() {
	console.log("beforeMount->", root.innerHTML)
},
//将页面内容替换为template之后
mounted() {
	console.log("mounted->", root.innerHTML)
},
/*
   数据更新
*/
//更新数据,但页面更新之前
beforeUpdate() {
	//在控制台更改数据
	//vm.$data.message="xxx"
	console.log("beforeUpdate->", root.innerHTML) //<p>hello world</p>
},
//页面更新之后
updated() {
	console.log("updated->", root.innerHTML) //<p>xxx</p>
},
/*
卸载vue实例
*/
//卸载但更新之前
beforeUnmount() {
	//在控制台使用
	//app.unmound()
	console.log("beforeUnmount->", root.innerHTML) 
	//<!-- template --><div><p>hello world</p></div><!-- /template -->
				},
	//更新之后
unmounted() {
	console.log("unmounted->", root.innerHTML) //空
},
})
const vm = app.mount("#root")

其中beforeUnmount对应beforeDestroyed,unmounted对应destroyed

父子组件:事件从外到内,渲染从内到外

父 beforeCreate
父 created
父 beforeMount
子 beforeCreate
子 created
子 mounted
父 mounted
父 beforeUpdate
子 beforeUpdate
子 updated
父 updated
父 beforeDestroyed
子 beforeDestroyed
子 destroyed
父 destroyed

10.高级特性

1.插槽

三种

匿名插槽

const UnnamedComponent = {
				name: "UnnamedComponent",
				methods: {},
				template: `<slot>默认值</slot>`,
}

具名插槽

const NamedComponent = {
				name: "NamedComponent",
				template: `
				<slot name="header"></slot>
					<div>conent</div>
				<slot name="footer"></slot>
					`,
}

作用域插槽:父组件能够调用子组件的数据

const ScopeComponent = {
				name: "ScopeComponent",
				data() {
					return {
						list: ["a", "b", "c"],
					}
				},
				template: `
				<slot v-for="item in list" :item="item"/>

				`,
}
//in app template
<div>
					<unnamed-component>
						<div>
							我是插槽里的内容
							{{count}}
						</div>
					</unnamed-component>
					<unnamed-component></unnamed-component>
					<named-component>
						<template v-slot:header><div>header</div></template>
						<template v-slot:footer><div>footer</div></template>
					</named-component>
					<scope-component v-slot="list">
						<span>{{list.item}}</span>
					</scope-component>
</div>`

2.动态、异步组件

动态组件是不确定要渲染的是什么组件,所以用component :is=“组件名”,先占个坑。

const OneComponent = {
				neme: "OneCompontent",
				template: `<div>我是OneComponent</div>`,
			}
			const TwoComponent = {
				neme: "TwoCompontent",
				template: `<div>我是TwoComponent</div>`,
			}
			const app = Vue.createApp({
				components: { OneComponent, TwoComponent },
				data() {
					return {
						currentItem: "one-component",
					}
				},
				methods: {
					handleClick() {
						if (this.currentItem === "one-component") {
							this.currentItem = "two-component"
						} else {
							this.currentItem = "one-component"
						}
					},
				},
				template: `
               <component :is="currentItem"/>
                <button @click="handleClick">切换</button>
                `,
			})
			const vm = app.mount("#root")

可以使用keep-alive保留动态属性的内容

异步组件,引入的时候

compontents:{
	asyncComponent:()=>{import("./组件的位置")}
}

3.$nectTick(组件更新后,如何获取最新的DOM)

在数据更新后,获得更新的DOM节点

给你想要监控的dom节点添加ref属性

<ul ref="ul">

进行数据更新操作(比如添加/删除一个li)后输出

this.$refs.url.childNodes

发现获取到的是操作前的dom节点

this.$nextTick(()=>{
	使用 this.$refs.url.childNodes
})

就行了

4.keep-alive(缓存组件)

将组件用包裹,可以和动态组件配合使用。使组件不会重复渲染(重复执行mounted)

5.自定义v-model

<input v-model="inputVlue"/>

的本质其实是

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

所以 父组件正常使用v-model

子组件

<input :value="inputValue"
		@input="$emit('change',$event.target.value)"/>
//子组件内部
props:[inputValue],
model:{
	prop:'inputValue',
	event:'change'
}

6.mixin(抽离公共逻辑)

Composition API也可以实现

mixins:[组件名]

会将引入的组件的内容与当前组件的内容混合。

可以将公共逻辑抽离在另一个组件中,使用时引入就行。

缺点:命名冲突、多对多关系

7.vuex

状态管理

设置想要管理的值

store->index.js
state:{
	name:'aaa'
}

在其他组件使用这个值

this.$store.state.name

修改这个值

//其他组件里
this.$store.dispatch("changeName",name)
//store->index.js里
actions: {
    changeName(ctx,name) {
      ctx.commit("handleChangeName", name)
    }
  },
mutations: {
    handleChangeName(state, name) {
      state.name = name
    }
  },
 

或者,跳过action

this.$store.commit("handleChangeName",name)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值