iT邦幫忙

9

[筆記][Vue.js]打開Vue.js世界的大門(2)-是或不是,不然就怎樣的條件判斷

前陣子和朋友在書局逛街的時候,他問了一句話:
「欸!你都是怎麼重頭學習一個新技術的啊?」
在記憶裡,我是這樣回答的:
「很簡單啊,做就對了!」

沒錯!

就是這樣子,所以第二天的我們繼續做下去吧XD


條件判斷式

一、那該怎麼使用if?

在Vue.js中,v-if的使用非常直觀,就像以下這樣:
HTML

<div id="vueDiv" v-if="status">
    {{text}}
</div>

JavaScript

let vueData = {
    text : 'Hello!Wrold!',
    status : true,
} 

let vueDiv = new Vue({
    el:'#vueDiv',
    data:vueData,
})

在HTML中使用v-if="status"去判斷status內的資料是truefalse,如果是true的話就顯示;false則隱藏,不過上述的例子可能看不出什麼v-if的作用,以下在console中改變status的值,當值被改變時,Vue.js也會重新繫結判斷:

  1. status=true的初始畫面,會看到Hello!Wrold!
    https://ithelp.ithome.com.tw/upload/images/20180815/20106935mlL1Lyjmwc.jpg
  2. status的值變成false,Hello!Wrold!會被隱藏起來。
    https://ithelp.ithome.com.tw/upload/images/20180815/20106935XyhwtYwoYF.jpg

二、既然有v-if那會不會有v-else-ifv-else

有的,讓我們繼續看下去吧!
HTML

<div id="vueDiv" >
    <span v-if="status == 'A'">我是小明</span>
    <span v-else-if="status == 'B'">我是小華</span>
    <span v-else>我是神Q</span>
</div>

JavaScript

let vueData = {
    status : 'A',
}

let vueDiv = new Vue({
    el:'#vueDiv',
    data:vueData,
})

在上方的HTML用一層div包住了三個span,並透過v-if來綁定status的判斷,如果等於A就顯示小明;等於B就顯示小華;都不是的話顯示神Q。如此一來就可以透過程式般的方式去控制目前要顯示的DOM,要注意的是v-else-ifv-else都是跟著v-if跑的,如果在他們上面沒有v-if,是不會有任何作用的。

另外,Vue.js的條件判斷為了更有效率的做切換DOM的動作,如果是目前已經在畫面上的DOM,就不會把他移除再建立一個,而是直接改變兩個DOM不同的地方而已,官方有舉一個例子說明這件事情:
HTML

<div id="vueDiv" >
    <input v-if="status" placeholder="輸入姓名">
    <input v-else="status" placeholder="輸入mail">
    <input type="button" value="切換輸入" @click="changeStatus">
</div>

JavaScript

let vueData = {
    status : true,
}

let vueMethods = {
    //切換status的值
    changeStatus : () =>{
        vueData.status ? vueData.status = false : vueData.status = true
    }
}

let vueDiv = new Vue({
    el:'#vueDiv',
    data:vueData,
    methods:vueMethods,
})

結果會如下,當他被點擊改變status的值後,inputplaceholder屬性值會變,但是這並不代表他是把input換掉了,就像我剛剛提到的,Vue.js為了提高效能,只會重新繪製不同的地方,這種做法類似於replace(),可以試著把input填入值,在點擊按鈕切換input會發現我們輸入的value不會消失,就是他只替換掉placeholder屬性值的最好證明了!
未輸入值之前,inputplaceholder會改變:
https://ithelp.ithome.com.tw/upload/images/20180815/20106935nbZA74oWqE.jpg
當填入值後,會發現就算切換了value也不會清空或改變:
https://ithelp.ithome.com.tw/upload/images/20180815/20106935e3VB2OXcye.jpg
不過這個方式有好有壞!如果是想要完全獨立兩個input反而會有點麻煩,所以Vue.js幫大家想了一個方法,那就是使用key去為每個input做一個識別,這樣就會重新繪製了!這裡只需調整HTML
HTML

<div id="vueDiv" >
    <input v-if="status" placeholder="輸入姓名" key="userName">
    <input v-else="status" placeholder="輸入mail" key="userEmail">
    <input type="button" value="切換輸入" @click="changeStatus">
</div>

沒有輸入值的結果就和上方一樣,直接來看看填入value值後切換吧!
https://ithelp.ithome.com.tw/upload/images/20180816/20106935yjssfWP0wN.jpg
所以大家可以知道v-if的基本用法,還有v-if的切換是會把DOM給移除再新增的!也因為這一點,所以上方的例子才會在從mail的input切回name的input時清空value值,其實也不是清空,只是因為他重新繪製了,所以value的值就不會留著。

三、如果v-if會把DOM給移除,那有沒有不移除的方法?

可能有些人會這麼想,

這也能當標題?才沒人會在乎這個吧!

錯!就算真的沒人在乎,Vue.js也在乎,於是我們有了v-show這個屬性可以用,他的用法和v-if很類似,不過沒有分支;只有唯一,來看看吧!
HTML

<!--把以上範例的v-if改成v-show-->
<div id="vueDiv" >
    <input v-show="status" placeholder="輸入姓名" key="userName">
    <input v-show="status == false" placeholder="輸入mail" key="userEmail">
    <input type="button" value="切換輸入" @click="changeStatus">
</div>

JavaScript的部分依然不需要改變,據官方說法v-show是使用CSS去控制他的隱藏和顯示,於是我一個好奇去看HTML點擊按鈕後的變化,哦原來是熟悉的display:none
https://ithelp.ithome.com.tw/upload/images/20180815/20106935e5sD7712eJ.jpg
知道原理後,應該想像的到運行後的結果,就算是相互切換也不會清掉value的值,畢竟只是透過CSS去隱藏而已:
https://ithelp.ithome.com.tw/upload/images/20180815/20106935hHUUFbJEjx.jpg

所以我們可以對這兩種用法下個結論(感謝fysh711426大大留言補充):

  • 使用v-if一開始再載入的畫面較少,但是切換畫面會重新繪製資料,資料一多會比較吃效能。
  • 使用v-show一開始就會先將全部的DOM繪製,切換則是透過CSS去控制,所以在切換時的效能耗損較少。

如果一開始的資料龐大可以選擇v-if減少載入時間,但如果覺得切換時會有一些不順,就可以改用v-show減少切換的效能,以上兩個方式在使用上就互相搭配囉!。


關於條件判斷v-ifv-show的基本用法先告一段落了,其實今天本來要連迴圈一起講,但是時間有限,明天還要上工XD,所以就一個壯士斷腕直接移到明天去,不然我怕趕出來的文章品質也不會很好,希望自己以後再回來看也不會有「天哪!到底再寫什麼?」的感覺,哈哈哈。

最後感謝各位大大的觀看,如果文章中有什麼問題、解釋不清楚或是理解錯誤的地方,還請麻煩留言告訴我,謝謝大家/images/emoticon/emoticon41.gif


2 則留言

1

ng1 也分 ifshow,不過沒有 if else 的用法。

原來 if else 會優化 dom,這個我不知道趕快筆記。 /images/emoticon/emoticon37.gif

會不會移除 dom 對 ng1 蠻重要的呢,因為 ng1 有髒檢查,所以需要提升效能時會用到,
Vue 則沒有髒檢查的問題,除非大量切換不然應該不太需要在意,哈哈哈。

  • v-show: 昂貴的初始,便宜的切換。
  • v-if: 便宜的初始,昂貴的切換。
看更多先前的回應...收起先前的回應...

大大的ng是Angular嗎?我第一次聽到髒檢查這個詞/images/emoticon/emoticon16.gif

是因為在資料綁定的時候,他不知道哪個表單的資料有變,所以每次都會全部檢查在綁定一次嗎?

最後對v-ifv-show的差別講好好!
我可以補充進去文章中嗎/images/emoticon/emoticon33.gif

tacodrem iT邦新手 5 級 ‧ 2018-08-16 13:38:49 檢舉

髒檢查在ng1是個還蠻有名(?)的毛病
據說在ng1的環境下, 如果專案到一定程度(某個page數量以上)就會出現很嚴重的效能問題@@"
所以ng2以後才為了改善這問題, 作出破壞性的更新
不過...是不是真的有改善...嗯....@@"
我也還沒操作過這麼大專案, 不太有感XDD

所以現在ng2使用的比率比較高嗎@@
想說年底前把前端的主要框架都摸過一遍XD

因為我第一次用這種資料前端框架,
所以很多東西還不太熟悉,
之後有機會分享ng的文章再麻煩大大們指點了XD

恩 ng1 是指 AngularJS。

例如觸發 ng-click 事件,ng1 會去檢查所有綁定元素是否有資料異動,有的話會去更新畫面,不過每次檢查所有元素這個動作,可能會導致效能不好,因此被稱為髒檢查。

可以補充,哈哈哈。 /images/emoticon/emoticon37.gif

使用率不太清楚,但感覺很多人跑去用 Vue (<-我也想用),哈哈哈。

tacodrem 同時綁定的元素大概 500 個左右就會有感覺,1000 以上就會很卡,在做列表時如果沒控制好數量,常常爆掉 XD。

小弟對 ng2 不太熟,據我所知 ng2 的確有改善,不過髒檢查還是存在,而事件因為是 zone.js 觸發,所以讓人感覺好像沒有 $apply() 機制,但其實還是存在。

ng2 主要是利用 组件樹單向數據流 來改善效能問題,ng2 的結構有點像 React 是由一顆組件樹組成,資料的檢測是由父组件到子组件,由上而下,因為資料流是單向,所以可以控制在一次檢查內就達到穩定狀態 (例外狀況除外),而 ng1 因為資料流錯綜複雜,可能需要檢測好多次才會穩定,

除此之外 ng2 還可以由我們自訂各組件的變化檢測器,決定需要檢查的範圍,以上這兩點是我所知 ng2 改善的地方,有錯誤再麻煩各位大大提點。
/images/emoticon/emoticon41.gif

fysh711426大大可以一起入坑啊XD
我也才剛學而已,哈哈哈!
以後也會跑去學Angular,但是應該是2啦XD
不過又怕用的人不多/images/emoticon/emoticon13.gif
看大大的說明ng好像有點複雜,ng2改善後比較單純,
但是我也還沒去找過相關資料,只有今天早上查了髒檢查/images/emoticon/emoticon06.gif
話說大大不會想學學看ng2嗎?哈哈。

tacodrem iT邦新手 5 級 ‧ 2018-08-17 09:01:36 檢舉

其實現在的話, 可以直接跳ng6+SCSS喔~~= =+
哈哈~Angular CLI都幫你做好好了, 習慣之後, 是真的還蠻好用的XDD
這方面可以多看看保哥的文章, 他也是個NG教派的信眾~XD

tacodrem iT邦新手 5 級 ‧ 2018-08-17 09:03:18 檢舉

fysh711426
果然~我經手過的專案還沒有哪個是在單頁裡面跑這麼多綁定的
哈哈哈~不過也可能因為事先知道, 所以都會盡量減少單頁綁定數量就是了

0
jack1234552000
iT邦新手 5 級 ‧ 2019-08-28 23:26:26

上面這一段
「Vue.js的條件判斷為了更有效率的做切換DOM的動作,如果是目前已經在畫面上的DOM,
就不會把他移除再建立一個」

可是下面為什麼又說「v-if的切換是會把DOM給移除再新增的」呢?

那是不是一開始先說
vue-if 會移除DOM新增
vue-show 會只顯示需要的DOM
這樣簡述會更好呢?

嗨!剛剛重新看了一下整篇文章,其實是有上下文的,

Vue 只會重新 Render 改變的地方,

也就是說,第一個例子裡是用同一個 input 在做 placeholder 的變化,那會重新 Render 的地方就只有 placeholder ,他確實沒有移除掉原本的 input ,文章中也有舉例子了( value 切換時的值不會消失)

然後比較有爭議的地方是第二點的例子,

切換的地方不再是 placeholder ,而是整個 input

在這個情況下,因為改變的地方是 input ,所以 Vue 就把整個 input 給移除,再重新 Render 一個。

所以這兩個結論都是以 v-if 的使用其境對例子本身做講解,我也會考慮如何補充才不會讓人誤會,謝謝指教 :)

我要留言

立即登入留言