# 父向子传值 props

# 介绍

当我们实际使用此组件的时候,发现这个简单的Button组件并不能满足我们的需求。我们想要的是漂亮的按钮。并且会改变颜色的按钮。漂亮的按钮我们可以通过 css 来美化,那么会改变颜色的按钮是什么意思呢?

从我们前面学习组件的知识来看,我们把组件写成什么样,我们引入过来后,页面就会显示什么样。但是我们总不能挨个把每个颜色的按钮都封装起来吧,那样就太 low 了。

所以,我们要基于目前的Button组件,来实现根据传入不同的值,显示不同颜色的按钮。

Vue 为此提供了props属性,我们可以向组件传入值,并且在组件内可以接收值。大家可以想到,Button.vue是一个按钮组件吧?index.vue是一个“页面”吧?那么我们在index.vue中引入Button.vue,说明index.vue是“父亲”,Button.vue是“儿子”,这就叫父向子传值

# props

在讲解之前,我们需要明确一个概念。我们在index.vue中,想要向Button.vue组件传入值,这个值可以是任何类型的值,然后在Button.vue中接收值。

明确了概念后,我们开始讲props了。

props就是在一个文件内,用来接收值的。跟methods、computed等一样,他们都是相同的地位。不过,props可以有不同的写法:

// first
props: {
  xxx
},
// second

props: [xxx, xxx, xxx],

前面说了,除了美化样式外,我们想要的是不同颜色的按钮。所以,我们可以定义一个color选项,用来接收值的

props: {
    color: {
        type: String,
        required: true
    }
}

我们使用对象的写法,因为可以进行灵活的配置,其中,type为接收的类型,require可以设置为必填项。更多的配置信息请参考官方文档

定义好了接收的color后,我们需要设定值的范围,比如说:['primary', 'success', 'error', 'warning'],不过这个范围是我们自己定义的

<template>
  <div class="container">
    <button :class="color">Click Me</button>
  </div>
</template>

<script>
  export default {
    data() {
      return {}
    },
    props: {
      color: {
        type: String,
        required: true
      }
    },
    components: {},
    computed: {},
    watch: {},
    methods: {},
    created() {},
    mounted() {},
    updated() {},
    destroyed() {}
  }
</script>

<style scoped>
  button {
    border: none;
  }
  .success {
    color: #fff;
    background: forestgreen;
  }
  .error {
    color: #fff;
    background: #ff0000;
  }
  .primary {
    color: #fff;
    background: blue;
  }
  .warning {
    color: #fff;
    background: yellow;
  }
</style>

可以看出来,我们定义颜色的范围是为了我们设置好对应的 class。 接着,使用v-bindcolorclass绑定在一起

以上操作我们基本完成了组件接收值的操作,剩下的就是在父组件中传递值了。这一步非常简单,我们来看

<Button color="success"></Button>

想要传值,我们只需要在使用组件里面添加对应的值即可。我们需要接收color,那么我们就需要在组件里面写上color="xxx",xxx 为你要传入的值,为['primary', 'success', 'error', 'warning']

除了直接写上color="xxx"外,我们还可以对color进行动态的绑定值,比如说:

<Button :color="dynamicColor"></Button>

data () {
    return {
        dynamicColor: 'success'
    }
}

这样,我们就通过变量灵活的控制按钮的颜色了。

# slot

在使用了上面的组件后,我们会发现,虽然可以根据传递color来改变颜色,但是每个按钮的内容全是一样的:Click Me。我们想要的是不同的内容,可能我们需要的是:确定或者是取消。所以,我们还可以在传入一个name选项,用来设置按钮的内容。


// index.vue
<Button :color="dynamicColor" name="确定"></Button>


// Button.vue

<button :class="color" v-text="name"></button>

props: {
    color: {
        type: String,
        required: true
    },
    name: {
        type: String,
        required: true
    }
}

虽然上面同样实现了动态传入按钮的内容,但是略显得麻烦。Vue 提供了一个<slot>插槽,用来接收传过来的内容,可以是 html,非常的方便。

那么我们把关于name的所有代码删除,添加<slot>

<!-- Button.vue -->
<button :class="color">
  <slot></slot>
</button>

<!-- index.vue -->
<button color="error">
  this is a button
</button>

可以看到,我们只需要在Button组件内,添加一个<slot></slot>标签,然后在index.vue里面,像普通标签一样,在组件内填写内容就行了。这就是基本slot插槽的应用。

提示

关于插槽的写法还有很多种,本文只是做一个抛砖引玉,更多写法请参考官方文档

上次更新: 2/3/2020, 9:47:35 PM