Vue3.0中setup语法糖

2,000 阅读1分钟
几个不同于Vue2.X的点,记录一下。

1.watch函数

watch函数在Vue3.0中包含三个参数watch(pointer, change, options)

pointer: 指针函数,告诉watch的是哪个对象

change: 被watch对象的值或者属性的变化

options: 给watch函数设置的属性,如deep, immediate等

<template>
    <div>{{`${person.name}今年${person.age}岁, 明年${nextYearAge}岁`}}</div>
    <button @click="changeAge">加1岁</button>
</template>
 
<script setup>
import { computed, reactive, watch } from 'vue'
const person = reactive({
    name: '小明',
    age: 18
})
 
// 声明methods
const changeAge = () => {
    person.age += 1
}
 
// 声明methods方法
const nextYearAge = computed(() => {
    return person.age + 1
})
 
watch(
    // pointer函数,监听的是什么
    () => person.age,
    // change函数,监听值的变化
    (newV, oldV) => {
        console.log("当前值:" + person.age)
        console.log("变化前:" + oldV)
        console.log("变化后:" + newV)
    },
    {
      immediate: true, // 立即执行
      deep: true // 深度监听
    }
)
</script>

2.props传值,父传子(defineProps)

// 父组件
<template>
  <div>
    <child :name="name"></child>
  </div>
</template>
 
<script setup>
// 引入组件,组件在setup语法糖中会自动注册
import Child from './child.vue'
</script>
 
//
//
//
//
//
//
// 
 
// 子组件
<template>
  <div>
    子组件中name=`${name}`
  </div>
</template>
 
<script setup>
// 引入组件,组件在setup语法糖中会自动注册
// import { defineProps } from 'vue'
// defineProps在<script setup>中自动可用,无需导入
// 需在.eslintrc.js文件中【globals】下配置【defineProps: true】
 
// 声明props
const props = defineProps({
  name: {
    type: String,
    default: ''
  }
})  
 
</script>

3.emit的使用(父传子),defineEmits([** emitFuncName **])

// 父组件
<template>
    <div>{{`${person.name}今年${person.age}岁`}}</div>
    <HelloWorld :person="person"></HelloWorld>
</template>
 
<script setup>
import HelloWorld from '../components/HelloWorld.vue'
import { reactive } from 'vue'
const person = reactive({
    name: '小明',
    age: 18
})
</script>
 
//
//
//
//
 
// 子组件
<template>
    <button @click="changePersonName">改名字</button>
</template>
 
<script setup>
// import { defineProps, defineEmits } from 'vue' // setup语法糖中可以不用import
// props声明
const props = defineProps({
  person: {
    type: Object,
    default() {
      return {}
    }
  }
})
 
// 声明事件
const emit = defineEmits(['update:person'])
 
const changePersonName = () => {
  props.person.name = "小红"
  // 执行
  emit('update:person', props.person)
}
</script>

4.setup中自定义v-model

给组件自定义v-model,可以非常灵活和方便的给我们解决一些实际上的问题,而不需要父组件去监听子组件回传事件。想象一下,如果你用到了一个树形结构的组件,而你要改变树结构的某个节点的数据,如果你去emit回传的话,肯定还需要告诉父组件我修改的节点的对应的id,或者key什么的,而通过自定义v-model,你可以省去这些繁琐而复杂的操作,这一点是本人在实际项目中得到的经验,真的感觉非常有用。

我们看下在Vue3.0中如何自定义v-model。不同于Vue2.x,Vue3.0中我们可以定义多个v-model,而Vue2.x每个组件只能定义一个v-model。

// 父组件
<template>
  <TestModel v-model:name="person.name" v-model:age="person.age"></TestModel>
  <p>{{person.name}}</p>
  <p>{{person.age}}</p>
</template>
 
<script setup>
import TestModel from '../components/TestModel.vue'
import { reactive, watch } from 'vue'
const person = reactive({
  name: 'John',
  age: 32
})
</script>
 
//
//
//
//
 
// 子组件
<template>
  <div>测试</div>
  <input type="text" :value="name" @input="changeName"/>
  <input type="number" :value="age" @input="changeAge"/>
</template>
 
<script setup lang="ts">
defineProps({
  name: String,
  age: Number
})
 
const emit = defineEmits(['update:name', 'update:age'])
const changeName = (e) => {
  emit('update:name', e.target.value)
}
 
const changeAge = (e) => {
  console.log(typeof e.target.value)
  emit('update:age', +e.target.value)
}
</script>
 
// ps: input的type="number"并不是说输入的值age是number数据类型,限制只能输入数字

原文链接:blog.csdn.net/qq_36514044…