Vue 學習記錄三

zs4336發表於2019-12-02

元件

我們在程式設計的時候時刻提醒自己DRY(Do not repeat yourself),元件化可以很大提高開發效率,並且是整體程式碼顯得優雅,但首要前提是曉得怎麼使用。下面,就按我的理解給大家介紹下吧。

元件可以分為區域性元件和全域性元件,其中最最重要的是元件之間的通訊。

Mbx5ZQ

區域性元件

舉例子吧,現在Vue這麼火,文字敘述太枯燥,首先宣告,這些例子是在cli3搭建的腳手架環境下。新建 components/CountDown.vue 倒數計時元件。

<template>
    <text>
        <text>{{timer.day}}天</text>
        <text>{{timer.hour}}時</text>
        <text>{{timer.minute}}分</text>
        <text>{{timer.second}}秒</text>
    </text>
</template>

<script>
    export default {
        name: "CountDown",
        props:{
            time:{
                type:String,
                default:'0',
            }
        },
        data() {
            return {
                timer: {
                    day: 0, //天
                    hour: 0, //小時
                    minute: 0, //分鐘
                    second: 0, //秒
                },
                ref: null, //定時器引用
                futureTime: 0, //截至時間點
            }
        },
        created() {
            this.transformTime(this.time);
            this.startTimer();
        },
        methods: {
            startTimer() {
                this.ref = setInterval(() => {
                    this.play();
                }, 1000)
            },
            endTimer() {
                clearInterval(this.ref)
            },
            play() {
                let currentTime = new Date().getTime();
                let diffNum = this.futureTime - currentTime;
                if (diffNum > 0) {
                    //總秒數
                    let totalSeconds = parseInt(diffNum / 1000);
                    //天數
                    let days = Math.floor(totalSeconds / (60 * 60 * 24));
                    //取模(餘數)
                    let modulo = totalSeconds % (60 * 60 * 24);
                    //小時數
                    let hours = Math.floor(modulo / (60 * 60));
                    modulo = modulo % (60 * 60);
                    //分鐘
                    let minutes = Math.floor(modulo / 60);
                    //秒
                    let seconds = modulo % 60;

                    this.timer.day = days.toString().length === 1 ? '0' + days : days;
                    this.timer.hour = hours.toString().length === 1 ? '0' + hours : hours;
                    this.timer.minute = minutes.toString().length === 1 ? '0' + minutes : minutes;
                    this.timer.second = seconds.toString().length === 1 ? '0' + seconds : seconds;
                } else {
                    this.endTimer();
                    this.timer.day = 0;
                    this.timer.hour = 0;
                    this.timer.minute = 0;
                    this.timer.second = 0;
                }
                //console.log(this.timer);
            },
            transformTime(formatTime) {
                let futureTime = new Date(formatTime).getTime();
                if (!isNaN(futureTime)) {
                    this.futureTime = futureTime;
                }
            }
        },
    }
</script>

<style scoped>

</style>

區域性元件是建好了,那麼怎麼使用呢?新建一個 pages/test.vue 檔案,但是需要在該檔案中引入並宣告倒數計時元件。

<template>
    <view>
        <!-- 3、使用區域性元件 -->
        活動倒數計時:<CountDown :time="endTime"></CountDown>
    </view>
</template>

<script>
    //1、引入區域性元件
    import CountDown from '@/components/CountDown'

    export default {
        //2、宣告注入區域性元件
        components:{
            CountDown
        }
        data(){
            return {
                endTime:'2019-11-23 00:00:00',
            }
        }
    }
</script>
<style scope>

</style>

區域性元件的使用步驟就像上例所示,首先定義一個元件,然後再另外一個元件裡面引入並註冊它,然後就可以使用啦。
另外需要提示的是prop關鍵字,它可以是陣列或物件,用於接收來自父元件的資料。它有以下幾個選項:

  • type 指定資料型別。型別可以是 String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定義建構函式、或上述內容組成的陣列
  • default 為 prop 制定一個預設值,物件或陣列的預設值必須從一個工廠函式返回
  • required 定義該prop是否是必填值,Boolean 值
  • validator 自定義驗證函式會將該 prop 的值作為唯一的引數代入
全域性元件

有些元件會被經常用到,可以將它作為全域性元件,下面就舉例怎麼實現。
新建訊息元件src/components/Message.vue

<template>
  <div v-show="show" :class="`alert alert-${type} alert-dismissible`">
    <button @click="close" type="button" class="close"><span>×</span></button>
    {{ msg }}
  </div>
</template>

<script>
  export default {
    name: 'Message',
    props: {
      // 是否顯示訊息框
      show: {
        type: Boolean,
        default: false
      },
      // 訊息框的型別
      type: {
        type: String,
        default: 'success'
      },
      // 訊息
      msg: {
        type: String,
        default: ''
      }
    },
    watch: {
      show(value) {
        if (value) {
          this.$nextTick(() => {
            this.$el.scrollIntoView(true)
          })
        }
      }
    },
    methods: {
      close() {
        this.$emit('update:show', false)
      }
    }
  }
</script>

<style scoped>

</style>

新建src/components/index.js

import Vue from 'vue'
import Message from './Message'

const components = [Message];

for (let [key,value] of Object.entries(components)) {
    Vue.component(key,value);
}

在入口檔案中引入全域性元件,src/main.js

import Vue from 'vue'
import App from './App'
import './components'

export new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

注意this.$emit 觸發當前例項上的事件。附加引數都會傳給監聽器回撥。
全域性元件使用Vue.component(key,value)進行註冊

趁還沒掉光,趕緊給每根頭髮起個名字吧~

相關文章