1、语法糖与非语法糖代码写法对比
<script lang="ts">
import { toRefs, reactive } from 'vue'
import navBar from '@/components/public/navBar.vue'
import foot from '@/components/public/foot.vue'
import productList from './components/product-list.vue'
/**
* 普通写法非语法糖
*/
export default {
name: '',
props: {},
components: { navBar, foot, productList },
setup() {
// 传参
const state = reactive({
navTitle: [{ name: '题目' }, { name: '题目' }, { name: '题目' }, { name: '题目' }, { name: '题目' }],
mousee: '',
mouseeIndex: 0,
})
const mouseenter = (data: any, index: number) => {
state.mousee = data
state.mouseeIndex = index
console.log("? ~ file: index.vue ~ line 102 ~ mouseenter ~ state.mousee", state.mousee, index)
}
const mouseleave = () => {
state.mousee = ''
}
return {
...toRefs(state),
mouseenter,
mouseleave
}
}
}
</script>
/**
* setup语法糖写法
*/
<script lang="ts" setup>
import { toRefs, reactive } from 'vue'
import navBar from '@/components/public/navBar.vue'
import foot from '@/components/public/foot.vue'
import productList from './components/product-list.vue'
const state = reactive({
navTitle: [{ name: '题目' }, { name: '题目' }, { name: '题目' }, { name: '题目' }, { name: '题目' }],
mousee: '',
mouseeIndex: 0,
})
const mouseenter = (data: any, index: number) => {
state.mousee = data
state.mouseeIndex = index
console.log("? ~ file: index.vue ~ line 102 ~ mouseenter ~ state.mousee", state.mousee, index)
}
const mouseleave = () => {
state.mousee = ''
}
let { navTitle, mousee, mouseeIndex } = toRefs(state) // 使用toRefs
</script>
2、如何在setup语法糖中使用props和配置TS使用(首先需要在<script setup>中使用defineProps来声明props,它具备完整的类型推断并且在<script setup>中是直接可用的)
/**
*非setup语法糖使用props
*/
<script>
export default {
props: ['more'],
}
</script>
/**
*setup语法糖使用props
*/
<script lang="ts" setup>
import { reactive } from 'vue'
/**
* 普通获取props数据
*/
const props = defineProps({
more: {
type: Object,
default: {
title: '',
subhead: '',
isMore: '',
isMoreUrl: ''
}
}
//或者:more: Object,more: {},虽然能正常使用但是页面使用的时候ts会报错未定义或者unknow
})
/**
* TS获取props数据
*/
const props = defineProps<{
more: Object
}>()
/**
* TS获取props数据(默认值)
* 引用:https://www.jianshu.com/p/102906089ab9
* withDefaults 用于defineProps绑定默认值的api
* defineProps 只能是要么使用运行时声明,要么使用typescript类型声明。同时使用两种声明方式会导致编译报错。
* defineProps、withDefaults 是只在 <script setup> 语法糖中才能使用的编译器宏。他不需要导入且会随着 <script setup> 处理过程一同被编译掉。
* 运行时声明 的方式只能设置参数类型、默认值、是否必传、自定义验证。
* 若想设置[ 编辑器报错、编辑器语法提示 ]则需要使用类型声明的方式。
*/
interface Props {
more?: {// 设置好类型定义
title: string,
subhead: string,
isMore: string,
isMoreUrl: string
}
}
/**
* 可以给定默认值
*/
const props = withDefaults(defineProps<Props>(), {
more: () => {
return {
title: '',
subhead: '',
isMore: '',
isMoreUrl: ''
}
}
})
</script>
3、如何在setup语法糖中使用emit和配置TS使用(首先需要在<script setup>中使用defineEmits来声明emits,它具备完整的类型推断并且在<script setup>中是直接可用的)
// 父组件调用子组件
<subheading @testEmits="testEmits"/>
// 父组件方法测试emits
const testEmits = (type: String) => {
console.log('我是测试emits:', type)
}
/**
* 子组件调用在非setup语法糖下
*/
<script>
export default {
emits: ['testEmits'],
emit('testEmits', '我是子组件调用的')
}
}
</script>
/**
* 子组件调用在setup语法糖下
*/
<script setup lang='ts'>
import { defineEmits } from 'vue'
const emit = defineEmits(['testEmit']) // 可以接收多个
emit('testEmit', '我是子组件调用')
// 在ts下使用
const emit = defineEmits<{ // 类型声明
(e: 'testEmit', value: String): void
}>()
emit('testEmit', 'test')
</script>
3、使用defineExpose(使用<script setup>的组件是默认关闭的,也即通过模板ref或者$parent链获取到的组件的公开实例,不会暴露任何在<script setup>中声明的绑定)
<script setup lang="ts">
import { ref } from 'vue'
const count = ref('我是子组件传递的值')
defineExpose({
count
})
</script>
<template>
<div @click="childClick">⽗组件</div>
<child ref="child" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import child from './components/child.vue'
const child = ref(null)
const childClick = () => {
console.log(child.value.count) // 我是子组件传递的值
}
</script>
评论 (0)