1.script标签中的differ和async的区别
都是异步加载外部的JS脚本文件,不会阻塞HTML的解析
区别:
①:执行顺序。differ保证脚本按照在HTML中出现的执行顺序,一般是在HTML解析完后执行。而async则是谁先下载完谁先执行,async可能会阻断解析以执行脚本。
2.label标签的使用
用于提升表单的可用性和可访问性,把文本标签和相应的表单控件关联起来,用户点击标签时,自动跳转聚焦到相应的表单控件上。
①:包裹控件
<label>
用户名:
<input type="text" name="username">
</label>
②:通过for属性关联
<label for="username">用户名:</label>
<input type="text" id="username" name="username">
3.在vue组件如何访问根实例
①:使用provide/inject机制
可以在跟组件提供数据,然后在任意子组件使用
// 在根组件或 main.js 中提供数据
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.provide('appName', 'Vue3应用')
app.mount('#app')
// 或在根组件中
setup() {
provide('appName', 'Vue3应用')
}
// 选项式 API
export default {
inject: ['appName'],
mounted() {
console.log(this.appName) // Vue3应用
}
}
// 组合式 API
setup() {
const appName = inject('appName')
console.log(appName) // Vue3应用
}
②:使用全局属性
// main.js
const app = createApp(App)
app.config.globalProperties.$appName = 'Vue3应用'
app.mount('#app')
在组件中访问
// 选项式 API
export default {
mounted() {
console.log(this.$appName) // Vue3应用
}
}
// 组合式 API
import { getCurrentInstance } from 'vue'
setup() {
const internalInstance = getCurrentInstance()
console.log(internalInstance.appContext.config.globalProperties.$appName)
}
③:直接导入应用实例
// main.js
const app = createApp(App)
app.mount('#app')
export { app }
// 组件中
import { app } from '@/main'
setup() {
console.log(app.config.globalProperties.$appName)
}
***在vue2中,我们可以通过this.$root直接访问根实例。
***在vue3中,推荐使用provide/inject机制替换直接访问根实例
4.如何定义vue的动态路由,并获取传递过来的参数
①:定义动态路由
在Vue Router中,动态路由通常是指路径中包含可变部分的路由,这些可变部分通常用于传递参数。定义动态路由的方法是在路径中使用冒号标记参数。
const routes = [
// 动态路径参数以冒号开头
{ path: '/users/:id', component: UserComponent },
//?标记可选参数
{ path: '/users/:id?', component: UserComponent },
// 可以定义多个参数
{ path: '/users/:username/posts/:postId', component: UserPostComponent }
]
②:获取动态路由参数
- 选项式API中,通过this.$root.params访问
export default {
mounted() {
// 获取路由参数
console.log(this.$route.params.id)
}
}
- 组合式API中。使用useRoute函数获得路由对象,然后访问其params属性
import { useRoute } from 'vue-router'
export default {
setup() {
const route = useRoute()
// 获取路由参数
console.log(route.params.id)
}
}
- 在模板(template)中,直接使用$route.params访问
<template>
<div>User ID: {{ $route.params.id }}</div>
</template>
5.vue中的data属性能和methods中的方法名重名吗
不可以。因为他们最终都会被挂载到同一个组件实例上,共享同一个命名空间,如果重名,将会导致冲突。methods方法会覆盖掉data的同名属性。
- vue实例属性的优先级顺序:props>methods>data>computed。如果出现重命名的现象,则优先级高的会覆盖掉优先级低的。
- Vue前缀保留。Vue内部有一个带有特俗前缀的保留属性。如以$或_开头的属性,不会被代理到vue实例上,使用vm.$data._property访问这些属性
6.vue的自定义指令
允许我们对DOM底层进行操作。自定义指令通过v-前缀标识,用于元素插入到DOM后执行特殊操作。
①:在组合式API的<script setup>内定义
<script setup>
// 以 v 开头的驼峰命名变量会被识别为自定义指令
const vHighlight = {
mounted: (el) => {
el.classList.add('highlighted')
}
}
</script>
<template>
<p v-highlight>这是高亮显示的文本</p>
</template>
②:在选项式API内,通过directives选项局部注册
export default {
directives: {
highlight: {
mounted: (el) => el.classList.add('highlighted')
}
}
}
③:全局注册自定义组件,directive
const app = createApp({})
app.directive('highlight', {
mounted: (el) => el.classList.add('highlighted')
})
7.介绍vue的单向数据流和双向数据流
这是两个不同概念的东西。
①:单向数据流是一种设计理念,它指父组件向子组件传递数据时,数据只能从父组件流向子组件,子组件无法修改数据。通过props实现,所有props都遵循单向绑定机制。
②:双向数据流是指保持数据和视图的一致。当数据发生变化时,视图自动更新。在vue中主要通过v-model实现,相当于v-bind和@inpute的语法糖。
8.created和mounted生命周期钩子函数的区别
执行时机
created是组件实例创建完成后立即调用。此时组件还未挂载到DOM上。
mounted是组件实例挂载到DOM后调用。此时可以访问组件的DOM节点,进行DOM操作
9.如何是CSS样式只在当前组件内生效
①:使用scoped样式
使用scoped后,父组件的样式不会渗透到子组件内,不过一个子组件的根节点会同时收到它的父组件的 scoped css和子组件的scoped css的影响。
<style scoped>
.example {
color: red;
}
</style>
②:在script标签内加入module特征
<style module>
.example {
color: red;
}
</style>
然后在模板内通过$style引用
<template>
<div :class="$style.example">示例</div>
</template>