乐趣区

关于前端:VUE-组件-组件通讯

组件 & 组件通信

原文链接:https://note.noxussj.top/?source=sifo

上一篇有介绍到什么是组件化,就是把一个页面拆分成若干个小模块,而后从新组成一个页面。其中的每个小模块就是对应一个 .vue 文件。在组件的应用上咱们还须要留神组件的引入和调用的命名形式,以及组件之间的数据是如何传递的。


组件注册

组件在应用之前必须要先注册。注册后才可能应用该组件。

<template>
    <div class="hello">
        <!-- 调用组件 -->
        <MyChildren></MyChildren>

        <!-- 或者简化写法 -->
        <MyChildren />
    </div>
</template>

<script>
import MyChildren from './MyChildren.vue' // 引入组件

export default {components: { MyChildren} // 注册组件
}
</script>

组件命名

组件的命名个别有两种,下面的例子中就是属于第一种,PascalCase 大写驼峰的模式。第二种是 kebab-case 小写横杠模式。

<template>
    <div class="hello">
        <!-- 调用组件 -->
        <my-children></my-children>

        <!-- 或者简化写法 -->
        <my-children />
    </div>
</template>

<script>
import MyChildren from './my-children.vue' // 引入组件

export default {components: { MyChildren} // 或者简化写法
}
</script>

当应用 kebab-case 注册一个组件时,你只能应用 kebab-case 模式进行调用组件,例如 <my-component-name />

当应用 PascalCase 注册一个组件时,你能够应用 PascalCase 或者 kebab-case 模式进行调用组件。例如 <my-component-name /> 或者 <MyComponentName />


组件通信

组件通信分为父子组件通信、兄弟组件通信、祖孙组件通信。本章重点介绍父子组件通信。以下面的例子持续解说。

Props

props 是用来接管父组件传递过去的动态 / 动态数据。

Home.vue

<template>
    <div class="hello">
        <MyChildren name="xiaoming" :age="age" />
    </div>
</template>

<script>
import MyChildren from 'MyChildren.vue'

export default {components: { MyChildren},
    data() {
        return {age: 18}
    }
}
</script>

MyChildren.vue

<template>
    <div class="my-children">
        {{name}}
        {{age}}
    </div>
</template>

<script>
export default {
    props: {
        name: {
            type: String,
            default: ''
        },
        age: {
            type: Number,
            default: 0
        }
    }
}
</script>

通过下面的例子能够看到父组件 Home.vue 向子组件 MyChildren.vue 传递了 name 和 age 属性。子组件如果想要应用该属性,就必须在 props 选项中进行接管。

Props 接管的语法有几种,别离是数组、对象的模式。举荐应用对象模式,并且设置默认值。

Props 语法

应用字符串数组的模式。

<script>
export default {props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
}
</script>

然而,通常都会心愿每个 prop 都有指定的值类型。这时,你能够以对象模式列出 prop,这些 property 的名称和值别离是 prop 各自的名称和类型。

<script>
export default {
    props: {
        title: String,
        likes: Number,
        isPublished: Boolean,
        commentIds: Array,
        author: Object,
        callback: Function,
        contactsPromise: Promise // or any other constructor
    }
}
</script>

如果设置了每个 prop 的类型,然而你没有依照规定的类型传递数据进来,Vue 会在浏览器的控制台中收回正告。

单向数据流

单向数据流指的是数据的流向是从父组件流向子组件,从上往下流。父级 prop 的更新会向下流动到子组件中,然而反过来则不行。这样会避免从子组件意外变更父级组件的状态,从而导致你的利用的数据流向难以了解。

额定的,每次父级组件产生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件外部扭转 prop。如果你这样做了,Vue 会在浏览器的控制台中收回正告。

一个尝试批改 props 值的谬误示范

<template>
    <div class="base-header"> 我批改了 props 的值 {{age}}</div>
</template>

<script>
export default {
    props: {
        age: {
            type: Number,
            default: 0
        }
    },
    mounted() {this.age = 100}
}
</script>

单向数据流其实很好了解的,当一个父组件外面有 n 个子组件,并且别离给 n 个子组件传递了同一个 age 属性,在每个子组件中都进行批改了 age。那么展现的时候以谁改的为准呢?因为父组件和 n 个子组件是共享了 age,所以一个中央改了 age 那么大家展现的时候都一起被改了。

在举例一个蹩脚的状况,一个父组件传递了 age 属性给 n 个子组件,n 个子组件又把这个 age 传递给了它们的子组件,以此类推 n 层深度。当你发现 age 展现的数值不正确的时候,你能在这 n n n * n 个组件中找到是谁改了吗?

如果应用单向数据流,当你遇到不可形容的谬误的时候,你就会很容易排查问题。假如你发现 age 显示不正确。那么你只须要在最顶级的父组件中去排查即可,而不须要每个子组件外面都去排查。

自定义事件 $emit

在父组件中能够通过 v-on 或者 @ 在子组件身上进行监听事件,子组件通过调用 $emit 能够触发父组件监听的事件,同时还可能传递参数。

Home.vue

<template>
    <div class="home">
        <MyChildren name="xiaoming" :age="age" @changeAge="handleChange" />
    </div>
</template>

<script>
import MyChildren from './MyChildren.vue'

export default {components: { MyChildren},
    data() {
        return {age: 18}
    },
    methods: {handleChange(val) {this.age = val}
    }
}
</script>

MyChildren.vue

<template>
    <div class="my-children">
        {{age}}

        <button @click="handleClick"> 点我批改父组件的 age</button>
    </div>
</template>

<script>
export default {
    props: {
        age: {
            type: Number,
            default: 0
        }
    },
    methods: {handleClick() {this.$emit('changeAge', this.age + 1)
        }
    }
}
</script>

原文链接:https://note.noxussj.top/?source=sifo

退出移动版