Vue 学习记录三

组件

我们在编程的时候时刻提醒自己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)进行注册

本作品采用《CC 协议》,转载必须注明作者和本文链接

趁还没掉光,赶紧给每根头发起个名字吧~

zs4336
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!