您好,登錄后才能下訂單哦!
這篇“Vue3如何使用setup語法糖拒絕寫return”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Vue3如何使用setup語法糖拒絕寫return”文章吧。
<script setup>
是在單文件組件 (SFC) 中使用組合式 API 的編譯時語法糖
解決Vue3.0中setup需要繁瑣將聲明的變量、函數以及 import 引入的內容通過return向外暴露,才能在<template/>
使用的問題
<script setup>
中無需return 聲明的變量、函數以及import引入的內容,即可在<template/>
使用
<script setup>
語法糖
<script setup> //import引入的內容 import { getToday } from './utils' // 變量 const msg = 'Hello!' // 函數 function log() { console.log(msg) } </script> //在template中直接使用聲明的變量、函數以及import引入的內容 <template> <div @click="log">{{ msg }}</div> <p>{{getToday()}}</p> </template>
標準組件<script>
需要寫setup函數并繁瑣retrun
<script> //import引入的內容 import { getToday } from './utils' export default{ setup(){ // 變量 const msg = 'Hello!' // 函數 function log() { console.log(msg) } //想在tempate里面使用需要在setup內return暴露出來 return{ msg, log, getToday } } } </script> <template> <div @click="log">{{ msg }}</div> <p>{{getToday()}}</p> </template>
小結:<script setup>
語法糖里面的代碼會被編譯成組件 setup()
函數的內容,不需要通過return暴露 聲明的變量、函數以及import引入的內容,即可在<template/>
使用,并且不需要寫export default{}
<script setup>
語法糖里面的代碼會被編譯成組件 setup()
函數的內容。這意味著與普通的 <script>
只在組件被首次引入的時候執行一次不同,<script setup>
中的代碼會在每次組件實例被創建的時候執行
<script> console.log('script');//多次實例組件,只觸發一次 export default { setup() { console.log('setupFn');//每次實例化組件都觸發和script-setup標簽一樣 } } </script>
(script-setup標簽最終都會編譯成setup()
函數的內容,每次實例化組件,就是實例化一次setup函數。script標簽里面的setup函數也是一樣每次實例化組件,就是實例化一次setup函數,但是script標簽setup是需要寫在export default{}內的,外的只是首次引入的時候執行一次)
不需要在引入組件后,通過 components:{}
注冊組件,可直接使用
<script setup> import MyComponent from './MyComponent.vue' //components:{MyComponent} 不需要注冊直接使用 </script> <template> <MyComponent /> </template>
在<script setup>
中必須使用 defineProps
和 defineEmits
API 來替代 props 和 emits
defineProps
和defineEmits
具備完整的類型推斷并且在<script setup>
中是直接可用的(瀏覽了一下掘金,發現大部分文章demo還是通過import引入這2個api,這點官方文檔寫得很清楚)
接收父組件傳遞的數據(父組件向子組件傳參)
父組件:
<template> <div>父組件</div> <Child :title="msg" /> </template> <script setup> import {ref} from 'vue' import Child from './child.vue' const msg = ref('父的值') //自動返回,在template直接解套使用 </script>
子組件:
<template/>
中可以直接使用父組件傳遞的props (可省略props.)
<script-setup>
需要通過props.xx獲取父組件傳遞過來的props
<template> <div>子組件</div> <div>父組件傳遞的值:{{title}}</div> </template> <script setup> //import {defineProps} from 'vue' 不需要引入 //語法糖必須使用defineProps替代props const props = defineProps({ title: { type: String } }); //script-setup 需要通過props.xx獲取父組件傳遞過來的props console.log(props.title) //父的值 </script>
子組件向父組件傳遞數據(子組件向外暴露數據)
子組件代碼:
<template> <div>子組件</div> <button @click="toEmits">子組件向外暴露數據</button> </template> <script setup> import {ref} from 'vue' const name = ref('我是子組件') //1、暴露內部數據 const emits = defineEmits(['childFn']); const toEmits = () => { //2、觸發父組件中暴露的childFn方法并攜帶數據 emits('childFn',name) } </script>
父組件代碼:
<template> <div>父組件</div> <Child @childFn='childFn' /> <p>接收子組件傳遞的數據{{childData}} </p> </template> <script setup> import {ref} from 'vue' import Child from './child.vue' const childData = ref(null) const childFn=(e)=>{ consloe.log('子組件觸發了父組件childFn,并傳遞了參數e') childData=e.value } </script>
使用 <script setup>
的組件,父組件是無法通過ref 或者 $parent
獲取到子組件的ref等響應數據,需要通過defineExpose 主動暴露
子組件代碼:
<script setup> import { ref } from 'vue' const a = 1 const b = ref(2) //主動暴露組件屬性 defineExpose({ a, b }) </script>
父組件代碼:
<template> <div>父組件</div> <Child ref='childRef' /> <button @click='getChildData'>通過ref獲取子組件的屬性 </button> </template> <script setup> import {ref} from 'vue' import Child from './child.vue' const childRef= ref() //注冊響應數據 const getChildData =()=>{ //子組件接收暴露出來得值 console.log(childRef.value.a) //1 console.log(childRef.value.b) //2 響應式數據 } </script>
useSlots
和 useAttrs
(少用,由于大部分人是SFC模式開發,在<template/>
通過<slot/>
標簽就可以渲染插槽)
如果需要在script-setup
中使用 slots
和 attrs
需要用useSlots
和 useAttrs
替代
需要引入:import { useSlots ,useAttrs } form 'vue'
在<template/>
中通過 $slots
和 $attrs
來訪問更方便(attrs用來獲取父組件中非props的傳遞到子組件的參數/方法,attrs 用來獲取父組件中非props的傳遞到子組件的參數/方法,attrs用來獲取父組件中非props的傳遞到子組件的參數/方法,slots可以獲取父組件中插槽傳遞的虛擬dom對象,在SFC模式應該用處不大,在JSX /TSX使用比較多)
父組件:
<template> <Child msg="非porps傳值子組件用attrs接收" > <!-- 匿名插槽 --> <span >默認插槽</span> <!-- 具名插槽 --> <template #title> <h3>具名插槽</h3> </template> <!-- 作用域插槽 --> <template #footer="{ scope }"> <footer>作用域插槽——姓名:{{ scope.name }},年齡{{ scope.age }}</footer> </template> </Child> </template> <script setup> // 引入子組件 import Child from './child.vue' </script>
子組件:
<template> <!-- 匿名插槽 --> <slot /> <!-- 具名插槽 --> <slot name="title" /> <!-- 作用域插槽 --> <slot name="footer" :scope="state" /> <!-- $attrs 用來獲取父組件中非props的傳遞到子組件的參數 --> <p>{{ attrs.msg == $attrs.msg }}</p> <!--true 沒想到有啥作用... --> <p>{{ slots == $slots }}</p> </template> <script setup> import { useSlots, useAttrs, reactive, toRef } from 'vue' const state = reactive({ name: '張三', age: '18' }) const slots = useSlots() console.log(slots.default()); //獲取到默認插槽的虛擬dom對象 console.log(slots.title()); //獲取到具名title插槽的虛擬dom對象 // console.log(slots.footer()); //報錯 不知道為啥有插槽作用域的無法獲取 //useAttrs() 用來獲取父組件傳遞的過來的屬性數據的(也就是非 props 的屬性值)。 const attrs = useAttrs() </script>
useSlots或許在JSX/TSX下更實用
想使用JSX語法在vite需要下載相關jsx的plugins才能識別jsx
useSlots 可以獲取父組件傳遞過來插槽的虛擬dom對象,可以用來渲染插槽內容
<script lang='jsx'> import { defineComponent, useSlots } from "vue"; export default defineComponent({ setup() { // 獲取插槽數據 const slots = useSlots(); // 渲染組件 return () => ( <div> {slots.default?slots.default():''} {slots.title?slots.title():''} </div> ); }, }); </script>
大部分人是SFC模式開發,在<template/>
通過<slot/>
標簽就可以渲染插槽,這種JSX 的寫法應該是很少人會使用的
訪問路由實例組件信息:route和router
setup
里不能訪問 this
,不能再直接訪問 this.$router
或 this.$route
。(getCurrentInstance可以替代this但不推薦)
推薦:使用useRoute
函數和useRouter
函數替代this.$route
和 this.$router
<script setup> import { useRouter, useRoute } from 'vue-router' const route = useRoute() const router = useRouter() function pushWithQuery(query) { router.push({ name: 'search', query: { ...route.query, }, }) } <script/>
導航守衛
仍然可以使用路由實例組件的導航守衛
import router from './router' router.beforeEach((to,from,next)=>{ })
也可以使用組合式api的導航守衛onBeforeRouteLeave, onBeforeRouteUpdate
<script setup> import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' // 與 beforeRouteLeave 相同,無法訪問 `this` onBeforeRouteLeave((to, from) => { const answer = window.confirm( 'Do you really want to leave? you have unsaved changes!' ) // 取消導航并停留在同一頁面上 if (!answer) return false }) const userData = ref() // 與 beforeRouteUpdate 相同,無法訪問 `this` onBeforeRouteUpdate(async (to, from) => { //僅當 id 更改時才獲取用戶,例如僅 query 或 hash 值已更改 if (to.params.id !== from.params.id) { userData.value = await fetchUser(to.params.id) } }) <script/>
組合式 API 守衛也可以用在任何由 `<router-view>` 渲染的組件中,它們不必像組件內守衛那樣直接用在路由組件上。
以上就是關于“Vue3如何使用setup語法糖拒絕寫return”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。