跳转到主要内容
冬月的博客

vue3 语法会比vue2 简洁

这里通过一个点击按钮累加的列子,来对比vue2和vue3的语法

vue2

<template>
  <button @click="add">{{ count }}</button>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    add() {
      this.count++;
    },
  },
};
</script>

<style scoped></style>

vue3

<template>
  <button @click="add">{{ count }}</button>
</template>

<script setup>
import { ref } from "vue";

const count = ref(0);

const add = () => {
  count.value++;
};
</script>

<style scoped></style>

从这里看出来,vue3的语法比vue2简洁很多,配和setup语法糖,代码更加简洁,结构更加清晰,速度更快

这里讲解一下案例里的ref,顺带引出 reactive

reactive

  1. reactive 是vue3的响应式数据,它接受一个对象,返回一个响应式对象,这个对象里的数据,当数据发生改变时,视图会自动更新 2,reactive 只能接受对象,不能接受数组和普通变量

ref

  1. ref 是vue3的响应式数据,它接受一个值,返回一个响应式对象,这个对象里的数据,当数据发生改变时,视图会自动更新 2,ref 可以接受数组和普通变量 3,ref 的值需要通过 .value 来访问和修改
  2. 日常中推荐全部使用 ref,因为 ref 可以接受数组和普通变量,而 reactive 只能接受对象

计算属性 computed

语法格式

const computedlist = computed(() => {
  return count.value;
});
  1. computed主要是用来计算属性的,它接受一个函数,返回一个计算后的值
  2. 通过声明一个变量来存储计算后的值:computedlist,方法里通过return 返回计算后的值,
  3. 注意:这里的值如果是ref创建的需要通过 .value 来访问和修改

侦听器 watch

语法格式

监听一个数据

watch(count, (newVal, oldVal) => {
  console.log(newVal, oldVal);
});
  1. watch 是用来监听数据的,它接受两个参数,第一个参数是你要监听的数据,可以是ref创建的,也可以是reactive创建的,也可以是普通变量
  2. 第二个参数是回调函数,当监听的数据发生改变时,会触发回调函数,回调函数有两个参数,第一个参数是新的值,第二个参数是旧的值
  3. 注意:这里的值如果是ref创建的需要通过 .value 来访问和修改

监听一个对象

# 监听一个数据并且深度监听
watch(count, (newVal, oldVal) => {
  console.log(newVal, oldVal);
}, { deep: true })
  1. 深度监听:当监听的数据是用ref创建时,需要设置 deep 为 true,才能监听到对象里的属性的变化

监听多个数据

watch([count, count2], (newVal, oldVal) => {
  console.log(newVal, oldVal);
});
  1. watch 可以监听多个数据,它接受一个数组,数组里的每个元素都是你要监听的数据,也可以把多个数据存储在一个数组里,然后一起监听
  2. 回调函数的参数是一个数组,数组里的每个元素都是对应的数据的新值和旧值
  3. 注意:这里的值如果是ref创建的需要通过 .value 来访问和修改

生命周期

Vue3 的生命周期 API 对应表

选项式 API组合式 API
beforeCreate / createdsetup()
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted

生命周期是按照顺序执行的

父子通信

父传子

  1. 父组件导入子组件,在子组件上绑定属性
  2. 子组件通过defineProps 接收父组件传递的属性,并生命类型,比如:name: string

父组件代码

<template>
  <sun  message="hello sun"/>
</template>

<script setup>
import { ref, reactive, computed } from "vue";
import sun from "./components/sun.vue";

</script>

<style scoped></style>

子组件代码

<template>
    {{ message }}
</template>

<script setup>
const props = defineProps({
    message: String
})

</script>

<style scoped></style>

子传父

  1. 父组件导入子组件,在子组件上绑定事件
  2. 子组件通过defineEmits 接收父组件传递的事件,并声明类型,比如:message: String
  3. 子组件通过emit 触发事件,并传递参数,比如:emit(‘message’, ‘hello father’)

父组件代码

<template>
  <div>
    <p>收到子组件:{{ msg }}</p>
    <sun @sendMsg="msg = $event"/>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import sun from './components/sun.vue'

const msg = ref()
</script>

<style scoped></style>

子组件代码

<template>
    <button @click="send">返回子组件数据</button>
</template>

<script setup>
const emit = defineEmits(['sendMsg'])
const send = () => {
    emit('sendMsg', '我是子组件的数据')
}
</script>

模版引用

通过 ref 标识获取真实的 dom 对象或者组件实例对象

  1. 创建一个ref对象
  2. 在标签里绑定ref对象
  3. 组件挂载完毕才可以获取
<template>
  <div ref="divref">123</div>
</template>

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

const divref = ref(null)
onMounted(() => {
  console.log(divref.value)
})
</script>

<style scoped></style>

顶层到底层的数据传递

通过 provideinject 实现数据的传递

  1. 在顶层组件里通过 provide 提供数据
  2. 在子组件里通过 inject 接收数据

顶层代码

<template>
  <div>
    <p>收到子组件:{{ msg }}</p>    
    <sun @sendMsg="msg = $event"/>
  </div>
</template>

<script setup>
import { ref, provide} from 'vue'

const msg = ref()
provide('msg', msg)
</script>

<style scoped></style>

底层代码

<template>
</template>

<script setup>
import { ref, inject} from 'vue'

const msg = inject('msg')

</script>