setup函数在组件创建前执行,位于beforeCreated之前,用于代替created 和beforeCreated。 为vue3.0的Composition API提供了统一的入口。
那么什么是composition Api(组合式api)?
组合式API其实就是把之前Vue2分散在data、生命周期、watch、computed、methods中的部分现在全部整合到一起放到了setup中,这样的好处就是我们可以把一些业务或者逻辑抽离出来,然后那个地方需要就直接引入,比vue2中的方便了一些
期初vue3.0刚出来的时候,定义的变量都需要我们手动return出来,在加上了setup语法糖之后,就不需要return出去就可以直接再template内调用,组件也可以直接导入,无需注册就能掉用
基本语法
<template>
<div @clikc="onBtn">{{data}}</div>
</template>
<script lang="ts" setup>
// 1. 从 vue 中引入 ref 函数
import { ref } from 'vue'
export default ({
// 2.定义一个单值,响应式变量
const data = ref('这是一个标题')
// 3.方法也不需要return出去
const onBtn = () => {
console.log('事件')
}
})
</script>
组件使用
script-setup 无法指定当前组件的名字,所以使用的时候以文件名为主
<template>
<MyComponent />
</template>
<script lang="ts" setup>
import MyComponent from './MyComponent.vue'
</script>
组件传值
defineProps函数 ==> 父传子
父组件
<template>
<div class="die">
<h3>我是父组件</h3>
<zi-hello :name="name"></zi-hello>
</div>
</template>
<script lang="ts" setup>
import ziHello from './ziHello'
import {ref} from 'vue'
let name = ref('传给父组件的')
</script>
子组件
<template>
<div class="die">
<h3>我是子组件</h3>
{{ name }}
</div>
</template>
<script lang="ts" setup>
import { defineProps } from 'vue'
// 通过defineProps指定当前props类型的同时,获得上下文的props对象
defineProps({
name: {
type: String,
default: ''
}
})
}
</script>
defineEmits函数 ==> 子传父
子组件
<template>
<div>
我是子组件{{name}}
<button @click="ziupdata">按钮</button>
</div>
</template>
<script lang="ts" setup>
import {defineEmits} from 'vue'
//自定义函数,父组件可以触发
const em = defineEmits(['updata'])
const ziupdata=()=>{
em("updata",'我是子组件的值')
}
</script>
父组件
<template>
<div class="die">
<h3>我是父组件</h3>
<zi-hello @updata="updata"></zi-hello>
</div>
</template>
<script lang="ts" setup>
import ziHello from './ziHello'
const updata = (data) => {
console.log(data); //我是子组件的值
}
</script>
defineEpose函数 (组件暴露自己的属性) ==> 子传多
子组件
<template>
<div>
我是子组件
</div>
</template>
<script lang="ts" setup>
import {defineExpose,reactive,ref} from 'vue'
// ref声明响应式数据,用于声明非引用类型
let ziage=ref(18)
// reactive声明响应式数据,用于声明引用数据类型
let ziname=reactive({
name:'你的名字'
})
//暴露出去的变量
defineExpose({
ziage,
ziname
})
</script>
父组件
<template>
<div class="die">
<h3 @click="isclick">我是父组件</h3>
<zi-hello ref="hello"></zi-hello>
</div>
</template>
<script lang="ts" setup>
import {ref} from 'vue'
const zihello = ref()
const isclick = () => {
console.log('接收ref暴漏出来的值',hello.value.ziage)
console.log('接收reactive暴漏出来的值',hello.value.ziname.name)
}
</script>
defineEpose函数 (组件暴露自己的属性) ==> 子传多
子组件暴露自己的属性
<template>
<div>子组件helloword.vue</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const count = ref(123456)
defineExpose({
count
})
</script>
父组件获取属性
<template>
<div @click="helloClick">父组件</div>
<helloword ref="hello"></helloword>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import helloword from './components/HelloWorld.vue'
const hello = ref(null)
const helloClick = () => {
console.log(hello.value.count) // 123456
}
</script>
style v-bind
除了以上基本的Api外,在vue3.2中还新增了一个style v-bind的特性,在官网中被称为状态驱动的动态 CSS
<template>
<div>123</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
const state = reactive({
color: 'red'
})
</script>
<style>
div {
/* 使用v-bind绑定state中的变量 */
color: v-bind(state.color);
}
</style>
实际的值会被编译成 hash 的 CSS 自定义 property,CSS 本身仍然是静态的。自定义 property 会通过内联样式的方式应用到组件的根元素上,并且在源值变更的时候响应式更新。
computed API 在Vue3.0中的应用
<template>
<div>{{`${person.name}今年${person.age}岁, 明年${nextYearAge}岁`}}</div>
</template>
<script lang="ts" setup>
import { computed, reactive } from 'vue'
const person = reactive({
name: '你的名字',
age: 18
})
// 声明methods方法
const nextYearAge = computed(() => {
return person.age + 1
})
</script>
watch API 在Vue3.0中的应用
<template>
<div>{{`${person.name}今年${person.age}岁, 明年${nextYearAge}岁`}}</div>
<button @click="changeAge">加1岁</button>
</template>
<script lang="ts" 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(
() => person.age,
// change函数,监听值的变化
(newV, oldV) => {
console.log("当前值:" + person.age)
console.log("变化前:" + oldV)
console.log("变化后:" + newV)
},
{
immediate: true, // 立即执行
deep: true // 深度监听
}
)
</script>
监听多个值
watch([() => data.count, () => data.name],
([newcount, newname], [oldcount, oldname]) => {
console.log(newcount) // 新的count值
console.log(newname) // 新的name值
console.log(oldcount) // 旧的count值
console.log(oldname) // 旧的name值
}
)