顯示具有 component 標籤的文章。 顯示所有文章
顯示具有 component 標籤的文章。 顯示所有文章

2021年1月13日 星期三

vue component的強制重新render

不知道大家有沒有遇過想要重置component的時候呢,不論是在validate後想要消除紅匡,或是在某些特定場合取到資料後,需要重新繪製畫面,最直覺的作法應該是透過if消除畫面後再重新顯示吧,程式碼如下

<template>
<div v-if="show">
hello
<button type="button" @click="rerender()"></button>
</div>
</template>

<script>
export default {
data: () => ({
show: true
}),
methods: {
rerender() {
this.show = false
this.$nextTick(() => {
this.show = true
}))
}
}
}
</script>

但這樣小編總覺得不是這麼直覺跟簡潔!

那有沒有更簡單的方式呢?有的!只要利用key這個屬性讓這個component屬於一個全新的物件就可以了

<template>
<div :key="index">
hello
<button type="button" @click="rerender()"></button>
</div>
</template>

<script>
export default {
data: () => ({
index: 0
}),
methods: {
rerender() {
this.index++
}
}
}
</script>


2021年1月7日 星期四

改變Vue sub component樣式

相信元件帶給大家的好處不言而喻,但使用上總是有一些不方便之處,例如三方的元件樣式我能否調成自己喜歡的?我自己的元件在不同情境下樣式能否不一樣?難道最終都難逃考比爬斯特,重新寫一個的命運嗎?

小編的任務就是盡可能幫各位提早下班,第一個問題,我們可以寫個全域css去改變他

先假設我們的子元件長這樣

// hello.vue
<div class="component-hello">
  hello
</div>
<style scoped>
  .component-hello {
    colorred
  }
</style>

父元件長這樣

// App.vue
<div class="app">
  <hello />
</div>

<style>
  .app .component-hello {
    colorblue
  }
</style>

在先不考慮css分數的情況下,這樣寫原則上就可以覆蓋component裡面的樣式。

雖然一般三方class寫都得不錯,不太會有重複的情況,但css汙染在我心目中跟watch一樣危險,有很多不可控的因素,所謂的不可控,所謂的黑魔法,就是當下可能會覺得很爽,一個禮拜之後就會變成導致你加班的原因,且一個不小心就會演變成泥沼戰(就是比誰宣告比較兇),所以能不要互相汙染、互相傷害就不要去做這種事,能寫sooped就給他用力寫,為這社會帶來一絲和諧吧!

然而你會發現當你加上了scoped,你原本吃的到css一夕之間的突然都吃不到了,原因是因為scoped會為該component的所有tag注入一個唯一的屬性(亂數產生),但卻不會為子component注入該屬性,所以導致子component吃不到上層scoped的css。那這問題怎麼要解呢?

這就是今天寫這篇主題的目的:那就是使用v-deep,用法很簡單如下。

// App.vue
<div class="app">
  <hello />
</div>

<style scoped>
  .app /deep/ .component-hello {
    colorblue
  }
</style>

這樣就可以控制在App.vue下的component-hello顏色才會是藍色,這樣也同時解決了我們上述的第二個問題,同一個元件在不同class下可以有不同樣式就是這樣來的。

大部分語言也可以簡寫成如下,我以stylus為例

<style lang="stylus" scoped>
  .app >>> .component-hello 
    color blue
</style>

scss或sass語言也可以簡寫成如下

<style lang="stylus" scoped>
  .app ::deep .component-hello 
    color blue
</style>

打完收工下班!

Vue component的v-model

承繼上一篇,我們在撰寫component時,除了要接value,如果data改變,同時也要emit出去,所以程式碼就會如下

export default {
  props: ["value"],
  data: () => ({
    data: ""
  }),
  watch: {
    data() {
      this.$emit("input"this.data);
    },
    value: {
      immediate: true,
      handler() {
        this.data = this.value;
      }
    }
  }
};

乍看之下也沒什麼問題,小編也這樣寫了好幾年了,但小編一直對於宣告一個data:""感到不是很舒服,雖然只是個過水變數,但沒有更乾淨的寫法嗎?還有小編其實一直對於watch很感冒,watch用得好可以帶你上天堂,用不好你就好幾天不用下班,甚至忙到你小孩覺得你只是個很有趣的叔叔!所以能不用就不要用,因此這幾天在賺國產車時想到一個妙招,可以使用computed的set阿!!直接超級簡化,我們直接來看程式碼

export default {
  props: ["value"],
  computed: {
    data: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit("input"val);
      }
    }
  }
};

是不是簡單很多呢,打完收工下班!