vue3.x <script setup>单文件组件

相比普通script模板优点:
    更少的样板内容,更简洁的代码。
    能够使用纯 Typescript 声明 props 和抛出事件。
    更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
    更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)
  
1、使用:
	里面的代码会被编译成组件setup()函数的内容,会在每次组件实例被创建的时候执行
	与普通的<script>内的setup只在组件被首次引入的时候执行一次不同
	<script setup>
		console.log('hello script setup')
	</script>

2、任何在setup顶层声明的变量、组件、函数、import导入的内容,都能在template中直接使用

	<template>
	  <div>
	    {{ color }}
	    {{ ename }}
	    {{ capitalize('hello') }}
	    <MyComponent />
	    <h1 v-my-directive>This is a directive</h1>
	  </div>
	</template>
	<script setup lang='ts'>
	(1)导入内容
		import { capitalize } from './helpers'
	
	(2)导入组件
		import MyComponent from './MyComponent.vue'
	
	(3)变量等方式
		const color = ref("red");
		const ename = "click";
		
	(4)定义props和emits,在typescript下可直接使用ts类型语法,同时使用两种声明方式会导致编译报错
		
		.其他使用格式和选项式一致
		
		const props = defineProps({
		  foo: String
		})
		const emit = defineEmits(['change', 'delete'])
		
	(5)向外暴露setup的内容,默认不能通过ref等方式获取到setup中的内容
		defineExpose({...})
		
	(6)访问slots和attrs
		import { useSlots, useAttrs } from 'vue'
		
		能在普通的组合式API中使用
		const slots = useSlots()
		const attrs = useAttrs()
	
	(6.5)使用Promise
		可直接使用await,结果代码会被编译成async setup()
		const post = await fetch(`/api/post/1`).then(r => r.json())


	(7)自定义指令
		命名必须以v开头,使用时-分隔驼峰
		const vMyDirective = {
		  beforeMount: (el) => {
			...
		  }
		}
		导入的指令必须符合命名规范才能直接使用
		import { myDirective as vMyDirective } from './MyDirective.js'
	<script>
	
	(8)和普通<script>一起使用
		使用场景
			1、无法 <script setup>声明的选项
			2、声明命名导出
			3、运行副作用或者创建只需要执行一次的对象
			
		<script>
		fn() fn只会执行一次
		export default {
		  inheritAttrs: false,
		  customOptions: {}
		  和<script setup>一起出现时不支持使用render函数。
		}
		</script>
		
		<script setup>
		...
		</script>
	(9)不能使用src属性
		<script setup src='x/xx.js'> 不能使用src属性,普通script标签可以
	
	(10)响应式语法糖
		.不再需要手动调用.value,会在编译时自动添加.value
		.无需导入的宏函数
		
		(1)函数语法糖
			ref -> $ref
			computed -> $computed
			shallowRef -> $shallowRef
			customRef -> $customRef
			toRef -> $toRef
		
		(2)解构赋值语法糖:
			const { x, y } = $(useMouse())	会将解构赋值的内容都变成ref,而不需要手动再调用toRefs
			
			会被编译为:
				const __temp = useMouse(),
				x = toRef(__temp, 'x'),
				y = toRef(__temp, 'y')
				
				console.log(x.value, y.value)
		
		(3)响应式语法糖导致的缺点:
			(1)函数传递丢失响应性
				let count = $ref(0)
				trackChange(count)  无效!因为被编译成了trackChange(count.value)
				
				解决办法:
					trackChange($$(count))  $$()表示不会在ref对象后自动追加.value
			
			(2)函数返回值丢失响应性
				function useMouse() {
				  let x = $ref(0)
				  let y = $ref(0)
				
				  fn(...) 监听 mousemove 事件
				
				  // 不起效!
				  return {
				    x,	因为会被编译成x.value
				    y
				  }
				}
				
				解决办法:
					return $$({
					   x,
					   y
					})
					
			(4)$$()语法糖
				.除了上面的应用外还能将变量转换成ref变量,编译器会高效地通过 toRef 来做转换
				
				const { count } = defineProps<{ count: number }>()
				$$(count)

3、递归组件
	根据文件名使用,名为FooBar.vue的组件可以在其模板中用<FooBar/>引用它自己
	根据文件名推断的优先级低于其他引入方式,如果冲突可使用别名
		import { FooBar as FooBarChild } from './components'

4、在typescipt下才能使用的功能
	(1)props和emits
		const props = defineProps<{
		  foo: string
		  bar?: number
		}>()
		
		const emit = defineEmits<{
		  (e: 'change', id: number): void
		  (e: 'update', value: string): void
		}>()
	
	声明默认值
		withDefaults辅助函数提供了对默认值的类型检查,并确保返回的props的类型删除了已声明默认值的属性的可选标志
		interface Props {
		  msg?: string
		  labels?: string[]
		}
		
		const props = withDefaults(defineProps<Props>(), {
		  msg: 'hello',
		  labels: () => ['one', 'two']
		})
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值