常见面试问题——Vue.js

66 阅读2分钟

vue2 和 vue3 的区别

v-if 和 v-show 的区别

v-if 和 v-for 的优先级

v-for 中 key 是什么,为什么要设置

diff 原理

computed 和 watch区别

vue性能优化方案

keepalive

nexttick

为什么data 是一个函数而不是对象

组件通讯

父子组件传值时,如果父组件数据异步时间比较长,子组件怎么处理能减少白屏问题

子组件怎么修改父组件的值

image.png

juejin.cn/post/699968…

组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。所以需要通过一些方式进行组件通讯。

1.父传子 props

  • 使用场景:子组件想使用父组件里的数据,父组件把数据传递给子组件。
  • 特点:prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop 只读,不可被修改,所有修改都会失效并警告。
  • 用法:(vue3 setup)
    • 父组件在子组件上绑定要传的值<child :prop='表达式'>
    • 子组件显式声明接收defineProps({prop:Type})
//父组件
<ChildComponent :childMsg1="fatherMsg1"></ChildComponent>
<ChildComponent childMsg2="fatherMsg2"></ChildComponent>

<script setup lang="ts">
    import { ref } from "vue";
    import ChildComponent from "./ChildComponent.vue";
    let fatherMsg1 = ref(1000); //或reactive({}) // 动态响应
    let fatherMsg2 = 2000;  // 静态传值
</script>
//子组件
<div class="child">{{ childMsg1 }}</div>
<div class="child">{{ childMsg2 }}</div>

<script setup lang="ts">
    defineProps({
      childMsg1: Number,
      childMsg2: Number
    });
</script>

2.子传父 组件事件$emit

  • 使用场景:父组件想使用子组件的数据,子组件通过事件传递给父组件
  • 用法:(vue3 setup)
    • 子组件触发自定义事件,传递事件参数 emit('event',n)
    • 父组件监听事件,接收事件附带的参数 @event='handle'
//子组件
<script setup lang="ts">
    const emit = defineEmits(['submitEvent'])
    function buttonClick() {
      emit('submitEvent',"这是发送给父组件的数据")
    }
</script>
//父组件
<ChildComponent @submit-event="handleEmit" />

<script setup lang="ts">
     function handleEmit(msg : String) {
        console.log(msg) // msg = "这是发送给父组件的数据"
      }
</script>

3.父传子、子传父 引用子组件实例+声明暴露 ref +expose

  • 使用场景:父组件想使用子组件的数据,直接引用子组件实例,访问暴露的公共属性。父组件可以在调用子组件方法时传递参数,子组件接收参数。
  • 用法:(vue3 setup)
    • 子组件声明当组件实例被父组件通过模板引用访问时暴露的公共属性和方法 expose
//子组件
<script setup >
    const msg='这是组件的属性'
    function someMethod() {
          console.log("这是子组件的方法");
    }
    defineExpose({
        msg,
        someMethod,
    });
</script>
<ChildComponent ref="childRef"></ChildComponent>

<script setup lang="ts">
    const childRef = ref<InstanceType<typeof ChildComponent> | null>(null)
    const useChild = () => { childRef.value?.someMethod() }
</script>

4.祖传子 透传 Attributes $attrs

  • “透传 attribute”指的是传递给一个组件,却没有被该组件声明为 propsemitsattribute 或者 v-on 事件监听器
  • 透传的 attribute 会自动被添加到根元素上
  • 使用场景:组件嵌套深
  • 用法:(vue3 setup)
    • 祖先组件传递属性
    • 子组件获取透传的属性
// 祖先组件
<ChildComponent :msg1="111" :msg2="222" title="3333"></ChildComponent>
//父组件
//如果有多个根节点,需要显示绑定$attrs
<div>第一个根节点
    <ChildButton v-bind="$attrs">子组件</ChildButton> 
</div>
<div>第二个根节点</div>
// 后代组件()
<span>Fallthrough attribute: {{ $attrs }}</span>

<script setup lang='ts'>
    import { useAttrs } from "vue"
    const props = defineProps({
        msg1: String
    })
    const attrs = useAttrs()
    console.log(attrs) // { msg2:"2222", title: "3333" }
</script>

5.祖传子 provide + inject

  • 一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
// 祖先组件()
<script setup> 
    import { provide } from 'vue' 
    provide('message', 'hello!') 
</script>
// 后代组件()
<script setup> 
    import { inject } from 'vue' 
    const message = inject('message') 
</script>

Vuex / Pinia

mitt

生命周期

vue2vue3
beforexxxxxxxxx
beforexxxxxxxxx
beforexxxxxxxxx
beforexxxxxxxxx
beforexxxxxxxxx
beforexxxxxxxxx

请求放在哪里,放在 created 和 mounted 的区别?

mvvm、双向绑定的原理

image.png 所有组件都是双向绑定吗,哪一层不能??什么意思?

响应式原理

diff算法

vuex

vue-router