Vue2.x 文档笔记-3

本文最后更新于:2023年6月27日 晚上

Vue2.x 文档笔记-3-深入了解组件部分

组件注册

全局注册

1
Vue.component('component-name', { ... })

局部注册

1
2
3
4
5
6
7
var vm = new Vue({
components: {
component-a: {
template:"<h1>Hello!</h1>"
}
}
})

Prop

prop类型

我们可以为每个prop指定值类型,这和python的类型提示十分相似,那就是在属性名后面加冒号,然后再带上期待的值类型:

1
2
3
4
5
props: {
title: String,
likes: Number,
isPublished: boolean
}

传递静态或动态Prop

如果我们想告诉prop我们将要传递的值不是字符串,而是一个JavaScript表达式的话,就需要使用v-bind指令:

1
2
3
4
5
6
7
<!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post>

<!-- 即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

单向数据流

我们不应该一个子组件内部改变prop。如果子组件中需要用到prop的值,可以定义一个本地的data property或者计算属性:

  1. 定义本地data property:

    1
    2
    3
    4
    5
    6
    props: ['initialCounter'],
    data: function () {
    return {
    counter: this.initialCounter
    }
    }
  2. 定义计算属性:

    1
    2
    3
    4
    5
    6
    props: ['size'],
    computed: {
    normalizedSize: function () {
    return this.size.trim().toLowerCase()
    }
    }

prop验证

在本节开头的prop类型其实就是prop验证。如果传入的值不满足需求,那么Vue会在浏览器控制台警告你(注意了,只是警告)。

当然prop验证还支持很多定制验证,如多个可能的类型、必填、带默认值等等。

非Prop的Attribute

一个非prop的attribute是指传向一个组件,但是该组件并没有相应prop定义的attribute。

虽然组件中没有相关定义,但是这个attribute仍会自动添加到组件的根元素上。

替换/合并已有的Attribute

对于绝大多数attribute来说,从外部提供给组件的值会替换掉组件内部设置好的值,比如type属性,假设现在有一个组件的根元素上是type="date",但如果我们提供了type="input"的话,那这个组件就会从日期选择器变成输入框,而这不是我们想要的结果。

但是有两个例外,classstyle并不会替换,而是合并。比如组件内部提供了class="red",而外部传入了一个class="big",那么最终得到的是class="red big"

禁用Attribute继承

如果不希望组件的根元素继承attribute,可以在组件的选项中设置inheritAttrs: false

自定义事件

事件名

事件名请使用kebab-case命名规范进行命名

自定义组件的v-model

一个组件上的v-model默认会利用名为value的prop和名为input的事件,但是我们可以对其进行自定义:

1
2
3
4
5
6
7
Vue.component('example', {
model: {
prop: 'prop-name',
event: 'event-name'
},
...
})

.sync修饰符

我们可以对一个prop进行“双向绑定”,即子组件的值变更时也能够反馈到父组件上。

假设现在有一个子组件,内含一个名为title的prop,我们想在这个title的值更新时,让父组件的某个值也进行更新,那就可以用update:myPropName的模式触发事件来实现:

1
this.$emit('update:title', newTitle)

在父组件中监听这个事件并根据需要更新即可:

1
2
3
4
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>

这种模式的缩写就是.sync修饰符:

1
<text-document v-bind:title.sync="doc.title"></text-document>

注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用!

插槽

具名插槽

这个功能使得我们能够在组件里面创建很多个插槽而互不干扰、正常渲染。在创建插槽时,使用<slot>元素的 name属性为这个插槽命名:

1
2
3
4
5
6
7
8
<div class="container">
<div>
<slot name="first"></slot>
</div>
<div>
<slot name="second"></slot>
</div>
</div>

然后在为这些具名插槽提供内容时,就在<template>元素中使用v-slot指令来指定我们需要传入的插槽:

1
2
3
4
5
6
7
8
<component-name>
<template v-slot:first>
<span></span>
</template>
<template v-slot:scecond>
<p></p>
</template>
</component-name>

作用域插槽

其实就是让父组件能访问到子组件中的某些data的功能。比如子组件中有一个userdata,要让这个data在父级的插槽内容可用,可以将user作为<slot>元素的一个attribute绑定上去:

1
2
3
<div>
<slot v-bind:user="user"></slot>
</div>

绑定在<slot>元素上的attribute被称为插槽prop

在父组件中,我们可以使用带值的v-slot来定义我们提供的插槽prop的名字,并且使用该插槽prop:

1
2
3
4
5
<component-name>
<template v-slot:default="slotProps">
{{ slotProps.user.name }}
</template>
</component-name>

default其实就是默认插槽,插槽不带名就等于<slot name="default">

具名插槽的缩写

v-onv-bind一样,v-slot也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符#。例如v-slot:header可以被重写为#header


这里有一只爱丽丝

希望本文章能够帮到您~


Vue2.x 文档笔记-3
https://map1e-g.github.io/2023/06/25/vue-learning-5/
作者
MaP1e-G
发布于
2023年6月25日
许可协议