写给懒人的vue3快速查阅📒

大家好,这是我2024年第一篇文章~祝大家新春快乐🎆

写了多年react,但是新入职的公司技术栈是vue,部门后续会升级到VUE3。并且发现身边不少小伙伴是react转vue,因项目原因需要快速上手,所以输出了一篇学习笔记,方便快速上手查阅。

Vue 3 相对于 Vue 2 有许多改进和新功能,其中一些主要的变化包括:

  1. 使用 Composition API:Vue 3 引入了 Composition API,这是一种新的、更灵活的组件编写方式,允许更好地组织和复用代码。
  2. 改进的性能:Vue 3 在性能方面进行了许多改进,包括更快的渲染速度、更小的捆绑体积和更好的内存管理。
  3. 更好的 TypeScript 支持:Vue 3 提供了更好的 TypeScript 支持,包括类型推断和类型注解。
  4. 新的路由器和状态管理库:Vue 3 引入了新的路由器和状态管理库,称为 Vue Router 和 Vuex 4。
  5. 更好的 tree-shaking 支持:Vue 3 更好地支持 tree-shaking,这意味着在生产环境中,只打包实际使用的代码,从而减少应用程序的大小。

setup

在 Vue 3 中,setup 是一个新的组件选项,用于定义组件的逻辑和状态。通过使用 setup,可以更清晰地组织组件的逻辑和状态,并使其更易于测试和维护。也可以直接把setup写在script标签上哦

html 复制代码
<template>
  <div>
    {{ count }}
  </div>
</template>

<script>
export default {
  name: 'MyComponent',
  setup() {
    const count = ref(0);
    const increment = () => {
      count.value++;
    };

    return {
      count,
      increment
    };
  }
};
</script>

响应式数据

使用reactive创建对象类型响应式数据,如果给reactive重新分配一个对象,会失去响应式,可以使用Object.assign()去整体替换。使用ref创建基本类型响应数据

ref也可以创建对象类型的响应数据。若层级较深,建议reactive

html 复制代码
<script setup>
  import { reactive , ref } from 'vue';
  let obj=reactive({
    a:1,
    b:{
      c:3
      d:4
    }
  })
  let str=ref('hi')
  const fnc=()=>{
    str.value = 'hello!'//记得加.value
  }
</script>

解构响应式对象

toRefs可用来解构,该对象的每个属性都是独立的 ref 对象,并保持响应式

js 复制代码
import { reactive, toRefs } from 'vue';
let info = reactive({
  name: 'Echo',
  age: 26,
  gender: 'Male',
})

let { name, age, gender } = toRefs(info);//解构数据,并保持响应式

如何监听多个数据?

监听多个数据,第一个参数需用数组包起来;如果监听非对象类型,需写成函数形式,若监听 reactive 定义的对象类型,就默认开启深度监听。

开启immediate :上来就调用监听里的内容,类似react中的useEffect(()=>{},[])

js 复制代码
import { watch } from 'vue';
//监听active、type
watch([() => props.active, ()=> props.type],(nv, ov) => {
  // nv代表最新数据,ov是老数据
  console.log(nv)
  //开启deep代表深度监听
},{ deep:true, immediate: true })

解放双手,自动检测变化

watchEffect可以自动检测到属性的变化,无需手动指定要监听的属性。

与传统的 watch 不同,watchEffect 会在属性变化时自动执行副作用函数,并且可以返回一个清理函数,用于在组件卸载时清理副作用。

js 复制代码
import { watchEffect } from 'vue';

//只要temp.val跟json.val发生变更,就会自动执行watchEffect内的副作用函数
watchEffect(()=>{
  if(temp.val>60||json.val>60){
    console.log('发送请求')
  }
})

接收props

父子组件传值,需要使用defineProps接收props,案例如下:

html 复制代码
<script setup>
  import { defineProps } from 'vue';
  //子组件接收props
  const props = defineProps({
    language: {
      type: Object,
      //也可以使用withDefaults设置默认值
      default: () => ({}),
    },
    cookieCountry: {
      type: String,
      default: ''
    }
  })
</script>

Ref属性(父子交互)

通过 Ref 属性,可以从父组件中访问子组件的属性和方法,或者直接操作 DOM 元素。

html 复制代码
<template>
  <div ref="myDiv">Hello, World!</div>
</template>

<script>
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const myDiv = ref(null);
		//mounted是生命周期,代表挂载完毕
    onMounted(() => {
      myDiv.value.style.color = 'red';//将myDiv的颜色改成红色
    });

    return {
      myDiv
    };
  }
};
</script>

如果父组件想访问子组件的内容,子组件需使用defineExpose将内容导出。

defineExpose将组件中的属性或方法暴露给外部环境,以便在其他组件或模板中使用。

html 复制代码
<template>
   <card-num 
    ref="cardNumRef"
   />
</template>

<script setup>
  import { ref } from 'vue';
  const resetAllRefData = () => {
    console.log(cardNumRef.value.cardNo)//获取子组件中的cardNo值
  }
</script>

cardNum组件:

html 复制代码
<script setup>
  import { defineExpose } from 'vue';
  const resetData = () => {
    cardNo.value = ''
    cardNum.value = ''
  }
  //暴露
  defineExpose({
    resetData
  })
</script>

自定义事件

defineEmits 是 Vue 3 中的一个新特性,它允许你在组件中自定义事件。在父组件中,可以使用 v-on 指令来监听自定义事件。

html 复制代码
<template>
  <!-- 自定义一个叫update的事件 -->
  <Child @update="onUpdate"/>
</template>

<script setup>
  import Child from '/Child.vue'
  
  const onUpdate = (value)=>{
    console.log(value)//666
  }
</script>

Child组件:

html 复制代码
<template>
  <!-- 点击button,将666传给父,emits 触发事件 -->
  <button @click="emits('update',666)"/>
</template>

<script setup>
  import { defineEmits,onMounted } from 'vue'
  
  // 定义 emits
  const emits = defineEmits(['update'])//接收事件名update
</script>

vue3 生命周期

html 复制代码
<script setup>
  import { onMounted,onBeforeMount,onUpdated,unmounted } from 'vue';
  //挂载前
  onBeforeMount(()=>{})
  //挂载完毕
  onMounted(()=>{})
  //更新完毕
  onUpdated(()=>{})
  //卸载完毕
  onUnmounted(()=>{})
</script>

beforeCreate: 在实例初始化之后。

created: 在实例创建完成后被立即调用。

beforeUpdate: 数据更新时。

beforeUnmount: 实例销毁之前。

以此类推...

作用域插槽

作用域插槽,它允许你在一个组件中定义具有局部作用域的插槽。通过作用域插槽,可以将组件的属性传递给插槽内容,从而使插槽内容能够根据组件的状态进行动态渲染。

作用域插槽使用 v-slot 指令来定义,它可以接受一个参数,该参数指定了要传递给插槽的属性名。

下面是具名插槽+作用域插槽的例子:

如果不写名字就是默认插槽

html 复制代码
 <!-- <template #ScopedSlot="{list}"></template> -->
<template>
  <SlotComponent>
    <!-- ScopedSlot是插槽名,params子组件传的是参数 -->
    <template v-slot:ScopedSlot='params'>
      <ul>
        <li v-for='d in params.list' :key="d.id">
        {{d.name}}
        </li>
      </ul>
    </template>
  </SlotComponent>
</template>

<script>
import SlotComponent from './SlotComponent.vue';

export default {
  components: {
    SlotComponent,
  },
};
</script>

子组件SlotComponent:

html 复制代码
<template>
  <div>
    <slot name="ScopedSlot" :list="list" />
  </div>
</template>

<script setup>
	import {reactive} from 'vue'
  let list=reactive([
    {id:'001',name:'test-01'},
    {id:'002',name:'test-02'}
  ])
</script>

提高性能-浅层次响应

shallowRef()ref()类似,但它不支持深度响应性,是浅层次响应。

对嵌套对象的属性或数组元素的修改不会触发响应性。这在需要优化性能并避免不必要的深度响应性跟踪时非常有用。这样使用浅的响应式提高性能,只有最外一层是响应式。

shallowReactive同理

响应式对象-》原始对象

toRaw() 是用于将响应式对象转换为原始对象。以便在需要时进行操作。转换后的对象不再具有响应性,对其进行的更改不会触发 Vue 的更新机制。

js 复制代码
import { reactive, toRaw } from 'vue';

const obj = reactive({ name: 'John', age: 24 });

const rawObj = toRaw(obj);

console.log(rawObj); 
// 输出:{ name: 'John', age: 24 }

rawObj.name = 'Alice';

console.log(obj.name); 
// 输出:'John'

创建自定义的ref

customRef 是 Vue 3 中引入的一个新特性,用于创建自定义的ref,让用户来决定什么时候收集和执行依赖,从而更好地控制行为和逻辑。customRef 接受 track 和 trigger 两个函数作为参数,并返回一个带有 get 和 set 方法的对象。

track用于追踪数据,trigger 用于触发响应,更新视图。一般 track 方法放在 get 中,trigger 方法放在 set 中。

js 复制代码
import { customRef } from 'vue';

const myCustomRef = customRef((track, trigger) => {
  // 在这里编写自定义的逻辑
  return{
    get(){
      track()//跟踪
    },
    set(value){
      trigger()//触发
    }
  }
});

// 在组件中使用自定义的 ref
const myComponent = {
  template: `<div ref="myCustomRef"></div>`,
  setup() {
    const myCustomRef = myCustomRef();

    console.log(myCustomRef.value); 
    // 获取当前的引用值
  }
};

获取未在 props 中声明的属性

$attrs 可以用于获取父组件传递的属性值,或者在组件内部未在 props 中声明的属性。

注意:$attrs 中的属性是只读的,不能直接修改。如果需要在组件内部处理未在 props 中声明的属性,可以使用 v-bind 指令或动态组件来实现。

html 复制代码
<!-- 传值给子组件 -->
<child-component :id="id" :style="style" some-other-attribute="value"></child-component>
js 复制代码
export default {
  props: ['id', 'style'],//props只接收了id跟style
  created() {
    console.log(this.$attrs); //$attrs能实现全部获取
    // 输出:{ id: "id", style: "style", someOtherAttribute: "value" }
  }
};

组件间通信

$parent和refs 是用于组件间通信和访问的属性。需要配合defineExpose一起使用

  • refs 可以用于在模板中访问子组件或 DOM 元素。在模板中的元素或组件上使用 ref 属性来定义一个引用名称,然后在组件的 JavaScript 代码中通过 $refs 访问到这个元素或组件。
  • parent 指向当前组件的父组件实例。通过 $parent,可以访问父组件的属性、方法和事件等。

父组件 $refs示例代码:

html 复制代码
<template>
  <div>
    <button @click="myButton($refs)">点击我</button>
    <!-- 子组件 -->
    <ChildComponent1 />
    <ChildComponent2 />
  </div>
</template>

<script setup>
  import ChildComponent1 from '/ChildComponent1.vue'
  import ChildComponent2 from '/ChildComponent2.vue'
  import { ref,defineExpose } from 'vue';
  
  let value=ref('666')
	function myButton(refs){
    // refs是子组件的集合
    for(let key in refs){
      refs[key].val=+1//操作每个子组件的val+1
    }
  }
  defineExpose({value})
</script>

子组件 $parent示例代码:

html 复制代码
<template>
  <div>
    <button @click="parentMethod($parent)">点击我</button>
  </div>
</template>

<script>
  import { ref } from 'vue';
  let value=ref('888')
  function myButton(parent){
    parent.value-=1//子操作父的value
  }
  defineExpose({value})
</script>

隔代通信

provide 是一个用于提供依赖注入的选项。可用于隔代通信;它允许父组件向其后代组件提供共享的数据或功能。在子组件中可以通过 inject 选项来接收父组件提供的属性。

html 复制代码
<template>
  <div>
    <Child />
  </div>
</template>

<script setup>
  import Child from './Child.vue';
  import { ref,provide } from 'vue';
  
  let value=ref({
    name:'sam',
    age:18
  })
  //provide向后代提供数据
  provide('val',value)
</script>

子组件Child:

html 复制代码
<template>
  <div>
    <!-- sam -->
    姓名:{{data.name}}
    <!-- 18 -->
    年龄:{{data.age}}
  </div>
</template>

<script setup>
  import { reject } from 'vue';
  //reject接收数据
  let data=reject('val',{//第二个参数是默认值
    name:'未知',
    age:0
  })
</script>

有bug?想补充?

更多参考官网:v3-migration.vuejs.org/zh/

感谢大家观看这篇文章,有任何问题或想和我交流,请直接留言,

发现文章有不妥之处,也可指出交流,感谢阅读~

相关推荐
Martin -Tang14 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发15 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html