从零开始学VUE之组件化开发(父子组件的通信)

父子组件的通信

为什么需要通信

  • 在开发中往往一些数据确实需要下面的子组件进行展示
    • 比如在一个页面中,我们从服务器请求了很多的数据,其中一部分数据并不是页面的大组件来展示的,而是需要下面的子组件进行展示,这个时候肯定不会让子组件再次调用网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)

如何通信

  • 父组件通过props属性将数据传递给子组件
  • 子组件通过自定义事件向父组件传递数据

父组件向子组件传递数据[props:字符串数组类型]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../../js/vue.js"></script>
</head>
<body>
<div id="app">
<!--    静态传值-->
    <cpn ctitle="title" cmovies="movies"></cpn>
<!--    动态传值-->
    <cpn :ctitle="title" :cmovies="movies"></cpn>
</div>
</body>
<template id="cpn">
    <div>
        {{ctitle}}
        {{cmovies}}
    </div>
</template>
<script>

    const cpn = {
        template:'#cpn',
        // 使用数组进行传值 在里面声明需要传输数据的key,在使用的时候通过属性就可以传递值了
        props:[
            'ctitle',
            'cmovies'
        ]
    }

    // 创建vue
    const vue = new Vue({
        el: '#app',
        data: {
            title:'this is title',
            movies: ['spring','springboot','springmvc','springData']
        },
        components:{
            // ES6 增强KEY 不写KEY 默认和值 一致
            cpn
        }
    })
</script>
</html>

运行效果

父组件向子组件传递数据[props:对象(带验证)]

组件可以为 props 指定验证要求。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。

props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

type(验证类型) 可以是下面原生构造器:

String

Number

Boolean

Array

Object

Date

Function

Symbol

type 也可以是一个自定义构造器,使用 instanceof 检测

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../../js/vue.js"></script>
</head>
<body>
<div id="app">
    <cpn :ctitle="title" :cmovies="movies"></cpn>
</div>
</body>
<template id="cpn">
    <div>
        {{ctitle}}
        {{cmovies}}
    </div>
</template>
<script>

    const cpn = {
        template:'#cpn',
        // 使用对象进行传值可以对key的value进行校验
        props: {
            ctitle:{
                // 类型为String 如果可能是多个采用 字符串数组
                type:String,
                // 是否必传
                required:true,
                // 默认值
                default:'没有传递数据'
            },
            cmovies:{
                // 可能是多个值
                type:[Array,Object],
                // 不是必填
                required: false,
                // 数组和对象的默认值必须由函数返回
                default(){
                    return [];
                }
            }
        }
    }

    // 创建vue
    const vue = new Vue({
        el: '#app',
        data: {
            title:'this is title',
            movies: ['spring','springboot','springmvc','springData']
        },
        components:{
            // ES6 增强KEY 不写KEY 默认和值 一致
            cpn
        }
    })
</script>
</html>

运行效果

父组件向子组件传递数据[props:驼峰命名问题]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../../js/vue.js"></script>
</head>
<body>
<div id="app">
<!--    采用大写将接收不到值-->
    <h2>cTitle</h2>
    <cpn :cTitle="title"></cpn>
<!--    自动转换 cTitle->c-title-->
    <h2>c-title</h2>
    <cpn :c-title="title"></cpn>
</div>
</body>
<template id="cpn">
    <div>
        {{cTitle}}
    </div>
</template>
<script>

    const cpn = {
        template:'#cpn',
        // 使用对象进行传值可以对key的value进行校验
        props: {
            // 使用驼峰命名时,在属性传值的时候会自动将驼峰转为中横线+小写
            cTitle:{
                // 类型为String 如果可能是多个采用 字符串数组
                type:String,
                // 默认值
                default:'没有传递数据'
            }
        }
    }

    // 创建vue
    const vue = new Vue({
        el: '#app',
        data: {
            title:'this is title'
        },
        components:{
            cpn
        }
    })
</script>
</html>

运行效果

子组件向父组件传递数据[自定义事件]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../../js/vue.js"></script>
</head>
<body>
<div id="app">
    <!--不是cli中 暂时不要写驼峰 因为我写了转 成中横线和小写也不行,暂时就全写小写 -->
    <!--@querybyitemname 这个事件就是自定义事件 通过子组件使用$.emit发射出来的-->
    <cpn @querybyitemname="queryByItemName"></cpn>
</div>
</body>
<template id="cpn">
    <div>
        <button v-for="item in categories" @click="itemClick(item)">{{item.name}}</button>
    </div>
</template>
<script>

    const cpn = {
        template: '#cpn',
        data() {
            return {
                categories: [
                    {id: 'a', name: '热门推荐'},
                    {id: 'b', name: '手机数码'},
                    {id: 'c', name: '家用电器'},
                    {id: 'd', name: '电脑办公'}
                ]
            }
        },
        methods: {
            itemClick(item) {
                // 通过自定义事件'querybyitemname'方法并传递参数'item',需要在组件调用的时候通过@也就是v-on监听
                this.$emit('querybyitemname', item);
            }
        }
    }

    // 创建vue
    const vue = new Vue({
        el: '#app',
        data: {},
        methods: {
            // 用于子组件调用
            queryByItemName(item) {
                console.log(JSON.stringify(item));
            }
        },
        components: {
            cpn
        }
    })
</script>
</html>

运行结果

 

作者:彼岸舞

时间:2021\06\02

内容关于:VUE

本文属于作者原创,未经允许,禁止转发

posted @ 2021-06-02 14:47  彼岸舞  阅读(73)  评论(0编辑  收藏  举报