【面试 · 一】vue大集合

目录

vue2

基础属性

组件通信

[全局状态管理 vueX](#全局状态管理 vueX)

路由

路由守卫

vue3

基础属性

组件通信

[全局状态管理 Pinia](#全局状态管理 Pinia)

路由

路由守卫

vue2、vue3生命周期

setup

vue2

基础属性

data:用于定义组件的初始数据,必须是一个函数,返回一个对象,每个组件实例都会有自己的数据对象,避免组件之间数据相互影响。

props:用于接收父组件传递的数据,必须是一个数组或对象,数组中的每个元素是一个字符串,表示接收的属性名,对象中的每个属性表示接收的属性名和属性值的类型。

methods:用于定义组件的方法,每个方法都是一个函数,可以在组件中通过 this 访问。

watch:用于监听数据的变化,当数据发生变化时,执行相应的回调函数,可以监听单个数据或多个数据的变化。

computed:用于计算属性,根据已有的数据计算出新的数据,可以监听多个数据的变化,只有当依赖的数据发生变化时才会重新计算。

created:在实例创建完成后立即执行,可以在这个钩子函数中进行数据初始化、事件监听等操作。

computed计算属性

watch

基本使用

javascript 复制代码
 watch: {
      name: { //这里是要监听的变量名
        handler(newValue, oldValue) { //这里的第一个参数是改变后的值,第二个参数是原来的值
          console.log('改后的值是:' + newValue)
          console.log('原来的值是:' + oldValue)
        }
      }
 }

简写

javascript 复制代码
    watch: {
      name(newValue, oldValue) { //这里的第一个参数是改变后的值,第二个参数是原来的值
        console.log('改后的值是:' + newValue)
        console.log('原来的值是:' + oldValue)
      }
    }

immediate:就是当值第一次绑定时,不会执行监听函数,只有值发生改变时才会执行。如果我们需要在最初绑定值的时候也执行函数,需要用到immediate属性;

deep:当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,此时就需要deep属性对对象进行深度监听,数组字符串一般不需要。

javascript 复制代码
  watch: {
      name: {
        handler(newValue, oldValue) {//这里的第一个参数是改变后的值,第二个参数是原来的值
          console.log('改后的值是:' + newValue)
          console.log('原来的值是:' + oldValue)
        },
        immediate: true,
        deep:true
      }
 }

组件通信

父传子

子传父

非父子通信 eventBus事件总线(兄弟组件)

src/utils/eventBus.js

javascript 复制代码
import Vue from 'vue';
export const EventBus = new Vue();
javascript 复制代码
<template>
  <button @click="sendData">发送数据到组件 B</button>
</template>

<script>
import { EventBus } from '@/utils/eventBus';

export default {
  methods: {
    sendData() {
      EventBus.$emit('dataEvent', '来自组件 A 的数据');
    }
  }
};
</script>
javascript 复制代码
<template>
  <p>收到的数据:{{ receivedData }}</p>
</template>

<script>
import { EventBus } from '@/utils/eventBus';

export default {
  data() {
    return { receivedData: '' };
  },
  created() {
    EventBus.$on('dataEvent', data => {
      this.receivedData = data;
    });
  },
  beforeDestroy() {
    EventBus.$off('dataEvent');
  }
};
</script>

组件通信------非父子通信 Provide Inject(跨层级组件)

javascript 复制代码
<template>
  <ChildComponent />
</template>

<script>
export default {
  provide() {
    return {
      sharedMessage: 'Hello from Provide!'
    };
  }
};
</script>
javascript 复制代码
<template>
  <p>收到的数据:{{ sharedMessage }}</p>
</template>

<script>
export default {
  inject: ['sharedMessage']
};
</script>

组件通信------非父子通信 attrs listeners

官方文档介绍:包含了父作用域不作为prop被识别(且获取)的attribute绑定(class和style除外)。当一个组件没有生命任何prop时,这里会包含所有父作用域的绑定(class和style除外),并且可以通过v-bind="$attrs"传入内部组件--在创建高级别的组件时非常有用。

通俗地来说就是如果从父组件传过来的值,没有在子组件中被接收,那么这些值就会被存在$attrs对象中。

javascript 复制代码
//Father.vue
<template>
  <div class="father">
    <span>父亲</span>
    <Son :message="message" :age="18"></Son>
  </div>
</template>

<script>
import Son from "../components/Son.vue";
export default {
  data() {
    return {
      message: "父组件传过来的值",
      age: 18,
    };
  },
  components: {
    Son,
  },
};
</script>


//Son.vue
<template>
  <div class="son">
    <span>儿子</span>
    <GrandSon v-bind="$attrs"></GrandSon>
  </div>
</template>

<script>
import GrandSon from "../components/GrandSon.vue";
export default {
  components: {
    GrandSon,
  },
  created() {
    console.log("son", this.$attrs);
  },
};



//GrandSon.vue
<template>
  <div class="grandson">
    <span>孙子</span>
    <div>{{ $attrs.message }}</div>
  </div>
</template>

<script>
export default {
  created() {
    console.log("grandson", this.$attrs);
  },
};
</script>

组件通信------ref $refs

引用信息会注册在父组件的$ref对象上 vue2/vue3 ref组件通信

javascript 复制代码
//父
<template>
  <div id="app">
    <TodoItem ref="msg"></TodoItem>
    <p ref="dom"></p>
  </div>
</template>
 
<script>
import TodoItem from './components/so.vue'
 
export default {
  name: 'App',
  components: {
    TodoItem
  },
  mounted() {
    console.log(this.$refs)
    // 通过这种方法给子组件传递数据
    this.$refs.msg.getmsg("我是tc") // this.$refs.msg指向的是子组件的实例
  },
}
</script>


//子
<template>
    <div class="so">
        <p>{{ msg }}</p>
    </div>
</template>
 
<script>
export default {
    name: "todo-item",
    data() {
        return {
            msg: ''
        }
    },
    methods: {
        getmsg(s) {
            this.msg = s
        }
    }
}
</script>

 

全局状态管理 vueX

vueX详解(1)

vueX详解(2)

路由

路由详解

路由守卫

路由守卫详解

vue3

基础属性

javascript 复制代码
import { computed, ref } from 'vue';
export default {
  setup() {
    const count = ref(0);
  // 定义一个计算属性
    const doubledCount = computed(() => count.value * 2);

    return {
      count,
      doubledCount
    };
  }
};
javascript 复制代码
const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // 注意:我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})

watch

javascript 复制代码
//ref
<script setup lang="ts">
import { watch, ref } from 'vue'
const sum=ref(1);
// New: 新值 | Old: 老值
watch(sum,(New, Old)=>{
	console.log(`新值:${New} --------- 老值:${Old}`)
})
</script>
javascript 复制代码
//reactive
<script setup lang="ts">
	import { watch,reactive} from 'vue'
    // 响应式变量
    const sum = reactive({
      value: 1
    })
    // watch是一个函数
    // 第一个参数: 要监听的响应式变量(数据源)
    // 第二个参数:执行的回调函数
    // 第三个参数: 配置(例如deep深度监听/immediate是否立即监听等)
    // 注意:当监听一个对象时,第一个参数数据源必须是函数且返回一个值即 "() => 对象.要监听的属性"
    watch(() => sum.value, (New, Old) => {
      console.log(`新值:${New} --------- 老值:${Old}`)
    }, { immediate: true, deep:ture })
</script>

watchEffect

  • 不需要手动传入依赖(不用指定监听对象)
  • 无法获取原始值,只能获取更新后的值
  • 立即执行(在onMounted前调用)
  • 一些异步操作放里面更加的合适
javascript 复制代码
const count = ref(0)
watchEffect(() => {
   console.log(count.value)
})
javascript 复制代码
const stop = watchEffect(() => {
  /* ... */
})
// 停止监听
stop()

副作用清除 做一些异步请求连发限制或取消请求的操作,保证请求数据的完整和准确性。

javascript 复制代码
watchEffect(async (onCleanup) => {
  const { response, cancel } = doAsyncWork(id.value)
  // `cancel` 会在 `id` 更改时调用
  // 以便取消之前
  // 未完成的请求
  onCleanup(cancel)
  data.value = await response
})

组件通信

父传子

javascript 复制代码
<Child info="我爱祖国" :money="money"></Child>
javascript 复制代码
子组件获取父组件传递数据:方式1
let props = defineProps({
  money:{
   type:Number,
   default:0
}})

子组件获取父组件传递数据:方式2
let props = defineProps(["info",'money']);

子传父

javascript 复制代码
<Event2  @xxx="handler3"></Event2>
javascript 复制代码
<script setup lang="ts">
let $emit = defineEmits(["xxx"]);
const handler = () => {
  $emit("xxx", "法拉利", "茅台");
};
</script>

v-model

javascript 复制代码
<template>
  <child v-model:name="name"></child>
</template>
 
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
 
const name = ref('XXX')
</script>
javascript 复制代码
<template>
  <input :value="name" @input="updateName" />
</template>
 
<script setup>
import { defineProps, defineEmits } from 'vue'
 
const props = defineProps(['name'])
const emit = defineEmits(['update:name'])
 
const updateName = (e) => {
  emit('update:name', e.target.value)
}
</script>

依赖注入 (Provide/Inject)

javascript 复制代码
<script setup>
import { provide, ref } from 'vue'
 
const themeColor = ref('blue')
provide('theme', themeColor)
</script>
javascript 复制代码
<script setup>
import { inject } from 'vue'
 
const theme = inject('theme')
console.log(theme.value) // 'blue'
</script>

ref

javascript 复制代码
<template>
  <TodoItem :ref="(el) => child = el"></TodoItem>
  <p ref="dom"></p>
</template>
 
<script>
import TodoItem from './components/so'
import { ref, onMounted  } from 'vue'
 
export default {
  name: 'App',
  components: {
    TodoItem
  }
}
</script>
 
<script setup>
  const child = ref(null)
  // const msg = ref()
  const dom = ref()
  onMounted(() => {
    console.log(child.value.getmsg("我是tc"))
    // msg.value.getmsg("我是tc")
    dom.value.innerHTML = "我是一个普通的DOM元素"
  })
</script>
javascript 复制代码
<template>
  <div class="so">
    <p>{{ msg }}</p>
  </div>
 </template>
 
<script setup>
import { ref, defineExpose } from 'vue'

const msg = ref("")
const getmsg = (s) => {
  msg.value = s
}
// 想要父组件可以获取到需要使用defineExpose向父组件暴露
defineExpose({getmsg})
</script>

事件总线

vue3中移除了事件总线,可以借助于第三方工具来完成,Vue官方推荐 mitt 或 tiny-emitter

全局状态管理 Pinia

Pinia详解

路由

路由详解

路由守卫

vue2、vue3路由区别及原理

vue3路由守卫详解

vue2、vue3生命周期

setup

setup() 钩子是在组件中使用组合式 API 的入口

vue3 setup

相关推荐
崔庆才丨静觅14 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment14 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅15 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊15 小时前
jwt介绍
前端
爱敲代码的小鱼15 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税15 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore
Cobyte15 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT0615 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
剪刀石头布啊15 小时前
生成随机数,Math.random的使用
前端
剪刀石头布啊15 小时前
css外边距重叠问题
前端