vue - Vue腳手架/消息訂閱與發佈

来源:https://www.cnblogs.com/heymar/archive/2022/05/07/16244588.html
-Advertisement-
Play Games

今天的內容有意思了,朋友們繼續對我們之前的案例完善,是這樣的我們之前是不是靠props來完成父給子,子給父之間傳數據,其實父給子最好的方法就是props但是自給父就不是了,並且今天學下來,不僅如此,組件間任何層級的關係我都可以傳數據了,兄弟之間,爺孫之間等等等等 七.瀏覽器本地存儲 1.localS ...


今天的內容有意思了,朋友們繼續對我們之前的案例完善,是這樣的我們之前是不是靠props來完成父給子,子給父之間傳數據,其實父給子最好的方法就是props但是自給父就不是了,並且今天學下來,不僅如此,組件間任何層級的關係我都可以傳數據了,兄弟之間,爺孫之間等等等等

七.瀏覽器本地存儲

1.localStorage

關閉瀏覽器數據不會丟失

通過它上面的一個api可以存儲數據 .setitem()兩個參數,前面是鍵,後面是值,要註意的是都要以加引號以字元串形式進行存儲,而且就算你不加引號,最終呈現效果也會強制給你調用toString這個方法

image-20220507122902184

image-20220507122831870

可以看到就算是字元串也變成了字元串類型,那麼問題就來了,那如果我傳入的是一個對象,也被強制調用了toString那我對象就沒了,什麼也看不到了

image-20220507123057878

所以如果是要存儲對象數據的時候需要將對象用轉為json數據在進行存儲,我們都知道json本質上還是一個字元串

image-20220507123224972

image-20220507123236808

剩下還有三個api:讀取getitem()、刪除removeitem()、清空clear()這個不用傳數據

image-20220507123519599

註意:讀取沒有的屬性,將會顯示null

2.sessionStorage

瀏覽器一關就沒有數據了

他的api跟local一樣

3.TodoList案例完善

我們剛纔做的案例數據在一刷新,就會回到初始案例,顯然這樣是不行的,每個人都應該有屬於自己的數據,就可以配合localstorage來,通過監視屬性來做,監視我們的data數據,當一發生變動就讓最新的值setitem到我們的本地存儲

image-20220507132539015

我在這裡卡了半天啊,我一直在糾結,為什麼這個local裡面的屬性名會給我變成個數組,最終查到了,原來watch監視屬性裡面的參數本身就是個數組,放的對象的形式,做到這一步當我們敲擊回車,已經可以看到localstorage將我們的數據存儲下來了,但是呢我們的頁面還沒有,這個時候需要將我們原來的數據,註意datas本身是一個數組這裡就不用再用數組包裹了

image-20220507133713721

這個時候我們我們刷新就能看到我們之前已經添加過的數據了

bug:當我們把local清空準備重新試一下,就會報錯

image-20220507133829630

不能夠讀取null的長度差不多是這個意思,哪裡來的null?還記得前面說過當我們本地存儲如果讀取的是一個不存在的屬性那他讀取出來就是null,所以問題出現在這裡,這個時候localstorage裡面還沒有這個屬性的,主需要採用短路運算,讓原始數據,存在就用它否則就為一個空數組

image-20220507134026587

bug:雖然完成了刷新添加的數據不會丟失,但是我們的選擇刷新了會丟失,為什麼,問題出現在watch這裡,我們對watch的監視只是看dataArr有沒有整體改動,用了unshift,vue都能檢測到,很明顯這是一個能夠改變自身的方法,但是我們去勾選前面的選擇,卻是深層次裡面的了,所以監視的deep屬性就來,只有監測到深層次的改動才又會重新setitem

八.自定義事件

  • 方法一 : @或者v-on方法完成一個案例,當我們點擊一個子組件,會把子組件的名字傳到app裡面來並列印出來,用到props的子傳父方法,怎麼用自定義事件來完成這件事情,首先在app的組件標簽寫上我們的自定義事件名,用v-on來綁定,

image-20220507143925723

那麼這個事件怎麼來觸發呢,這樣來理解,當我們通過組件標簽給她綁定了一個自定義事件,那麼此時這個組件實例對象vc身上肯定已經有這個事件了,至於怎麼來觸發就需要回到我們的組件裡面去定義

image-20220507144350422

這裡先把我們的觸發後的事件處理函數定義好,然後關鍵邏輯 主要是在我們要觸發的這個組件裡面,想要這個自定義事件要怎麼觸發其實是聽你自己的,同樣還是需要在這邊生命一個內置的事件,然後在這個事件函數裡面用到一個api $emit,他的第一個參數就是你的自定義的事件的名字,第二個參數可以傳參給你自定義事件的處理函數

image-20220507144740569

props和自定義事件異同點:

共同:都可以實現子給父傳數據,而且都是通過父組件裡面的回調來實現的

不同點:props需要接收,而這種方法,直接拿來用都不用調用這個函數,props還需要自己去調用這個函數把參數傳進去

  • 方法二: 針對於上面的自定義事件的形式,我們還有第二種方法也叫做 ref法,通過在app給子組件添加一個ref,前面就說過我們用ref獲取來的組件是這個組建的實例對象,有了實例對象,直接通過mounted這個生命周期鉤子,為什麼要在這裡做,因為只有掛載完畢了我們才能拿到這個實例對象,vue才會new 組件構造函數,繼續通過$on這個方法給這個實例對象在他身上添加一個自定義事件

    image-20220507151516618

    做到這一步,我們組件裡面的代碼不變,還是click同時還是通過$emit 這個api來觸發自定義事件,做到這一步意思就是,一切準備就緒,一旦在這個組件觸發了這個自定義事件就會執行自定義事件的回調函數,那麼回到函數呢?直接在後面以參數的形式添加

    image-20220507151747849

  • 如果說我只想執行一次用v-on方法就是直接用事件修飾符,用ref方法,就調用$once這個api

    image-20220507152150000

    image-20220507152156308

    註意如果是子組件多個參數傳進來,可以使用這種方式將其以一個數組方式接受

    image-20220507152526973

8.1解綁自定義事件

  • 解綁單個事件,寫在子組件裡面,全新api $off

    image-20220507153119289

  • 解綁多個,用字元串包裹

    image-20220507153148913

  • 解綁所有,this.$off()不傳參數

    回顧前面所說的一個生命周期的問題,說過當執行了destroy之後,身上的事件、監聽器等都會被銷毀,但是說的事件是自定義事件,和vue事件不包括原生js事件,比如你點擊一個按鈕n++,這個時候n肯定不加了,但是如果你寫的有console.log那麼這個log肯定還是你點一次輸出一次的,自定義事件就更不用說了,也是vue實現的,所以也會被銷毀實現不了了,還有一個點就是,vm被銷毀了他下麵的子組件的這些自定義事件等也會被銷毀

8.2註意

  • 是一種組件間的通信方式,適用於 子組件給父組件傳

  • 我們的組件標簽上也可以綁定內置事件,但是需要 .native這個修飾符,綁定後比如一個click那就是這個子組件的最大的div可以觸發也就是子組件的最外層

  • 如果用下麵這鐘方式綁定自定義事件的時候,需要註意回調這裡要麼寫在mtehods裡面,要麼寫成一個箭頭函數,不然this指向會變

    image-20220507161900502

8.3TodoList自定義事件

將之前這個案例子傳父數據的地方都改成自定義事件,我就直接傳幾個,比如敲回車放入數組這裡直接將原來的動態綁定改為自定義事件,簡寫形式

image-20220507164142830

然後我們header這邊的 props就可以刪除了,同時在我們的鍵盤事件添加上調用api去觸發自定義事件的命令

image-20220507164235207

然後我們在用ref打標識的方法再做一次全選的方式,首先需要在app裡面找到footer的子組件,給她打一個標識,然後在我們app這個組建的mounted函數裡面來通過ref得到這個組件實例對象通過on這個api將自定義事件綁定上去,同時第二個參數為我們要調用這個事件的回調函數

image-20220507165031575

然後後面基本是一樣的,在我們子組件裡面這個自定義事件該怎麼觸發,就寫內置事件,寫一個事件處理函數,然後在這個處理函數裡面,emit這個api來觸發自定義事件,同時將我們需要的參數傳過來

image-20220507165149931

九.全局事件匯流排

9.1安裝全局事件匯流排

可實現任意組件間的通信

image-20220507170750378

其實原理是這樣的,我們左邊這麼多組件,要實現任意互相通信,可以由一個中間者實現,比如我們在B裡面定義這個x給她通過$on綁定一個自定義事件,同時回調在我們B裡面,註意是在B裡面,所以當執行這個自定義事件的時候,是在B裡面執行,完成了這一步,比如說我們要把A的數據傳到B裡面來,那麼A就可以通過x這個對象用他身上的$emit這個api來觸發我們的自定義事件同時把A身上的數據,傳過來,這個時候我們B的回調裡面就能收到這個數據了

其實原理跟我們前面的自定義事件很像,所以這麼一看,這個x是不是要滿足兩個特性:一個是它能夠被所有組件訪問到,一個是他身上要有$on、$emit等api,第一個問題它能夠被所有組件訪問到,放在VueComponent上實現不了,因為我們說過每個VueComponent都是一個全新的構造函數,放在自己vc上更不可能,那就只有你能訪問了,那麼順著那條線,是不是答案已經出來了,沒錯,要讓所有組件都訪問得到,那就只有Vue的原型對象了

第二個問題,怎麼讓他身上有這些api,這些api其實都是在vue原型對象上的,所以我們vm、vc都可訪問得到,但是將它等於一個vc不太現實,因為我們是將它定義在入口文件的,那就只能為一個vm了,並且還要在vm的beforecreate這個生命周期函數來賦值,為什麼要在生命周期函數里來賦值,因為這裡講究一個時間效應,太慢了不行的,前面也已經看過了ref打標識這種方法調用on這個api就是在mounted生命周期函數裡面調用的,為什麼因為講mounted的時候就說過這裡面是萬物的開始,呱呱墜地的時候,什麼定義定時器、自定義事件等等都是在這裡,而且也只能在這裡,不然時間晚了,我觸發了你還沒綁定好那怎麼可以,所以說我們講究一個時間效應,如果等到vm都定義完了,來一個x=vm,這個時候已經整個都掛載到頁面上去了,我們組件裡面的mounted也早已經執行完了,你的x都還沒有這些api那就會報錯,然後還只能寫在beforecreate這個生命周期鉤子,為什麼,也不是說只能嘛,最好寫在這裡,created感覺也是可以的,因為這裡數據掛載這些都還沒做,但是也說過vue內置的一些事件、api之類的定義完了,我要這些就夠了,我不需要數據

image-20220507174548564

所以最終定義成這樣就是最標準的了,而且我們一般x叫做$bus,因為這個東西的作用一是本身有點公交車的感覺,誰都能用,還有一個就是他的中文意思還有匯流排的意思

有一點必須要清楚,我想把A發送到B,那調用emit發射這個api的就是前者並且參數是數據,而後者就調用on並且參數為回調,你就拿到這個數據了,想幹嘛幹嘛了

image-20220507181001940

image-20220507181019131

然後就是,定義自定義事件也就是on肯定一掛載就要定義,所以寫在mounted裡面,而發送數據這邊決定觸發事件的方式

既然用到了出生mounted,最好也在臨別beforeDestroy解綁我們的事件,一定要寫事件名

image-20220507181429151

9.2TODOList全局事件匯流排

又可以繼續完善之前的案例了,其實父給子傳數據,props是最好的方法,子給父傳,用我們原始方法也行(props),自定義事件也好,都差不多的,這裡最需要用到全局事件匯流排的,是孫給爺傳,之前一直靠著list這個中間量props,他自己也沒用只是給item帶過去函數

定義好api

image-20220507182642351

我們是item給app傳,那就在item先emit,都是傳過去id進行更新我們的數據裡面的completed是否勾選和篩選進行刪除操作

image-20220507182901518

然後再mounted裡面聲明事件

image-20220507183024764

十.消息訂閱與發佈

一種組件間的通信方式,適用於任意組件間通信

如果A需要C的數據,那麼A就訂閱消息,C就發佈消息即可

image-20220507202035240

原生JS無法輕鬆實現消息訂閱與發佈,需要第三方庫(這裡推薦 pubsub-js

  • 先安裝這個庫
  • 哪裡需要就在那裡導入,我要把student的學生姓名傳給school那他們兩個都需要

,導入時註意 直接pubsub沒有js

image-20220507202734103

  • 學生這邊發佈信息,參數為要傳過去的數據,用到的api pubsub.publish,第一個參數為消息名,發佈與訂閱都需要的

    image-20220507203027427

  • 學校這邊訂閱消息用到的是 pubsub.subscribe接受兩個參數,第一個是我們的消息名字,所以一般取名為msgName,第二個參數才是我們傳過來的數據,一般取名data,註意消息訂閱同自定義事件、全局事件接收數據這邊都是放在mounted函數裡面的

    image-20220507203733717

  • 註意一,同樣需要在beforeDestory函數裡面取消訂閱,用到的api .unsubscribe,但是我們這裡的消息訂閱有點類似於定時器,需要一個變數去接收,這邊取消訂閱為這個變數名,註意不是消息名

    image-20220507204123960

    像這樣是拿不到的,都是兩個作用域了,把它放到實例對象上去,作為一個屬性即可

    image-20220507204231285

  • 註意二:直接在訂閱消息裡面寫這個函數同樣要寫為箭頭函數,不然this會亂,或者也可以在methods裡面寫,這裡直接調用


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、下載安裝包 打開官網,跳轉至下載界面,選擇對應版本的安裝包,拷貝其鏈接,這裡是手動安裝,所以下載tgz安裝包,如果要自動化安裝,選擇server的rpm自動安裝包 https://www.mongodb.com/try/download/community 這裡直接使用wget下載至伺服器中,然 ...
  • **導讀:**京東智能商客之推薦賣點是基於NLP的產品,目前已廣泛地助力和賦能於京東商城的各個平臺。今天和大家分享一下自然語言處理如何在工業界落地實現。主要圍繞以下5個方面展開: 推薦賣點技術背景 架構描述 核心AI技術 模型研發與實踐 產品的落地與回報 -- 01 推薦賣點技術背景 1. 什麼是推 ...
  • 大家見過這張圖嗎? Swami Chandrasekaran在2013年用地鐵圖來描述如何通過“一段旅程”來成為數據科學家 (鏈接:http://nirvacana.com/thoughts/2013/07/08/becoming-a-data-scientist/) 這個圖幫助很多人叩開了數據科學 ...
  • 解決MySQL 8.0在Linux環境下的安裝、初始化、配置。參考環境:MySQL Community Server 8.0.28;CentOS Linux release 7.9.2009。 ...
  • 本文收集了各種資料庫的SQL語句優化原理思路、技術要點和方法實操案例文檔!希望大家都能寫得一手好SQL、掌握資料庫高性能運行秘訣! ...
  • HarmonyOS Connect智能硬體開放生態即將步入富設備產業化時代!為了讓廣大開發者能搶先體驗鴻蒙智聯富設備開發,本期我們將為大家帶來七款支持富設備開發的開發板。 ...
  • 精準推送是移動端產品留存階段的主要運營手段,精準推送常常會與用戶畫像緊密結合,針對用戶的喜好、畫像,採用不同策略,但基於用戶所屬區域推送消息卻很難實現。目前市面上大多數第三方消息推送服務商,在系統未深度定製的情況下,通常不支持將推送人群範圍精確到某個商圈或較小的區域,而地理圍欄技術可以很好地彌補這一 ...
  • 前言 本文主要是整理了使用WebRTC做音視頻通訊時的各知識點及問題點。有理解不足和不到位的地方也歡迎指正。 對於你感興趣的部分可以選擇性觀看。 WebRTC的初始化 在使用WebRTC的庫之前,需要對WebRTC進行初始化, 用到的代碼如下: RTCInitializeSSL(); 轉定義後可以看 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文將以 C# 語言來實現一個簡單的布隆過濾器,為簡化說明,設計得很簡單,僅供學習使用。 感謝@時總百忙之中的指導。 布隆過濾器簡介 布隆過濾器(Bloom filter)是一種特殊的 Hash Table,能夠以較小的存儲空間較快地判斷出數據是否存在。常用於允許一定誤判率的數據過濾及防止緩存 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 「簡單有價值的事情長期堅持做」 這是成功最簡單,但也最難學的秘訣。不經過訓練,人很難意識到時間複利的威力。 仙劍奇俠傳的「十里坡劍神」和金庸群俠傳的「十級野球拳」,就是簡單的事情持之以恆反覆做,最後就有巨大的威力 唐家三少成為網文收入第一,最重要的一步是十四年從未斷日更 這樣的案例很多,一開始可能成 ...
  • 迎面走來了你的面試官,身穿格子衫,挺著啤酒肚,髮際線嚴重後移的中年男子。 手拿泡著枸杞的保溫杯,胳膊夾著MacBook,MacBook上還貼著公司標語:“我愛加班”。 面試開始,直入正題。 面試官: 看你簡歷上面寫著精通MySQL,我先問你事務的特性是什麼? 老生常談,這個還有誰不會背的嗎? 我: ...
  • 基礎知識 python是一門腳本語言,它是解釋執行的。 python使用縮進做為語法,而且python2環境下同一個py文件中不能同時存在tab和空格縮進,否則會出錯,建議在IDE中顯示縮進符。 python在聲明變數時不寫數據類型,可以type(xx)來獲取欄位的類型,然後可以int(),list ...
  • 為什麼要多線程下載 俗話說要以終為始,那麼我們首先要明確多線程下載的目標是什麼,不外乎是為了更快的下載文件。那麼問題來了,多線程下載文件相比於單線程是不是更快? 對於這個問題可以看下圖。 橫坐標是線程數,縱坐標是使用對應線程數下載對應文件時花費的時間,藍橙綠代表下載文件的大小,每個線程下載對應文件2 ...
  • 詳細講解python爬蟲代碼,爬微博搜索結果的博文數據。 爬取欄位: 頁碼、微博id、微博bid、微博作者、發佈時間、微博內容、轉發數、評論數、點贊數。 爬蟲技術: 1、requests 發送請求 2、datetime 時間格式轉換 3、jsonpath 快速解析json數據 4、re 正則表達式提... ...
  • 背景: 一般我們可以用HashMap做本地緩存,但是HashMap功能比較弱,不支持Key過期,不支持數據範圍查找等。故在此實現了一個簡易的本地緩存,取名叫fastmap。 功能: 1.支持數據過期 2.支持等值查找 3.支持範圍查找 4.支持key排序 實現思路: 1.等值查找採用HashMap2 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 本章是系列文章的第八章,用著色演算法進行寄存器的分配過程。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 寄存器分配 寄存器分配是為程式處理的值找到存儲位置的問題 這些值可以存放到寄存器,也可以存放在記憶體中 寄存器更快,但數量有限 記憶體很多,但 ...