【面试 · 一】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

相关推荐
yzzzzzzzzzzzzzzzzz19 分钟前
JavaScript 操作 DOM
开发语言·javascript·ecmascript
奋斗的小羊羊1 小时前
HTML5关键知识点之多种视频编码工具的使用方法
前端·音视频·html5
前端呆猿1 小时前
深入解析HTML5中的object-fit属性
前端·css·html5
再学一点就睡1 小时前
实现大文件上传全流程详解(补偿版本)
前端·javascript·面试
你的人类朋友2 小时前
【Node&Vue】什么是ECMAScript?
前端·javascript·后端
路灯下的光3 小时前
用scss设计一下系统主题有什么方案吗
前端·css·scss
l_tian_tian_3 小时前
SpringClound——网关、服务保护和分布式事务
linux·服务器·前端
一只小风华~3 小时前
CSS @media 媒体查询
前端·css·媒体
shix .4 小时前
最近 | 黄淮教务 | 小工具合集
前端·javascript
John_ToDebug4 小时前
Chrome 内置扩展 vs WebUI:浏览器内核开发中的选择与实践
前端·c++·chrome