Vue3.0中setup语法糖的使用
可以说setup函数是Vue3.0的最重要的核心方法之一。setup函数在组件创建前执行,并且充当Componsition API的入口。使用setup函数应该注意:setup函数中没有this, 因为setup函数在beforeCreated之前就执行了setup其本身不可以为异步函数setup内可以执行await方法处理异步问题setup函数接收两个参数,props和context(conte
可以说setup函数是Vue3.0的最重要的核心方法之一。setup函数在组件创建前执行,并且充当Componsition API的入口。
使用setup函数应该注意:
- setup函数中没有this, 因为setup函数在beforeCreated之前就执行了
- setup其本身不可以为异步函数
- setup内可以执行await方法处理异步问题
- setup函数接收两个参数,props和context(context包含3个参数attrs,slots,emit),而context是可以被解构的
<script setup="props, context" lang="ts">
console.log(context.attrs)
console.log(context.slots)
console.log(context.emit)
</script>
<script setup="props, { attrs, slots, emit }" lang="ts">
console.log(attrs)
console.log(slots)
console.log(emit)
</script>
我们可以与Vue2.x做一下类比,这样更加能够帮助我们如何用Vue3.0做开发
1、data变量声明的变化
在Vue2.x中,data是通过Vue的工厂函数创建,原理是通过Object.defineProperties去创建或者修改Vue实例的属性。
<script>
export default {
data () {
return {
mgs: "Hellow World"
}
}
}
</script>
而在Vue3.0中就不一样了,是通过Vue3.0的Componsition API,reactive、ref、toRefs将setup中声明的变量转变成Vue可以监听的对象
<script>
import { defineComponent, ref, toRefs, reactive} from 'vue'
export default defineComponent({
setup(){
// ref声明响应式数据,用于声明非引用类型
const active = ref(0)
// 修改
active.value = 1
// reactive声明响应式数据,用于声明引用数据类型
const state = reactive({
name: 'Jerry',
sex: '男'
})
// 修改
state.name = 'Tom'
// 使用toRefs解构
const {name, sex} = toRefs(state)
return {
active,
state
}
}
})
</script>
或者setup语法糖的形式
<script setup>
import { reactive, ref, toRefs } from 'vue'
// ref声明响应式数据,用于声明非引用类型
const active = ref(0)
// 修改
active.value = 1
// reactive声明响应式数据,用于声明引用数据类型
const state = reactive({
name: 'Jerry',
sex: '男'
})
// 修改
state.name = 'Tom'
// 使用toRefs解构
const {name, sex} = toRefs(state)
</script>
2、methods方法创建的变化
Vue2.x中统一在methods对象内创建方法,Vue3.0中更加简洁,直接在setup函数中声明一个函数表达式即可
<template>
<div>{{`${person.name}今年${person.age}岁`}}</div>
<button @click="changeAge">加1岁</button>
</template>
<script setup>
import { reactive } from 'vue'
const person = reactive({
name: '小明',
age: 18
})
// 声明methods方法
const changeAge = () => {
person.age += 1
}
</script>
3、computed。Vue3.0中引入computed API创建
<template>
<div>{{`${person.name}今年${person.age}岁, 明年${nextYearAge}岁`}}</div>
</template>
<script setup>
import { computed, reactive } from 'vue'
const person = reactive({
name: '小明',
age: 18
})
// 声明methods方法
const nextYearAge = computed(() => {
return person.age + 1
})
</script>
4、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>
5、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>
6、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>
7、setup中自定义v-model
给组件自定义v-model,可以非常灵活和方便的给我们解决一些实际上的问题,而不需要父组件去监听子组件回传事件。想象一下,如果你用到了一个树形结构的组件,而你要改变树结构的某个节点的数据,如果你去emit回传的话,肯定还需要告诉父组件我修改的节点的对应的id,或者key什么的,而通过自定义v-model,你可以省去这些繁琐而复杂的操作,这一点是本人在实际项目中得到的经验,真的感觉非常有用。
我们看下在Vue3.0中如何自定义v-model。不同于Vue2.x,Vue3.0中我们可以定义多个v-model,而Vue2.x每个组件只能定义一个v-mdel。
// 父组件
<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数据类型,它
// 只是限制只能输入数字
好了,关于setup的用法先介绍这些,各位大佬如果发现错误或者补充的话请指正!!!不胜感激
接下来将会边学习边补充Vue3.0的各种知识点。谢谢!
更多推荐
所有评论(0)