Vue3新语法

Vue3新语法

vue3 新特性_vue3 props-CSDN博客

1、data数据

1.1 响应式区别

Vue2中响应式是通过defineProperty实现的。

Vue3中响应式是通过ES6的Proxy实现的。

Vue3中实现响应式提供了ref和reactive两个组合式API。

1.2 ref和reactive的区别

ref特点

  • ref的参数一般是基本数据类型,也可以是对象类型

  • 如果参数是对象类型,其实底层的本质还是reactive,系统会自动将ref转换为reactive,例如 ref(1) ===> reactive({value:1})

  • ref包括的数据,要访问内容需要用.value属性,在模板中使用的时候,系统会自动帮我们添加.value,在JS中访问ref中的数据,需要手动添加.value

  • ref的底层原理同reactive一样,都是Proxy

<template>
    <h1>{{ name }}</h1>
    <h1>{{ age }}</h1>
</template>
​
<script>
import { ref} from 'vue'
export default {
  name: 'App',
  setup () {
    //定义简单数据
    const name = ref('frank')
    const age = ref(18)
    //定义方法
    const handleChange = () => {
        name.value = 'mike'
        age.value = 20
    }
    //暴露给模板
    return { name, age, handleChange }
  }
}
</script>
​

reactive特点

  • reactive的参数一般是对象或者数组,他能够将复杂数据类型变为响应式数据。

  • reactive的响应式是深层次的,底层本质是将传入的数据转换为Proxy对象

import { reactive } from 'vue'
export default {
  name: 'App',
  setup () {
    //定义复杂数据
    const user = reactive({
      name: 'frank',
      age: 18
    })
    //定义方法
    const handleChange = () => {
        user.name = 'mike'
        user.age = 20
    }
    //暴露给模板
    return { user, handleChange }
  }
}

2、method方法

定义变量指向一个箭头函数即可,可以在模板中调用该方法。

   //方法定义
   const addFn = () => {
      count.age++
   }

3、计算属性

通过computed()方法创建计算属性。方法参数是一个箭头函数。

只读的计算属性

const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value)  //2
​

可写的计算属性

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => {
    count.value = val - 1
  }
})
plusOne.value = 1
console.log(count.value) // 0

4、监听器

https://cn.vuejs.org/guide/essentials/watchers.html#basic-example

检测某个变量值的变化,变化后执行对应的逻辑代码。

与监听器相关的方法watch(),watchEffect(),watchPostEffect(),watchSyncEffect()

4.1 watch()

侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。

https://cn.vuejs.org/api/reactivity-core#watch

监听一个getter函数,当函数返回值变化的时候,触发方法执行

const state = reactive({ count: 0 })
watch(
  () => state.count,
  (count, prevCount) => {
    /* ... */
  }
)
   //数据定义
   const person = reactive({
      name: 'san xiaogui',
      chineseName: [
         '小王', '小陈'
      ]
   })
   //变更方法
   const changeNameFn = () => {
      person.name = '1111';
   }
   //监听器
   watch(() => {
      return person.name;
   }, (value, oldValue) => {
      console.log(oldValue)
      console.log(value)
   }, {deep: true})

监听一个ref

const count = ref(0)
watch(count, (count, prevCount) => {
  /* ... */
})

4.2 watchEffect()

立即运行一个函数,同时响应式地追踪相关的依赖数据,并在依赖更改时重新执行。

const count = ref(0)
watchEffect(() => console.log(count.value))
// -> 输出 0
count.value++
// -> 输出 1

4.3 区别

1.watch是惰性执行的,而watchEffect不是,不考虑watch第三个配置参数的情况下,watch在组件第一次执行的时候是不会执行的,只有在之后依赖项变化的时候再执行,而watchEffect是在程序执行到此处的时候就会立即执行,而后再响应其依赖变化执行。
2.watch需要传递监听的对象,watchEffect不需要

监听器创建时会返回方法引用,如果要停止监听,则需要通过调用该引用停止监听。

const stopWatch = watchEffect(() => console.log(count.value))

//停止
stopWatch()

5、生命周期

Vue2的钩子函数都是组件选项,Vue3提供了组合API的使用方式,组件选项方式是保留的。

image-20220416204216376-1679012515719

   //原Created内要执行的代码
   console.log('HelloWorld Created')
   //生命周期函数
   onMounted(() => {
      console.log('HelloWorld mounted')
   })

6、子组件定义

setup组件内必须通过defineProps,defineEmits,defineExpose进行声明。

<script setup>
   import {defineProps, defineEmits, defineExpose, reactive} from 'vue'

   // 定义接收属性:defineProps
   const props = defineProps({
      name: {
         type: String,
         required: true
      },
      age: Number
   })
   // 定义触发父组件方法的事件:defineEmits
   const emit = defineEmits(['change', 'delete'])

   const subValue = reactive({
      name: '1111',
      age: 12
   })
   const showDialogFn = (a) => {
      console.info('显示对话框', a)
   }

   function deleteHandler() {
      emit('delete', 'aaa')
   }

   // 对外公开的属性和方法:defineExpose
   defineExpose({
      subValue,
      showDialogFn
   })


</script>

<template>
   <!--显示传入数据-->
   <p>Child1 - name: {{ props.name }}, age: {{ props.age }}</p>
   <!--调用外部方法-->
   <button @click="$emit('change', 'bbb')">change</button>
   <!--调用外部方法-->
   <button @click="deleteHandler">delete</button>
   <slot></slot>
</template>

7、父子组件交互

<script setup>
   import {ref, reactive, computed, onMounted, watch, watchEffect, getCurrentInstance} from 'vue'
   //导入子组件,无需注册,就可以直接使用。
   import child from '@/components/child.vue'
   //获取子组件的引用(名称和组件的ref属性值相同),可以用来调用子组件公开的方法和属性
   const childRef = ref(null)

   const person = reactive({
      name: '志瑞', age: 43
   })
   //方法定义,绑定子组件的事件
   const changeFn = () => {
      console.info('通过子附件调用父组件方法changeFn')
   }
   //方法定义,绑定子组件的事件
   const deleteFn = () => {
      console.info('通过子附件调用父组件方法deleteFn')
   }

   //通过引用调用子附件的方法和属性
   const invokeChild = () => {
      console.info('调用子组件')
      childRef.value.showDialogFn('123');
      console.info(childRef.value.subValue);
   }

</script>

<template>
   <div class="card">
      <!--给字符串传入属性,并绑定emit事件处理函数-->
      <child ref="childRef" :name="person.name" :age="person.age" @change="changeFn" @delete="deleteFn">
         <div>Slot的内容</div>
      </child>
      <div>
         <button @click="invokeChild">调用子组件</button>
      </div>
   </div>
</template>

<style scoped>
   .read-the-docs {
      color: #888;
   }
</style>

8、组件导入

同vue2的组件导入方法

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值