要使用Vue3,那必须得会setup,因为setup是组合式API表演的舞台。
安装volar
如果你的VScode之前安装有vuter插件,请先把他禁用或者卸载掉,然后安装volar。
因为,vuter
插件是针对Vue2的,而Vue3的写法跟Vue3是有区别的,特别是使用setup语法糖之后,所以写代码的时候可能会有报错。
volar
插件则是针对Vue3的。安装之后就不报错,而且有提示出来。而且点击右上角的小图标,还可以将html代码、js代码和css代码做分开展示。
一、Vue3中变量和方法
1.1 之前的用法
通过这个例子,我们可以知道,Vue3中HTML模板不再需要一个根标签了,数据也不用在data中定义,方法也不需要在methods中定义。而且,模板中需要的数据、方法必须在setup中返回(return)。
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击了 {{ count }} 次了</button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
let count = ref(0)
const increment = () => {
count.value ++
}
/*不使用script-srtup语法糖需要导出需要在template使用的变量和方法*/
return {
count,
increment
}
}
}
</script>
1.2 现在的用法(setup语法糖)
在<script setup>
中,需要在script标签加上setup属性,就不再需要写setup函数,而且模板中用到的变量和方法不需要返回(return)。使用setup语法糖后变量和方法已不再需要return出去才能被template使用了,减少了代码量,看起来更加的美观。
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击 {{ count }} 次了</button>
</template>
<script setup>
import { ref } from 'vue'
let count = ref(0)
const increment = () => {
count.value ++
}
</script>
二、Vue3中使用组件
2.1之前的用法
// App.vue
<template>
<demo />
</template>
<script>
import Demo from './components/Demo.vue'
export default {
components: { Demo }
}
</script>
2.2现在的用法(setup语法糖)
在<script setup>
中,只需要在引入组件即可在模板中使用,不再需要自己去注册组件。
// App.vue
<template>
<demo />
</template>
<script setup>
import Demo from './components/Demo.vue'
</script>
三、Vue3中父传子接收Props --> defineProps()
3.1之前的用法
传递数据给组件,传递的方式不变,接收时,需要在props中定义接收。setup函数被调用接收到的以第一个参数就是props。
// App.vue
<template>
<demo msg="hi Demo, I'm your father!"/>
</template>
<script setup>
import Demo from './components/Demo.vue'
</script>
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击 {{ count }} 次了</button>
<h3>{{msg}}</h3>
</template>
<script>
import { ref } from 'vue'
export default {
props: {
msg: {
type: String
}
},
setup(props) {
let count = ref(0)
const increment = () => {
count.value ++
}
return {
count,
increment
}
}
}
</script>
3.2现在的用法(setup语法糖)
在<script setup>
中,我们没有机会写setup函数,就接收不到他调用时传递的参数。所以有一个新的APIdefineProps
它是一个函数。defineProps
会返回一个对象,其中包含了可以传递给组件的所有 props
。
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击 {{ count }} 次了</button>
<h3>{{msg}}</h3>
</template>
<script setup>
import { ref, defineProps } from 'vue'
const props = defineProps(['msg'])
let count = ref(0)
const increment = () => {
count.value ++
}
</script>
四、Vue3中子传父emit自定义事件 --> defineEmits()
4.1之前的用法
子组件射出自定义事件给父组件,则需要通过emits
定义好要传递的事件,setup
函数中的第二个参数就是上下文对象centext
(这里我们不详细介绍了),然后通过这个对象去调用emit
方法就可以射出自定义事件了。
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击 {{ count }} 次了</button>
<h3>{{msg}}</h3>
</template>
<script>
import { ref } from 'vue'
export default {
props: {
msg: {
type: String
}
},
emits: ['hanlde-count'],
setup(props, centext) {
let count = ref(0)
const increment = () => {
count.value ++
centext.emit('hanlde-count', count.value)
}
console.log(props.msg)
return {
count,
increment
}
}
}
</script>
// App.vue
<template>
<demo
msg="hi Demo, I'm your father!"
@hanlde-count="hanldeCount"
/>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
components: { Demo },
setup() {
const hanldeCount = count => {
console.log(count)
}
return{
hanldeCount
}
}
}
</script>
4.2现在的用法(setup语法糖)
在<script setup>
中,子组件想要射出自定义事件时,则需要通过defineEmits
来定义自定义事件。
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击{{ count }} 次了</button>
<h3>{{msg}}</h3>
</template>
<script setup>
import { ref, defineProps, defineEmits } from 'vue'
const props = defineProps(['msg'])
const emit = defineEmits(['hanlde-count'])
console.log(props.msg)
let count = ref(0)
const increment = () => {
count.value ++
emit('hanlde-count', count.value)
}
</script>
五、Vue3中父组件获取组件的数据或方法 --> defineExpose()
5.1之前的用法
在子组件中,暴露组件变量或者方法时,不用做其他操作,只需要确保setup函数中return该变量或方法。因为在script标签中所有代码都使用expost default暴露了。而在父组件中需要通过给子组件添加ref属性,然后在onMounted生命周期函数中获取子组件的dom即可获得子组件的变量和方法。
注意:获取dom是,一定在onMounted声明周期获取,因为页面没有渲染,就获取不要dom
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击 {{ count }} 次了</button>
<h3>{{msg}}</h3>
</template>
<script>
import { ref } from 'vue'
export default {
props: ['msg'],
emits: ['hanlde-count'],
setup(props, context) {
let count = ref(0)
const name = ref('vernin')
const increment = () => {
count.value ++
context.emit('hanlde-count', count.value)
}
return {
count,
increment,
name
}
}
}
</script>
// App.vue
<template>
<demo
ref="demo"
msg="hi Demo, I'm your father!"
@hanlde-count="hanldeCount"
/>
</template>
<script>
import Demo from './components/Demo.vue'
import { ref, onMounted } from 'vue'
export default {
components: { Demo },
setup() {
const demo = ref(null) // 记得把 demo return 出去
// 错误写法:setup 函数无法获取dom -- setup相对于vue2的created钩子
// console.log(demo.value.name) // 报错
// console.log(demo.value.count) // 报错
// 正确写法:
onMounted(() => {
console.log('子组件Demo的count:', demo.value.count)
console.log('子组件Demo的name:', demo.value.name)
})
const hanldeCount = count => {
console.log(count)
}
return {
demo,
hanldeCount
}
}
}
</script>
5.2现在的用法(setup语法糖)
在<script setup>
中,没有写export default
暴露,为了在组件中明确要暴露出去的变量或方法,需要使用defineExpose
来变量,在父组件中,也是通过给子组件ref
属性获取。
// components/Demo.vue
<template>
<h2>Vue3.2中setup语法糖的使用</h2>
<button @click="increment">点击 {{ count }} 次了</button>
<h3>{{msg}}</h3>
</template>
<script setup>
import { ref, defineProps, defineEmits, defineExpose } from 'vue'
const props = defineProps(['msg'])
const emit = defineEmits(['hanlde-count'])
let count = ref(0)
const increment = () => {
count.value ++
emit('hanlde-count', count.value)
}
const name = ref('vernin')
defineExpose({
name,
count
})
</script>
// App.vue
<template>
<demo
ref="demo"
msg="hi Demo, I'm your father!"
@hanlde-count="hanldeCount"
/>
</template>
<script setup>
import Demo from './components/Demo.vue'
import { ref, onMounted } from 'vue'
const demo = ref(null)
onMounted(() => {
console.log('子组件Demo的count:', demo.value.count)
console.log('子组件Demo的name:',demo.value.name)
})
const hanldeCount = count => {
console.log(count)
}
</script>
总结
使用setup语法糖和setup函数对比,我们不难看出,使用语法糖是,代码整洁了好多,不会有那么多的对象嵌套。也不用做什么额外的return,代码也简化了不少。