> 웹 프론트엔드 > View.js > Vue3의 스크립트 설정 구문 설탕에 대한 자세한 설명

Vue3의 스크립트 설정 구문 설탕에 대한 자세한 설명

青灯夜游
풀어 주다: 2022-11-22 20:07:20
앞으로
3552명이 탐색했습니다.

Vue3의 스크립트 설정 구문 설탕에 대한 자세한 설명

스크립트 설정 구문 설탕

Composition API: setup()

기본 사용

Vue 3의 Composition API 시리즈는 새로운 setup code> 함수를 출시했습니다. 구성 요소 옵션이며 구성 요소가 생성되기 전, props가 구문 분석된 후 실행되고 구성된 API의 진입점 역할을 합니다. [학습 동영상 공유: <a href="https://www.php.cn/course/list/18.html" target="_blank" textvalue="vue 동영상 튜토리얼">vue 동영상 튜토리얼</a>, 웹 프런트엔드 동영상]<code>setup 函数,它是一个组件选项,在创建组件之前执行,一旦 props 被解析,并作为组合式 API 的入口点。【学习视频分享:vue视频教程web前端视频

setup 选项是一个接收 props 和 context 的函数,我们参考文档进行讨论。此外,我们将 setup 返回的所有内容都暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板。

<script>
// 这是一个基于 TypeScript 的 Vue 组件
import { defineComponent } from &#39;vue&#39;

export default defineComponent({
  setup(props, context) {
    // 在这里声明数据,或者编写函数并在这里执行它

    return {
      // 需要给 `<template />` 用的数据或函数,在这里 `return` 出去
    }
  },
})

</script>
로그인 후 복사

新的 setup 选项是在组件创建之前, props 被解析之后执行,是组合式 API 的入口。

注意:
setup 中你应该避免使用 this,因为它不会找到组件实例。setup 的调用发生在 data property、computed property 或 methods 被解析之前,所以它们无法>在 setup 中被获取。

在添加了setup的script标签中,我们不必声明和方法,这种写法会自动将所有顶级变量、函数,均会自动暴露给模板(template)使用
这里强调一句 “暴露给模板,跟暴露给外部不是一回事

TIP:说的通俗一点,就是在使用 Vue 3 生命周期的情况下,整个组件相关的业务代码,都可以放在 setup 里执行。

因为在 setup

< code>setup< /code> 옵션은 propscontext를 받는 함수입니다. a7b22d822ee95472ceccd763025cd194" title=" https://www.php.cn/link/a7b22d822ee95472ceccd763025cd194" target="_blank">문서를 참조하여 논의하세요. 또한 setup에서 반환된 모든 항목을 나머지 구성 요소(계산된 속성, 메서드, 수명 주기 후크 등)와 구성 요소의 템플릿에 노출합니다.

<script setup>
</script>
로그인 후 복사
로그인 후 복사
새로운 setup 옵션은 컴포넌트가 생성되기 전props가 파싱된 후에 실행되며, 이는 결합된 API의 입구입니다.

참고:
설정에서 this를 사용하면 구성 요소 인스턴스를 찾을 수 없으므로 사용하지 않는 것이 좋습니다. setup에 대한 호출은 data 속성, computed 속성 또는 methods가 구문 분석되기 전에 발생하므로 획득할 수 없습니다. 설정에서.

설정이 추가된 스크립트 태그에서는 메소드를 선언할 필요가 없습니다. 이 작성 방법은 모든 최상위 변수와 함수를 템플릿에 자동으로 노출하여 사용합니다
여기서는 ""라는 점을 강조합니다더 쉽게 말하면 Vue 3 라이프사이클을 사용할 때 전체 컴포넌트는 관련 모든 비즈니스 코드는 설정에서 실행할 수 있습니다. 설정 후에 다른 라이프사이클이 활성화되므로 Vue2의 Vue3 라이프사이클 변경 사항을 비교해 보겠습니다. Vue 라이프사이클 변경 사항에 대해서는 다음과 같이 할 수 있습니다. 다음 표를 통해 직관적으로 이해하세요. 컴포넌트 생성 전 실행컴포넌트 생성 후 실행노드에 컴포넌트가 마운트되기 전에 실행컴포넌트 마운트 후 실행컴포넌트 업데이트 전 실행컴포넌트 업데이트 완료 후 실행컴포넌트 제거 전 실행
템플릿에 노출되는 것과 외부에 노출되는 것은 다르다TIP:
Component 라이프사이클
Vue 2 라이프사이클 Vue 3 라이프사이클 실행 시간 설명
beforeCreatesetup
생성됨 setup
beforeMountonBeforeMount
mountedonMounted
업데이트 전 onBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
🎜🎜destroyed🎜 🎜onUnmounted🎜🎜다음 이후에 실행됨 구성요소가 제거되었습니다🎜 🎜🎜🎜errorCaptured🎜🎜onErrorCaptured🎜🎜하위 구성요소에서 예외를 포착할 때 후크 기능이 활성화되었습니다🎜🎜🎜🎜

可以看到 Vue 2 生命周期里的 beforeCreatecreated ,在 Vue 3 里已被 setup 替代。

script setup 语法糖

它是 Vue3 的一个新语法糖,在 setup 函数中。所有 ES 模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。相对于之前的写法,使用后,语法也变得更简单。

自动注册属性和方法无需返回,直接使用

1.<script setup> 语法糖并不是新增的功能模块,它只是简化了以往的组合API(compositionApi)的必须返回(return)的写法,并且有更好的运行时性能。

2.在 setup 函数中:所有 ES 模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。相对于之前的写法,使用后,语法也变得更简单。

你不必担心setup语法糖的学习成本,他是组合式API的简化,并没有新增的知识点。你只需要了解一些用法和细微的不同之处,甚至比之前写setup()还要顺手!

使用方式也很简单,只需要在 script 标签加上 setup 关键字即可

<script setup>
</script>
로그인 후 복사
로그인 후 복사

组件核心 API 的使用

组件自动注册

在 script setup 中,引入的组件可以直接使用,无需再通过components进行注册,并且无法指定当前组件的名字,它会自动以文件名为主,也就是不用再写name属性了。

示例

<template>
	<Child />
</template>

<script setup>
import Child from &#39;@/components/Child.vue&#39;
</script>
로그인 후 복사

定义组件的 props

defineProps ----> [用来接收父组件传来的 props] 代码示列

通过defineProps指定当前 props 类型,获得上下文的props对象。

示例:

<script setup>
  import { defineProps } from &#39;vue&#39;

  const props = defineProps({
    title: String,
  })
</script>
<!-- 或者 -->
<script setup> 
    import { ref,defineProps } from &#39;vue&#39;;
    
    type Props={ 
        msg:string 
    }
    defineProps<Props>(); 
</script>
로그인 후 복사

定义 emit

defineEmit ----> [子组件向父组件事件传递]

使用defineEmit定义当前组件含有的事件,并通过返回的上下文去执行 emit。

代码示列

<script setup>
  import { defineEmits } from &#39;vue&#39;
  const emit = defineEmits([&#39;change&#39;, &#39;delete&#39;])
  
</script>
로그인 후 복사

父子组件通信

defineProps 用来接收父组件传来的 props ; defineEmits 用来声明触发的事件。

//父组件
<template>
	<Child @getChild="getChild" :title="msg" />
</template>

<script setup>
import { ref } from &#39;vue&#39;
import Child from &#39;@/components/Child.vue&#39;
const msg = ref(&#39;parent value&#39;)
const getChild = (e) => {
	// 接收父组件传递过来的数据
	console.log(e); // child value
}
</script>
로그인 후 복사
//子组件
<template>
	<div @click="toEmits">Child Components</div>
</template>

<script setup>
// defineEmits,defineProps无需导入,直接使用
const emits = defineEmits([&#39;getChild&#39;]);
const props = defineProps({
	title: {
		type: String,
		defaule: &#39;defaule title&#39;
	}
});

const toEmits = () => {
	emits(&#39;getChild&#39;, &#39;child value&#39;) // 向父组件传递数据
}

// 获取父组件传递过来的数据
console.log(props.title); // parent value
</script>
로그인 후 복사

子组件通过 defineProps 接收父组件传过来的数据,子组件通过 defineEmits 定义事件发送信息给父组件

useSlots()useAttrs()

获取 slots 和 attrs

注:useContext API 被弃用,取而代之的是更加细分的 api。

可以通过useContext从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrsuseSlots

  • useAttrs:见名知意,这是用来获取 attrs 数据,但是这和 vue2 不同,里面包含了 class属性方法

<template>
    <component v-bind=&#39;attrs&#39;></component>
</template>
<srcipt setup>
   const attrs = useAttrs();
<script>
로그인 후 복사
  • useSlots: 顾名思义,获取插槽数据。

使用示例:

// 旧
<script setup>
  import { useContext } from &#39;vue&#39;

  const { slots, attrs } = useContext()
</script>

// 新
<script setup>
  import { useAttrs, useSlots } from &#39;vue&#39;

  const attrs = useAttrs()
  const slots = useSlots()
</script>
로그인 후 복사

defineExpose API

defineExpose ----> [组件暴露出自己的属性]

传统的写法,我们可以在父组件中,通过 ref 实例的方式去访问子组件的内容,但在 script setup 中,该方法就不能用了,setup 相当于是一个闭包,除了内部的 template模板,谁都不能访问内部的数据和方法。

<script setup> 的组件默认不会对外部暴露任何内部声明的属性。
如果有部分属性要暴露出去,可以使用 defineExpose

注意:目前发现defineExpose暴露出去的属性以及方法都是 unknown 类型,如果有修正类型的方法,欢迎评论区补充。

如果需要对外暴露 setup 中的数据和方法,需要使用 defineExpose API。示例

//子组件

<template>
	{{msg}}
</template>

<script setup>
import { ref } from &#39;vue&#39;

let msg = ref("Child Components");
let num = ref(123);

// defineExpose无需导入,直接使用
defineExpose({
	msg,
	num
});
</script>
로그인 후 복사
//父组件
<template>
	<Child ref="child" />
</template>

<script setup>
import { ref, onMounted } from &#39;vue&#39;
import Child from &#39;@/components/Child.vue&#39;

let child = ref(null);

onMounted(() => {
	console.log(child.value.msg); // Child Components
	console.log(child.value.num); // 123
})
</script>
로그인 후 복사

定义响应变量、函数、监听、计算属性computed

<script setup > 
import { ref,computed,watchEffect } from &#39;vue&#39;;

const count = ref(0); //不用 return ,直接在 templete 中使用

const addCount=()=>{ //定义函数,使用同上 
    count.value++; 
} 

//创建一个只读的计算属性 ref:
const plusOne = computed(() => count.value + 1)

// 创建一个可写的计算属性 ref
const plusOne = computed({
get: () => count.value + 1, 
set: (val) => { count.value = val - 1 } 
})


//定义监听,使用同上 //...some code else 
watchEffect(()=>console.log(count.value)); 
</script>
로그인 후 복사

watchEffect和watch区别

1、watch是惰性执行,也就是只有监听的值发生变化的时候才会执行,但是watchEffect不同,每次代码加载watchEffect都会执行(忽略watch第三个参数的配置,如果修改配置项也可以实现立即执行)

2、watch需要传递监听的对象,watchEffect不需要

3、watch只能监听响应式数据:ref定义的属性和reactive定义的对象,如果直接监听reactive定义对象中的属性是不允许的,除非使用函数转换一下

4、watchEffect如果监听reactive定义的对象是不起作用的,只能监听对象中的属性。

reactive

返回一个对象的响应式代理。

<script setup>
import { reactive, onUnmounted } from &#39;vue&#39;

const state = reactive({
    counter: 0
})
// 定时器 每秒都会更新数据
const timer = setInterval(() => {
    state.counter++
}, 1000);

onUnmounted(() => {
    clearInterval(timer);
})
</script>
<template>
    <div>{{state.counter}}</div>
</template>
로그인 후 복사

使用ref也能达到我们预期的'counter',并且在模板中,vue进行了处理,我们可以直接使用counter而不用写counter.value.

ref和reactive的关系:

ref是一个{value:'xxxx'}的结构,value是一个reactive对象

ref 暴露变量到模板

曾经的提案中,如果需要暴露变量到模板,需要在变量前加入export声明:

export const count = ref(0)
로그인 후 복사

不过在新版的提案中,无需export声明,编译器会自动寻找模板中使用的变量,只需像下面这样简单的声明,即可在模板中使用该变量

<script setup >
import { ref } from &#39;vue&#39;

const counter = ref(0);//不用 return ,直接在 templete 中使用

const timer = setInterval(() => {
    counter.value++
}, 1000)

onUnmounted(() => {
    clearInterval(timer);
})
</script>
<template>
    <div>{{counter}}</div>
</template>
로그인 후 복사

其他 Hook Api

  • useCSSModule:CSS Modules 是一种 CSS 的模块化和组合系统。vue-loader 集成 CSS Modules,可以作为模拟 scoped CSS。允许在单个文件组件的setup中访问CSS模块。此 api 本人用的比较少,不过多做介绍。

  • useCssVars: 此 api 暂时资料比较少。介绍v-bind in styles时提到过。

  • useTransitionState: 此 api 暂时资料比较少。

  • useSSRContext: 此 api 暂时资料比较少。

支持 async await 异步

注意在vue3的源代码中,setup执行完毕,函数 getCurrentInstance 内部的有个值会释放对 currentInstance 的引用,await 语句会导致后续代码进入异步执行的情况。所以上述例子中最后一个 getCurrentInstance() 会返回 null,建议使用变量保存第一个 getCurrentInstance() 返回的引用.

<script setup>
  const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>
로그인 후 복사

<script setup> 中可以使用顶层 await。结果代码会被编译成 async setup()

<script setup>
const post = await fetch(`/api/post/1`).then(r => r.json())
</script>
로그인 후 복사

另外,await 的表达式会自动编译成在 await 之后保留当前组件实例上下文的格式。

注意
async setup() 必须与 Suspense 组合使用,Suspense 目前还是处于实验阶段的特性。我们打算在将来的某个发布版本中开发完成并提供文档 - 如果你现在感兴趣,可以参照 tests 看它是如何工作的。

定义组件其他配置

配置项的缺失,有时候我们需要更改组件选项,在setup中我们目前是无法做到的。我们需要在上方再引入一个 script,在上方写入对应的 export即可,需要单开一个 script。

<script setup> 可以和普通的 <script> 一起使用。普通的 <script> 在有这些需要的情况下或许会被使用到:

  • 无法在 <script setup> 声明的选项,例如 inheritAttrs 或通过插件启用的自定义的选项。
  • 声明命名导出。
  • 运行副作用或者创建只需要执行一次的对象。

在script setup 外使用export default,其内容会被处理后放入原组件声明字段。

<script>
// 普通 `<script>`, 在模块范围下执行(只执行一次)
runSideEffectOnce()

// 声明额外的选项
  export default {
    name: "MyComponent",
    inheritAttrs: false,
    customOptions: {}
  }
</script>
<script setup>
    import HelloWorld from &#39;../components/HelloWorld.vue&#39;
    // 在 setup() 作用域中执行 (对每个实例皆如此)
    // your code
</script>
<template>
  <div>
    <HelloWorld msg="Vue3 + TypeScript + Vite"/>
  </div>
</template>
로그인 후 복사

注意:Vue 3 SFC 一般会自动从组件的文件名推断出组件的 name。在大多数情况下,不需要明确的 name 声明。唯一需要的情况是当你需要 <keep-alive> 包含或排除或直接检查组件的选项时,你需要这个名字。

(학습 영상 공유: 웹 프론트엔드 개발, 기본 프로그래밍 영상)

위 내용은 Vue3의 스크립트 설정 구문 설탕에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿