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

相关推荐
liuyang___2 分钟前
vue3+ts的computed属性怎么用?
前端·javascript·vue.js
cwl724 分钟前
Unity WebGL、js发布交互
javascript·unity·webgl
软件技术NINI20 分钟前
html css js网页制作成品——HTML+CSS珠海网页设计网页设计(4页)附源码
javascript·css·html
爱编程的鱼22 分钟前
如何用CSS实现HTML元素的旋转效果:从基础到高阶应用
前端·css·html
lhhbk2 小时前
angular的cdk组件库
前端·javascript·angular.js
布兰妮甜2 小时前
Node.js入门指南:开启JavaScript全栈开发之旅
开发语言·javascript·node.js
Wcowin2 小时前
Mkdocs页面如何嵌入PDF
前端·pdf·mkdocs
Joker Zxc2 小时前
【前端基础】7、CSS的字体属性(font相关)
前端·css
一个W牛3 小时前
精选面试题
javascript·面试