目錄
Vue3.2 setup语法糖
1.<script setup>在<template/>使用
2、<script setup>引入组件将自动注册
3、组件通信:
defineProps 代替props
defineEmit 代替emit
4.<script setup>需主动向父组件暴露子组件属性 :defineExpose
5.语法糖其他功能
6.在setup访问路由
首頁 web前端 Vue.js Vue3怎麼使用setup語法糖拒絕寫return

Vue3怎麼使用setup語法糖拒絕寫return

May 12, 2023 pm 06:34 PM
vue3 return setup

    Vue3.2 setup语法糖

    <script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖

    解决Vue3.0中setup需要繁琐将声明的变量、函数以及 import 引入的内容通过return向外暴露,才能在<template/>使用的问题

    1.<script setup>在<template/>使用

    <script setup>中无需return 声明的变量、函数以及import引入的内容,即可在<template/>使用

    <script setup>语法糖

    <script setup>
    //import引入的内容
    import { getToday } from &#39;./utils&#39;  
    // 变量
    const msg = &#39;Hello!&#39;
    // 函数
    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 &#39;./utils&#39;  
    export default{
     setup(){
        // 变量
        const msg = &#39;Hello!&#39;
        // 函数
        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(&#39;script&#39;);//多次实例组件,只触发一次
      export default {
          setup() {
              console.log(&#39;setupFn&#39;);//每次实例化组件都触发和script-setup标签一样
          }
      }
      </script>
    登入後複製

    (script-setup标签最终都会编译成setup() 函数的内容,每次实例化组件,就是实例化一次setup函数。script标签里面的setup函数也是一样每次实例化组件,就是实例化一次setup函数,但是script标签setup是需要写在export default{}内的,外的只是首次引入的时候执行一次)

    2、<script setup>引入组件将自动注册

    不需要在引入组件后,通过 components:{}注册组件,可直接使用

    &lt;script setup&gt;
    import MyComponent from &#39;./MyComponent.vue&#39;
    //components:{MyComponent}  不需要注册直接使用
    &lt;/script&gt;
    
    &lt;template&gt;
      &lt;MyComponent /&gt;
    &lt;/template&gt;
    登入後複製

    3、组件通信:

    <script setup>中必须使用 defineProps defineEmits API 来替代 props 和 emits

    definePropsdefineEmits具备完整的类型推断并且在 <script setup> 中是直接可用的(浏览了一下掘金,发现大部分文章demo还是通过import引入这2个api,这点官方文档写得很清楚)

    defineProps 代替props

    接收父组件传递的数据(父组件向子组件传参)

    父组件:

    <template>
      <div>父组件</div>
      <Child :title="msg" />
    </template>
    
    <script setup>
    import {ref} from &#39;vue&#39;
    import Child from &#39;./child.vue&#39;
    const msg = ref(&#39;父的值&#39;)  //自动返回,在template直接解套使用
    </script>
    登入後複製

    子组件:

    <template/> 中可以直接使用父组件传递的props (可省略props.)

    <script-setup> 需要通过props.xx获取父组件传递过来的props

    <template>
      <div>子组件</div>
      <div>父组件传递的值:{{title}}</div>
    </template>
    
    <script setup>
    //import {defineProps} from &#39;vue&#39;   不需要引入
    
    //语法糖必须使用defineProps替代props
    const  props = defineProps({
      title: {
        type: String
      }
    });
    //script-setup 需要通过props.xx获取父组件传递过来的props
    console.log(props.title) //父的值
    </script>
    登入後複製
    defineEmit 代替emit

    子组件向父组件传递数据(子组件向外暴露数据)

    子组件代码:

    <template>
      <div>子组件</div>
      <button @click="toEmits">子组件向外暴露数据</button>
    </template>
    
    <script setup>
    import {ref} from &#39;vue&#39;
    const name = ref(&#39;我是子组件&#39;)
    //1、暴露内部数据
    const  emits = defineEmits([&#39;childFn&#39;]);
    
    const  toEmits = () => {
      //2、触发父组件中暴露的childFn方法并携带数据
      emits(&#39;childFn&#39;,name)
    }
    </script>
    登入後複製

    父组件代码:

    <template>
      <div>父组件</div>
      <Child  @childFn=&#39;childFn&#39; />
      <p>接收子组件传递的数据{{childData}} </p>
    </template>
    
    <script setup>
    import {ref} from &#39;vue&#39;
    import Child from &#39;./child.vue&#39;
        
    const childData = ref(null)    
    const childFn=(e)=>{
        consloe.log(&#39;子组件触发了父组件childFn,并传递了参数e&#39;)
        childData=e.value
    }    
           
    </script>
    登入後複製

    4.<script setup>需主动向父组件暴露子组件属性 :defineExpose

    使用 <script setup> 的组件,父组件是无法通过ref 或者 $parent 获取到子组件的ref等响应数据,需要通过defineExpose 主动暴露

    子组件代码:

    <script setup>
    import { ref } from &#39;vue&#39;
    
    const a = 1
    const b = ref(2)
    //主动暴露组件属性
    defineExpose({
      a,
      b
    })
    </script>
    登入後複製

    父组件代码:

    <template>
      <div>父组件</div>
      <Child  ref=&#39;childRef&#39; />
      <button @click=&#39;getChildData&#39;>通过ref获取子组件的属性 </button>
    </template>
    
    <script setup>
    import {ref} from &#39;vue&#39;
    import Child from &#39;./child.vue&#39;
    const childRef= ref()  //注册响应数据  
    const getChildData =()=>{
      //子组件接收暴露出来得值
      console.log(childRef.value.a) //1
      console.log(childRef.value.b) //2  响应式数据
    }    
    </script>
    登入後複製

    5.语法糖其他功能

    useSlotsuseAttrs少用,由于大部分人是SFC模式开发,在<template/>通过<slot/>标签就可以渲染插槽)

    如果需要在script-setup中使用 slotsattrs 需要用useSlotsuseAttrs替代

    需要引入: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>
          <h2>具名插槽</h2>
        </template>
        <!-- 作用域插槽 -->
        <template #footer="{ scope }">
          <footer>作用域插槽——姓名:{{ scope.name }},年龄{{ scope.age }}</footer>
        </template>
      </Child>
    </template>
    
    <script setup>
    // 引入子组件
    import Child from &#39;./child.vue&#39;
    </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 &#39;vue&#39;
    const state = reactive({
      name: &#39;张三&#39;,
      age: &#39;18&#39;
    })
    
    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=&#39;jsx&#39;>
    import { defineComponent, useSlots } from "vue";
    export default defineComponent({
      setup() {
        // 获取插槽数据
        const slots = useSlots();
        // 渲染组件
        return () => (
          <div>
            {slots.default?slots.default():&#39;&#39;}
            {slots.title?slots.title():&#39;&#39;}
          </div>
        );
      },
    });
    </script>
    登入後複製

    大部分人是SFC模式开发,在<template/>通过<slot/>标签就可以渲染插槽,这种JSX 的写法应该是很少人会使用的

    6.在setup访问路由

    • 访问路由实例组件信息:route和router

    setup 里不能访问 this,不能再直接访问 this.$routerthis.$route。(getCurrentInstance可以替代this但不推荐)

    推荐:使用useRoute 函数和useRouter函数替代this.$routethis.$router

    <script setup>
    import { useRouter, useRoute } from &#39;vue-router&#39;
        const route = useRoute()
        const router = useRouter()
        
        function pushWithQuery(query) {
          router.push({
            name: &#39;search&#39;,
            query: {
              ...route.query,
            },
          })
        }
      <script/>
    登入後複製
    • 导航守卫

    仍然可以使用路由实例组件的导航守卫

    import router from &#39;./router&#39;
    router.beforeEach((to,from,next)=&gt;{
    
    })
    登入後複製

    也可以使用组合式api的导航守卫onBeforeRouteLeave, onBeforeRouteUpdate

    <script setup>
    import { onBeforeRouteLeave, onBeforeRouteUpdate } from &#39;vue-router&#39;
    
        // 与 beforeRouteLeave 相同,无法访问 `this`
        onBeforeRouteLeave((to, from) => {
          const answer = window.confirm(
            &#39;Do you really want to leave? you have unsaved changes!&#39;
          )
          // 取消导航并停留在同一页面上
          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 守卫也可以用在任何由 `` 渲染的组件中,它们不必像组件内守卫那样直接用在路由组件上。

    以上是Vue3怎麼使用setup語法糖拒絕寫return的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您聽不到任何人,如何修復音頻
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解鎖Myrise中的所有內容
    4 週前 By 尊渡假赌尊渡假赌尊渡假赌

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    vue3+vite:src使用require動態匯入圖片報錯怎麼解決 vue3+vite:src使用require動態匯入圖片報錯怎麼解決 May 21, 2023 pm 03:16 PM

    vue3+vite:src使用require動態導入圖片報錯和解決方法vue3+vite動態的導入多張圖片vue3如果使用的是typescript開發,就會出現require引入圖片報錯,requireisnotdefined不能像使用vue2這樣imgUrl:require(' …/assets/test.png')導入,是因為typescript不支援require所以用import導入,下面介紹如何解決:使用awaitimport

    vue3專案中怎麼使用tinymce vue3專案中怎麼使用tinymce May 19, 2023 pm 08:40 PM

    tinymce是一個功能齊全的富文本編輯器插件,但在vue中引入tinymce並不像別的Vue富文本插件一樣那麼順利,tinymce本身並不適配Vue,還需要引入@tinymce/tinymce-vue,並且它是國外的富文本插件,沒有透過中文版本,需要在其官網下載翻譯包(可能需要翻牆)。 1.安裝相關依賴npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2、下載中文包3.引入皮膚和漢化包在項目public資料夾下新建tinymce資料夾,將下載的

    Vue3怎麼解析markdown並實現程式碼高亮顯示 Vue3怎麼解析markdown並實現程式碼高亮顯示 May 20, 2023 pm 04:16 PM

    Vue實作部落格前端,需要實作markdown的解析,如果有程式碼則需要實作程式碼的高亮。 Vue的markdown解析函式庫很多,如markdown-it、vue-markdown-loader、marked、vue-markdown等。這些庫都大同小異。這裡選用的是marked,程式碼高亮的函式庫選用的是highlight.js。具體實現步驟如下:一、安裝依賴庫在vue專案下開啟命令窗口,並輸入以下命令npminstallmarked-save//marked用於將markdown轉換成htmlnpmins

    Vue3如何實作刷新頁面局部內容 Vue3如何實作刷新頁面局部內容 May 26, 2023 pm 05:31 PM

    想要實現頁面的局部刷新,我們只需要實現局部元件(dom)的重新渲染。在Vue中,想要實現這效果最簡單的方式方法就是使用v-if指令。在Vue2中我們除了使用v-if指令讓局部dom的重新渲染,也可以新建一個空白元件,需要刷新局部頁面時跳轉至這個空白元件頁面,然後在空白元件內的beforeRouteEnter守衛中又跳轉回原來的頁面。如下圖所示,如何在Vue3.X中實現點擊刷新按鈕實現紅框範圍內的dom重新加載,並展示對應的加載狀態。由於Vue3.X中scriptsetup語法中組件內守衛只有o

    C語言return的用法詳解 C語言return的用法詳解 Oct 07, 2023 am 10:58 AM

    C語言return的用法有:1、對於傳回值類型為void的函數,可以使用return語句來提前結束函數的執行;2、對於傳回值型別不為void的函數,return語句的作用是將函數的執行結果傳回給呼叫者;3、提前結束函數的執行,在函數內部,我們可以使用return語句來提前結束函數的執行,即使函數並沒有回傳值。

    Vue3復用元件怎麼使用 Vue3復用元件怎麼使用 May 20, 2023 pm 07:25 PM

    前言無論是vue還是react,當我們遇到多處重複程式碼的時候,我們都會想著如何重複使用這些程式碼,而不是一個檔案裡充斥著一堆冗餘程式碼。實際上,vue和react都可以透過抽組件的方式來達到復用,但如果遇到一些很小的程式碼片段,你又不想抽到另外一個檔案的情況下,相比而言,react可以在相同文件裡面宣告對應的小元件,或透過renderfunction來實現,如:constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(

    Vue3中怎麼實現選取頭像並裁剪 Vue3中怎麼實現選取頭像並裁剪 May 29, 2023 am 10:22 AM

    最終效果安裝VueCropper組件yarnaddvue-cropper@next上面的安裝值針對Vue3的,如果時Vue2或想使用其他的方式引用,請訪問它的npm官方地址:官方教程。在元件中引用使用時也很簡單,只需要引入對應的元件和它的樣式文件,我這裡沒有在全域引用,只在我的元件檔案中引入import{userInfoByRequest}from'../js/api' import{VueCropper}from'vue-cropper&

    怎麼使用vue3+ts+axios+pinia實現無感刷新 怎麼使用vue3+ts+axios+pinia實現無感刷新 May 25, 2023 pm 03:37 PM

    vue3+ts+axios+pinia實作無感刷新1.先在專案中下載aiXos和pinianpmipinia--savenpminstallaxios--save2.封裝axios請求-----下載js-cookienpmiJS-cookie-s//引入aixosimporttype{AxiosRequestConfigig ,AxiosResponse}from"axios";importaxiosfrom'axios';import{ElMess

    See all articles