vue组件传值的十种方式

一、props

父传子

  • 子组件
// 第一种数组方式
props: [xxx, xxx, xxx]
// 第二种对象方式
props: { xxx: Number, xxx: String}
// 第三种对象嵌套对象方式
//第三种对象默认支持 4 种属性,并且都是非必填的。可以随意使用
props: {
    xxx: {
        //类型不匹配会警告
        type: Number,
        default: 0,
        required: true,
        // 返回值不是 true,会警告
        validator(val) { return val === 10}
    }
}
  • 父组件
// 第一种静态属性传参
// 注意:
	// 1.在不定义 props 类型的情况下 props 接受到的均为 String。
	// 2.当 props 属性指定为 Boolean 时,并且只有属性 key 没有值 value 时接受到的是 true
	
<!--props 接受到的均为 String -->
<children xxx="123"></children>

<!-- 有只有属性没有值, 这种情况 props 指定类型是 Boolean 则接收到的是 true -->
<children xxx></children>
// 第二种动态属性传参

// 注意:
	// 1.需要区分非简写形式传入的值是对象,则会对应 props 中多个值
	// 2.会保留传入值的类型
	// 3.如果是表达式则获取到的是表达式的计算结果
<!-- prop 接收到 Number 类型的 123-->
<children :xxx="123"></children>

<!-- prop 接收到 Array 类型的 [1, 2, 3]-->
<children v-bind:xxx="[1, 2, 3]"></children>

<!-- prop 会接收到 xxx1 和 xxx2 俩个参数。这种不支持简写形式-->
<children v-bind="{xxx1: 1, xxx2: 2}"></children>

二、$emit-- $on

子传父

  • 子组件
<template>
  <div>
    子组件:
    <span>{{childValue}}</span>
    <!-- 定义一个子组件传值的方法 -->
    <input type="button" value="点击触发" @click="childClick">
  </div>
</template>
<script>
  export default {
    data () {
      return {
        evidence: '我是子组件的数据'
      }
    },
    methods: {
      childClick () {
        // childByValue是在父组件on监听的方法
        // 第二个参数this.childValue是需要传的值
        this.$emit("materials", this.evidence); //触发 input 事件,并传入新值
      }
    }
  }
</script>
  • 父组件
<template>
  <div>
    父组件:
    <span>{{name}}</span>
    <br>
    <br>
    <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
    <child  
    	:third="third"
        @materials="getMaterials">
   </child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    },
    methods: {
      getMaterials(evidence) {
        // childValue就是子组件传过来的值
        this.name = evidence
      }
    }
  }
</script>

三、公共仓库bus.js

非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果

  • 公共bus.js
//bus.js
import Vue from 'vue'
export default new Vue()
  • 组件A(传值的页面)
<template>
  <div>
    A组件:
    <span>{{elementValue}}</span>
    <input type="button" value="点击触发" @click="elementByValue">
  </div>
</template>
<script>
  // 引入公共的bug,来做为中间传达的工具
  import Bus from './bus.js'
  export default {
    data () {
      return {
        elementValue: 4
      }
    },
    methods: {
      elementByValue () {
        Bus.$emit('val', this.elementValue)
      }
    }
  }
</script>
  • 组件B (接收值的页面)
<template>
  <div>
    B组件:
    <input type="button" value="点击触发" @click="getData">
    <span>{{name}}</span>
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        name: 0
      }
    },
    mounted () {
      // 用$on事件来接收参数
      Bus.$on('val', elementValue => {
        console.log(elementValue)
        vm.name = elementValue
      })
    },
    methods: {
      getData () {
        this.name++
      }
    }
  }
</script>

四、vuex

五、v-model

  • 父组件
// 引入子组件
// 写法 1
<plaintiff    v-model="activeName_copy"></plaintiff >

// 写法 2
<plaintiff  :activeName_copy="activeName_copy" @update:activeName_copy="activeName_copy= $event"></plaintiff>

// 写法 3 
// 1. 事件名必须是 update: + 属性名
// 2. 参数不能是表达式,最好是 data 里面的属性
<plaintiff    :activeName_copy.sync="activeName_copy"></plaintiff>

data(){
	return{
		activeName_copy: "first",
	}
}
  • 子组件
props: ['activeName_copy],
data(){
	return{
		activeName: this.activeName_copy,
	}
}
methods:{
	aa(){
			this.activeName = 'fifth'
	        this.$emit('update:activeName_copy', this.activeName) //触发 input 事件,并传入新值
	}
}

六、project / inject

<!--父组件 提供-->
{
    project() {
        return {
            parent: this.test
        }
    },
    data(){
      return{
          test:true
      }
  }
}
<!--子组件 注入-->
{
    // 写法一
    inject: ['parent']
    // 写法二
    inject: { parent: 'parent' }
    // 写法三
    inject: {
        parent: {
            from: 'parent',
            default: 222
        }
    }
}

七、$refs和ref

八、$root

九、 $parent 和 $children (但是在实际中 $parent用的非常少——考虑到耦合度的原因)

$root 获取根组件
$parent 获取父组件—父传子
$children 获取子组件(所有的子组件,不保证顺序)-----子传父
$refs 组件获取组件实例,元素获取元素

十、插槽

十一、$attrs 和 $listeners