组件传值之父传子、子传父、非父子传值

引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。
以字符串数组形式列出的 prop:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

但是,通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop,这些属性的名称和值分别是 prop 各自的名称和类型:

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

这不仅为你的组件提供了文档,还会在它们遇到错误的类型时从浏览器的 JavaScript 控制台提示用户。你会在这个页面接下来的部分看到类型检查和其它 prop 验证。
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
有两种常见的试图改变一个 prop 的情形:
1.这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:

props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

2.这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

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

Vue.component('my-component', {
  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 将会产生一个控制台的警告。

注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default 或 validator 函数中是不可用的。

父组件传值给子组件

父组件

<template>
    <div>
        父组件:<input type="text" v-model="inputName"/>
        <child :inputName='inputName'></child>
    </div>
</template>

<script>
import child from '@/page/child';
export default {
    components: {
        child
    },
    data() {
        return {
            inputName:''
        };
    }
};
</script>

子组件

<template>
    <div>
        子组件:<span>{{inputName}}</span>
    </div>
</template>

<script>
export default {
    // 接收父组件的值,props里面值不能改变
    // props:['inputName',] // 写法一
    props: { // 对象写法
        inputName: {
            type: String,
            require: true
        }
    }

};
</script>

组件传值之父传子、子传父、非父子传值_第1张图片

子组件传值给父组件

方法一:在父组件v-on监听子组件传过来的值
父组件

<template>
    <div>
        父组件:<input type="text" v-model="inputName"/>
        <child :inputName='inputName' v-on:child-by-value="childByValue"></child>
    </div>
</template>

<script>
import child from '@/page/child';
export default {
    components: {
        child
    },
    data() {
        return {
            inputName:''
        };
    },
    methods: {
        childByValue(childValue) {
            this.inputName = childValue;
        }
    }
};
</script>

子组件

<template>
    <div>
        子组件:<span>{{inputName}}</span>
        <div>
            <input type="button" value="给父组件传值" @click="childClick"/>
        </div>
    </div>
</template>

<script>
export default {
    // 接收父组件的值,props里面值不能改变
    // props:['inputName',] // 写法一
    props: { // 对象写法
        inputName: {
            type: String,
            require: true
        }
    },
    data() {
        return {
            childValue: '我是子组件的数据'
        };
    },
    methods: {
        childClick () {
            // child-by-value是在父组件on监听的方法
            // 第二个参数this.childValue是需要传的值
            this.$emit('child-by-value', this.childValue);
        }
    }
};
</script>

组件传值之父传子、子传父、非父子传值_第2张图片
方法二:在父组件上使用.sync
https://www.jianshu.com/p/6b062af8cf01
父组件

<template>
    <div>
        父组件:<input type="text" v-model="inputName"/>
        <child :inputName.sync='inputName'></child>
    </div>
</template>

<script>
import child from '@/page/child';
export default {
    components: {
        child
    },
    data() {
        return {
            inputName:''
        };
    }
};
</script>

子组件


<template>
    <div>
        子组件:<span>{{inputName}}</span>
        <div>
            <input type="button" value="给父组件传值" @click="childClick"/>
        </div>
    </div>
</template>

<script>
export default {
    // 接收父组件的值,props里面值不能改变
    props: { // 对象写法
        inputName: {
            type: String,
            require: true
        }
    },
    data() {
        return {
            childValue: '我是子组件的数据'
        };
    },
    methods: {
        childClick() {
            this.$emit('update:inputName',this.childValue);
        }
    }
};
</script>

组件传值之父传子、子传父、非父子传值_第3张图片

非父子组件传值

event bus

你可能感兴趣的:(前端)