Vue进阶—组件的三大核心概念

274 阅读3分钟
原文链接: mp.weixin.qq.com

组件概念

可简单的描述为小型的、一个个独立的可复用的UI模块。完整的网页都是由独立的UI模块拼接而成。

Vue组件就是一个Vue实例,通过 new Vue() 函数的形式来创建一个实例生成的。不同的组件不过是options的不同。

所谓组件的组成的三大核心概念其实就是属性、事件、插槽。

组件的组成—属性

自定义属性 props

在组件props中声明的变量,组件的核心功能也都是它来确定的。

Vue风格指南建议每个定义的属性需要设置类型、默认值或自定义校验属性的值,这对于项目后续的维护或排查错误特别重要。

// 父组件<props-demo  name="Hello Vue!"  :type="type"  :is-visible="false"  :on-change="handlePropChange"  title="属性Demo"  class="test1"  :class="['test2']"  :style="{ marginTop: '20px' }"  style="margin-top: 10px"/>

// 子组件export default {  name: "propsDemo",  // inheritAttrs: false,  // props: ['name', 'type', 'list', 'isVisible'],  props: {    name: String,    type: {      default: 'warning',      validator: function(value) {        // 这个值必须匹配下列字符串中的一个        return ["success", "warning", "danger"].includes(value);      }    },    list: {      type: Array,      // 对象或数组默认值必须从一个工厂函数获取      default: () => []    },    isVisible: {      type: Boolean,      default: false    },    onChange: {    // 不推荐使用onChange这样的命名,组件会与vuex里面的功能点产生冲突      type: Function,      default: () => {}    }  }};

默认情况下父作用域的不被认作 props 的特性绑定将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。

可通过设置 inheritAttrs 为 false,这些默认行为将会被去掉。 注意:这个选项不影响 class 和 style 绑定。

子组件为何不能修改父组件传递的Prop ?

props属性是单向数据流,它的数据都是通过父组件或者更高层级的组件数据或者字面量的方式进行传递的,不允许直接操作改变各自实例中的props数据。

组件的组成—事件

Vue事件分为普通事件和修饰符事件。普通事件主要是@click、@input、@change等事件通过this.$emit() 触发。

修饰符事件

<!-- 阻止单击事件继续传播 --><a v-on:click.stop="doThis"></a><!-- 提交事件不再重载页面 --><form v-on:submit.prevent="onSubmit"></form><!-- 修饰符可以串联 --><a v-on:click.stop.prevent="doThat"></a>

组件的组成—插槽

插槽分为普通插槽和作用域插槽,其实两者很类似,只不过作用域插槽可以接受子组件传递过来的参数。

// 父组件// 2.6 新语法<SlotDemo>  <p>default slot</p>  <template v-slot:title>    <p>title slot1</p>    <p>title slot2</p>  </template>  <template v-slot:item="props">    <p>item slot-scope {{ props }}</p>  </template></SlotDemo>// 老语法<SlotDemo>  <p>default slot</p>  <p slot="title">title slot1</p>  <p slot="title">title slot2</p>  <p slot="item" slot-scope="props">item slot-scope {{ props }}</p></SlotDemo>
//子组件<div>  <slot />  <slot name="title" />  <slot name="item" v-bind="{ value: 'vue' }" /></div>

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即  v-slot 指令)。它取代了  slot 和  slot-scope 。我们来思考个问题: 相同名称的插槽是合并还是替换

  • Vue2.5版本,普通插槽合并、作用域插槽替换

  • Vue2.6版本,都是替换(见下面例子)

总结

所有的属性、事件、插槽都可以通过属性的方式去解决。