<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          萬萬沒想到,Vue3 的 setup 還能這么玩

          共 8654字,需瀏覽 18分鐘

           ·

          2021-12-02 01:10

          一、前言

          昨天講了什么是組合式API,\# 馬上都2202年了你還不知道什么是Vue3的組合式API嗎?[2]今天就來聽我吹一吹vue3的setup都能怎么用

          ef09193f915a12abcca5c8e619198ad6.webpimage.png

          借用官網(wǎng)一句話

          setup?選項是一個接收?props?和?context?的函數(shù)

          也就是說它的基本寫法應該是這樣的

          export?default{
          ????name:?'test',
          ????setup(props,context){

          ?????return?{}???//?這里返回的任何內(nèi)容都可以用于組件的其余部分
          ????}
          ????//?組件的“其余部分”
          }
          復制代碼

          接收一個propscontext函數(shù)并且將setup內(nèi)的內(nèi)容通過return暴露給組件的其余部分。

          二、setup注意點

          • 由于在執(zhí)行 setup函數(shù)的時候,還沒有執(zhí)行 Created 生命周期方法,所以在 setup 函數(shù)中,無法使用 data 和 methods 的變量和方法

          • 由于我們不能在 setup函數(shù)中使用 data 和 methods,所以 Vue 為了避免我們錯誤的使用,直接將 setup函數(shù)中的this 修改成了 undefined

          三、定義響應式數(shù)據(jù)

          ref reactive

          vue3通過ref reactive來定義響應式數(shù)據(jù)

          ref我們用來將基本數(shù)據(jù)類型定義為響應式數(shù)據(jù),其本質是基于Object.defineProperty()重新定義屬性的方式來實現(xiàn)(ref更適合定義基本數(shù)據(jù)類型)

          reactive用來將引用類型定義為響應式數(shù)據(jù),其本質是基于Proxy實現(xiàn)對象代理

          • 基本數(shù)據(jù)類型(單類型):除Object。String、Number、boolean、null、undefined。
          • 引用類型:object。里面包含的 function、Array、Date。
          53ef6e40e7b314c44a59bf885edb382f.webpimage.png

          定義

          <script>
          import?{ref,?reactive}?from?"vue";
          export?default?{
          ??name:?"test",
          ??setup(){
          ????//?基本類型
          ????const?nub?=?ref(0)
          ????const?str?=?ref('inline')
          ????const?boo?=?ref(false)
          ????//?引用類型
          ????const?obj?=?reactive({
          ??????name:'inline',
          ??????age:'18'
          ????})
          ????const?arr?=?reactive(['0','1','2'])

          ????return{
          ??????nub,
          ??????str,
          ??????boo,

          ??????obj,
          ??????arr,
          ????}
          ??}
          }
          </script>
          復制代碼

          使用

          <template>
          ????<div>
          ??????<h1>基本類型</h1>
          ??????<p>nub:{{?nub?}}</p>
          ??????<p>str:{{?str?}}</p>
          ??????<p>boo:{{?boo?}}</p>
          ????</div>
          ????<div>
          ??????<h1>引用類型</h1>
          ??????<p>obj:{{?obj.name?}}</p>
          ??????<p>arr:{{?arr[1]?}}</p>
          ????</div>
          </template>
          復制代碼

          結果ea1d482254c29229b21655b9cc2915a5.webp

          四、toRefs

          如果我們用reactive的形式來定義響應式變量

          setup(){
          ??const?obj?=?reactive({
          ????name:'inline',
          ????gender:'男',
          ????age:'18'
          ??})

          ??return{
          ????obj
          ??}
          }
          復制代碼

          使用

          <div>
          ??<p>姓名:{{?obj.name?}}</p>
          ??<p>性別:{{?obj.gender?}}</p>
          ??<p>年齡:{{?obj.age?}}</p>
          </div>
          復制代碼

          這樣我們是不是發(fā)現(xiàn)在模板內(nèi)使用參數(shù)很麻煩,那我們想直接用{{ name }}的方式訪問行不行,答案是可行的

          這里我們使用es6的擴展運算符

          setup(){
          ??const?obj?=?reactive({
          ????name:'inline',
          ????gender:'男',
          ????age:'18',
          ??})

          ??return{
          ????...obj,
          ??}
          }
          復制代碼

          使用

          <div>
          ??<p>姓名:{{?name?}}</p>
          ??<p>性別:{{?gender?}}</p>
          ??<p>年齡:{{?age?}}</p>
          </div>

          <div>
          ??<button?@click="name?=?'juejin'">改變姓名</button>
          ??<button?@click="gender?=?'女'">改變性別</button>
          ??<button?@click="age?=?'20'">改變年齡</button>
          </div>
          復制代碼

          結果

          950fa4baccfdf666ff4e7be59c064600.webp動畫.gif

          這里看到我們的參數(shù)都正常的顯示到了頁面上,但是我們?nèi)ジ淖儏?shù)時發(fā)現(xiàn)視圖并沒有更新,這是為什么呢???

          748be54ea3474562dfca3a37a98da458.webpimage.png

          我們把擴展運算符寫成它的等價格式

          const?obj?=?reactive({
          ????name:'inline',
          ????gender:'男',A
          ????age:'18',
          ??})
          //?...obj?==>?name:obj.name
          復制代碼

          哎哎哎,等下 我的鼠標浮動上去怎么提示我name只是一個字符串?

          65cfb8b716c99bcc43c79042dd53d036.webpimage.png

          那我們在看看我們用ref定義值時提示什么

          eff7f520304501424790ee4ca7042312.webpimage.png

          奧奧,這個時候我們看到name是一個Ref<string>,是一個響應式字符串。

          這樣我們就找到了為什么沒有更新視圖的原因,當我們用...擴展運算符時我們得到的只是一個普通類型的數(shù)值,并不是一個響應式數(shù)據(jù)

          為了解決這個問題呢,vue3給我們提供了toRefs函數(shù),來讓我們看看效果如何

          setup(){
          ??const?obj?=?reactive({
          ????name:'inline',
          ????gender:'男',
          ????age:'18',
          ??})

          ??return{
          ????...toRefs(obj),
          ??}
          }
          復制代碼
          <div>
          ??<p>姓名:{{?name?}}</p>
          ??<p>性別:{{?gender?}}</p>
          ??<p>年齡:{{?age?}}</p>
          </div>

          <div>
          ??<button?@click="name?=?'juejin'">改變姓名</button>
          ??<button?@click="gender?=?'女'">改變性別</button>
          ??<button?@click="age?=?'20'">改變年齡</button>
          </div>
          復制代碼

          參數(shù)都可以正常改變,成功改頭換面

          19ffeee53691ea2791fd198bf2df2216.webp動畫1.gif3cf75243692427d2131e29191b255112.webpimage.png

          toRefs總結

          toRefs會將我們一個響應式的對象轉變?yōu)橐粋€普通對象,然后將這個普通對象里的每一個屬性變?yōu)橐粋€響應式的數(shù)據(jù)

          e9528eec43205878f6a59882c0a91c88.webpimage.png

          五、setup中執(zhí)行方法

          方式一

          reactive定義響應式數(shù)據(jù)的方式來定義方法

          <script>
          import?{ref,?reactive,toRefs}?from?"vue";

          export?default?{
          ??name:?"test",
          ??setup(){
          ????const?str?=?ref('inline')
          ????const?fun?=?reactive({
          ??????fun1(data){
          ????????console.log(str.value)
          ????????this.fun2(data)
          ??????},
          ??????fun2(data){
          ????????console.log(data)
          ????????console.log('我是fun2')
          ??????}
          ????})

          ????return{
          ??????...toRefs(fun),
          ????}
          ??}
          }
          </script>
          復制代碼

          通過點擊事件將值傳給fun1,fun1接收到后在傳給fun2

          這里我們用this.fun2()的方式去調用fun2,為什么這里用this可以正常執(zhí)行不會報undefind,因為這里的this非彼this,Vue2里的this是實例這里的this是對象

          <button?@click="fun1('你好')">點我1</button>
          復制代碼

          結果,成功調用并輸出

          d78abebed8b0ac1360bc7781a1ad6ffc.webpimage.png

          方式二

          注意這里調用fun2的方式與方式一不同,直接調用就可以,不用this調用

          export?default?{
          ??name:?"test",
          ??setup(){
          ??????const?fun1?=?(data)?=>?{
          ????????fun2(data)
          ??????}
          ??????const?fun2?=?(data)?=>?{
          ????????console.log(data)
          ??????}
          ????return{
          ??????fun1,
          ????}
          ??}
          }
          復制代碼

          調用

          <button?@click="fun1('你好?inline')">點我1</button>
          復制代碼

          結果

          02216e5db37dac2fe02b708b057b60a0.webpimage.png

          方式三

          這種方式避免了將功能邏輯都堆疊在setup的問題,我們可以將獨立的功能寫成單獨的函數(shù)

          這里我在setup外寫了fun() login()兩個功能函數(shù),并在setup內(nèi)分別調用

          import?{ref,?reactive,toRefs}?from?"vue";

          export?default?{
          ??name:?"test",
          ??setup(){
          ????const?test1?=?fun()??????//?如果函數(shù)返回參數(shù)過多,可以賦值給變量并用擴展運算符暴露給組件的其余部分
          ????const?{?test?}?=?login()?//?也可單個接收
          ????return{
          ??????...toRefs(test1),
          ??????test,
          ????}
          ??}
          }

          //?功能1
          function?fun(){
          ??let?str?=?ref('我是功能1')
          ??function?fun1(data){
          ????console.log(str.value)
          ????fun2(data)
          ??}
          ??function?fun2(data){
          ????console.log(data)
          ??}
          ??return{
          ????fun1,
          ????fun2,
          ??}
          }

          //?功能2
          function?login()?{
          ??const?obj?=?reactive({
          ????msg:'我是功能2,我愛掘金'
          ??})
          ??function?test()?{
          ????console.log(obj.msg)
          ??}
          ??return{
          ????test
          ??}
          }
          </script>
          復制代碼

          調用

          <button?@click="fun1('你好?inline')">點我1</button>
          <button?@click="test">點我2</button>
          復制代碼

          結果

          5efb5b829853856e663e91500996413d.webp動畫.gif

          方式四

          與方式三一樣,只是我們將兩個功能函數(shù)提取出來放在單獨的.js文件中

          aea5766d0e6050be6c71b18653594a67.webpimage.png

          然后引入組件,并在setup內(nèi)調用

          <template>
          ??<div?style="text-align:?center;margin-top:?50px">
          ????<button?@click="fun1('你好?inline')">點我1</button>
          ????<button?@click="test">點我2</button>
          ??</div>

          </template>

          <script>
          import?{ref,?reactive,toRefs}?from?"vue";
          import?{?fun,login?}?from?'./
          test.js'
          export?default?{
          ??name:?"test",
          ??setup(){
          ????const?test1?=?fun()
          ????const?{?test?}?=?login()
          ????return{
          ??????...toRefs(test1),
          ??????test,
          ????}
          ??}
          }

          </script>
          復制代碼

          正常執(zhí)行且輸入5efb5b829853856e663e91500996413d.webp

          方式五

          我們還可以這樣寫,這里我定義一個reactive響應式對象,賦值給login變量,這個響應式對象內(nèi)有我們登錄需要的參數(shù)驗證方法,這里我們?nèi)糠旁?code style="font-size:14px;font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;color:rgb(155,110,35);background-color:rgb(255,245,227);">login這個響應式對象內(nèi)然后用toRefs擴展運算符暴露出去

          <script>
          import?{ref,?reactive,toRefs}?from?"vue";

          export?default?{
          ??name:?"test",
          ??setup(){
          ????const?login?=?reactive({
          ??????param:?{
          ????????username:?'123',
          ????????password:?'123456',
          ??????},
          ??????rules:?{
          ????????username:?[{?required:?true,?message:?'請輸入用戶名',?trigger:?'blur'?}],
          ????????password:?[{?required:?true,?message:?'請輸入密碼',?trigger:?'blur'?}],
          ??????},
          ??????login(){
          ????????this.param.username?=?'inline'
          ????????this.param.password?=?'123456'
          ????????console.log('成功登錄!')
          ??????}
          ????})

          ????return{
          ??????...toRefs(login),
          ????}
          ??}
          }
          </script>
          復制代碼

          我們使用一下

          <input?type="text"?v-model="param.username">
          <input?type="password"?v-model="param.password">
          <button?@click="login">登錄</button>
          復制代碼
          076de298c02e3143e3eceab5b463f18b.webpimage.png

          正常執(zhí)行,所以我們還可以將一個功能的所有方法和相關參數(shù)寫在一個reactive對象內(nèi)

          915b59eae90013c9c1433d582f6f5665.webp表情包1.gif

          如有遺漏的執(zhí)行方式歡迎評論區(qū)指出~~~

          六、script setup

          script setup已在vue3.2的版本上正式發(fā)布

          用法

          <script?setup>

          </script>
          復制代碼

          是不是異常簡單

          變量方法無需return

          使用<script setup>時,模板被編譯成一個內(nèi)聯(lián)在 setup 函數(shù)作用域內(nèi)的渲染函數(shù)。這意味著內(nèi)部聲明的任何頂級綁定<script setup>都可以直接在模板中使用

          <script?setup>
          ??const?msg?=?'Hello!'
          </script>

          <template>
          ??<div>{{?msg?}}</
          div>
          </template>
          復制代碼

          script setup內(nèi)定義的變量和方法無需返回,可直接使用

          組件引入

          導入的組件無需注冊,可直接使用

          <script?setup>
          ??//?導入的組件也可以直接在模板中使用
          ??import?Foo?from?'./Foo.vue'
          ??import?{?ref?}?from?'vue'

          ??//?編寫合成API代碼,就像在正常設置中一樣
          ??//?不需要手動返回所有內(nèi)容
          ??const?count?=?ref(0)
          ??const?inc?=?()?=>?{
          ????count.value++
          ??}
          </script>

          <template>
          ??<Foo?:count="count"?@click="inc"?/
          >
          </template>
          復制代碼

          發(fā)布PropsEmits

          <script?setup>

          ??const?props?=?defineProps({
          ????foo:?String
          ??})
          ??
          ??const?emit?=?defineEmits(['update',?'delete'])
          </script>
          復制代碼

          普通scriptscript setup

          script setup可以和script同時存在

          <script>
          ??export?const?name?=?1
          </script>

          <script?setup>
          ??import?{?ref?}?from?'vue'

          ??const?count?=?ref(0)
          </
          script>
          復制代碼

          script setup 附加選項

          script setup給我們提供了大多數(shù)與 options api等效的能力

          就是說options api能辦到的事 script setup大部分都能辦到

          那還有哪些是script setup做不到的呢?如下:

          • name
          • inheritAttrs
          • 插件或庫所需要的自定義選項

          那我要是想用這些怎么辦呢?答案是分開寫

          <script>
          ??export?default?{
          ????name:?'CustomName',
          ????inheritAttrs:?false,
          ????customOptions:?{}
          ??}
          </script>

          <script?setup>
          ??//?script?setup?logic
          </
          script>
          復制代碼

          defineExpose

          script setup定義的變量默認不會暴露出去,因為變量這時候包含在setup的閉包中。這時我們可以使用definExpose({ })來暴露組件內(nèi)部屬性給父組件使用

          <script?setup>
          ??const?a?=?1
          ??const?b?=?ref(2)

          ??defineExpose({
          ????a,
          ????b
          ??})
          </script>
          復制代碼

          當父組件通過模板引用獲取此組件的實例時,檢索到的實例將會是這樣{ a: number, b: number }(引用會像在普通實例上一樣自動展開)

          039eb3f2fdc35f461b78687dc05b7623.webpimage.png

          七、寫在最后

          script setup可以說的東西還有很多,等我這幾天整明白了可以單獨出一期它的用法。

          最后感謝您的閱讀~~~您的點贊和閱讀就是對我最大的鼓勵~~~63b7ee65a15ea47cd1ea3a08062083fb.webp

          往期vue3文章:

          \# 在實驗 vue3.2中 的script setup時,關于...toRefs的應用嘗試[3]\# 什么是Vue3的組合式API?[4]作者:inline705https://juejin.cn/post/7029339447078420493
          Vue一直是前端開發(fā)必學的,說實話網(wǎng)上找資料真是一抓一大把,但大多都浮于表面,重在理論,實戰(zhàn)薄弱;很多刷題資料,也并沒有很好地分類以及經(jīng)驗總結;更別提通過 Vue3 建立知識體系了。?好在,最近看到前端技術大佬「大圣」,出了個專欄玩轉?Vue3?全家桶,我第一時間買來看了,果然驚喜,上來就給了一套知識路徑,「建立對?Vue3?的全局認知?→?掌握核心概念和原理?→?企業(yè)級代碼質量和工程實戰(zhàn)」大家可以長按下方圖片二維碼,先仔細看看目錄和介紹,看看是不是適合自己??????

          ?Vue3?戰(zhàn),。?,?Vue3??點擊下方「閱讀原文」,最低?¥89?到手,掌握“ Vue 3 開發(fā)?這個硬核技能。
          瀏覽 65
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄片视频免费 | 日韩黄在线 | 少妇无码免费视频 | 日韩免费三级电影 | 成人免费电影MV |