vue2中组件间通讯

发布于:2022-08-09 ⋅ 阅读:(360) ⋅ 点赞:(0)

目录

1. 使用属性,父组件向子组件传递数据props

1.1 道具属性使用

1.3父传子通讯案例

2 子传父    $emit

2.1.在子组件中定义一个方法,使用,'itemclick'是事件名,item是传过去的值。(实现子传父核心代码)btnClick(item)$emititem

2.2在子组件中监听点击事件并回调此方法

2.3.在父组件中定义一个方法cpnClcik(item)

2.4.并在父组件(vue实例)中调用(不写参数默认传递btnClick的item ),父组件监听事件名为的子组件传过来的事件。itemclick

 2.5代码实现效果​编辑

 3. 父访问子(儿童参考)ref属性

3.1$refs方式:


1. 使用属性,父组件向子组件传递数据props

首先在父组件中引入子组件,然后以属性的方式将数据传递给子组件

父组件:

<template>
	<div class="home">
        <!-- 在子组件中使用 :变量名=value  的方式向子组件传递数据,子组件通过 props 接收-->
        <HelloWorld :msg="fatchData" ref="childEl"/>       
    </div>
</template>

<script>
    // @ is an alias to /src
    import HelloWorld from '@/components/HelloWorld.vue'

    export default {
        name: 'Home',
        components: {
            HelloWorld
        },
        data () {
            return {
                fatchData: '我是父组件通过props传递给子组件的文字'
            }
        }        
    }
</script>

然后在子组件中使用props接收,props里定义的名字要和父组件定义的一致

子组件:

<template>
	<div>
        <span>{{ msg }}</span>
    </div>
</template>

<script>
    export default {
        name: 'HelloWorld',
        // 子组件通过使用 props 接收父组件传递过来的数据
        props: {
            msg: String
        }
  }
</script>

1.1 道具属性使用

数组写法

props: ['cmovies', 'cmessage']
对象写法

  props: { 
          cmessage: {
          type: String,
          default: 'zzzzz',
          required: true //在使用组件必传值
          }
  }
props属性的类型限制

//1.类型限制(多个类使用数组)
cmovies:Array,//限制为数组类型
cmessage:String,//限制为Strin类型
cmessage:['String','Number']//限制为String或Number类型
props属性的默认值

// 2.提供一些默认值,以及必传值
        cmessage: {
          type: String,
          default: 'zzzzz',//默认值
        }
props属性的必传值

cmessage: {
          type: String,
          default: 'zzzzz',
          required: true //在使用组件必传值
        }
类型是Object/Array,默认值必须是一个函数

//类型是Object/Array,默认值必须是一个函数
cmovies: {
	type: Array,
	default () {
		return [1, 2, 3, 4]
	}
},
自定义验证函数

vaildator: function (value) {
	//这个传递的值必须匹配下列字符串中的一个
	return ['zzzzz', 'ttttt', 'yyy'].indexOf(value) !== -1
}
自定义类型

    function Person(firstName,lastName) {
      this.firstName = firstName
      this.lastName = lastName
    }
	cmessage:Person//限定了cmeessage必须是Person类型

1.3父传子通讯案例

  <div id="app">
    <!-- v-bind不支持驼峰 :cUser改成 :c-User-->
    <!-- <cpn :cUser="user"></cpn> -->
    <cpn :c-User="user"></cpn>
    <cpn :cuser="user" ></cpn>
  </div>
  <template id="cpn">
    <div>
      <!-- 使用驼峰 -->
      <h2>{{cUser}}</h2>
      <!-- 不使用 -->
      <h2>{{cuser}}</h2>
    </div>
  </template>
  <script src="../js/vue.js"></script>
  <script>
    // 父传子:props
    const cpn = {
      template: "#cpn",
      props: { //对象写法
        //驼峰
        cUser:Object,
        //未使用驼峰
        cuser:Object
      },
      data() {return {}},
      methods: {},
    };
    const app = new Vue({
      el: "#app",
      data: {
        user:{
          name:'zzz',
          age:18,
          height:175
        }
      },
      components: {
        cpn
      }
    })
  </script>

2 子传父    $emit

  <!-- 父组件 -->
  <div id="app">
    <!-- 不写参数默认传递btnClick的item -->
    <cpn @itemclick="cpnClcik"></cpn>

  </div>

  <!-- 子组件 -->
  <template id="cpn">

    <div>
      <button v-for="(item, index) in categoties" :key="index" @click="btnClick(item)">{{item.name}}</button>
    </div>
  </template>

  <script src="../js/vue.js"></script>

  <script>
    const cpn = {
      template: "#cpn",
      data() {
        return {
          categoties: [{
              id: 'aaa',
              name: '热门推荐'
            },
            {
              id: 'bbb',
              name: '手机数码'
            },
            {
              id: 'ccc',
              name: '家用家电'
            },
            {
              id: 'ddd',
              name: '电脑办公'
            },
          ]
        }
      },
      methods: {
        btnClick(item) {
          this.$emit('itemclick', item)
        }
      },
    };
    const app = new Vue({
      el: "#app",
      data() {
        return {

        }
      },
      methods: {
        cpnClcik(item) {
          console.log('cpnClick'+item.name);
        }
      },
      components: {
        cpn
      },
    })
  </script>

2.1.在子组件中定义一个方法,使用,'itemclick'是事件名,item是传过去的值。(实现子传父核心代码)btnClick(item)$emititem

      methods: {
        btnClick(item) {
          this.$emit('itemclick', item)
        }
      },

2.2在子组件中监听点击事件并回调此方法

<div>
      <button v-for="(item, index) in categoties" :key="index" @click="btnClick(item)">{{item.name}}</button>
    </div>

2.3.在父组件中定义一个方法cpnClcik(item)

methods: {
	cpnClcik(item) {
		console.log('cpnClick'+item.name);
	}
},

2.4.并在父组件(vue实例)中调用(不写参数默认传递btnClick的item ),父组件监听事件名为的子组件传过来的事件。<cpn @itemclick="cpnClcik"></cpn>itemclick

<cpn @itemclick="cpnClcik"></cpn>

 2.5代码实现效果

 3. 父访问子(儿童参考)ref属性

3.1$refs方式:

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。

注意的是:

1.如果单纯操作Dom,原生js也可以实现 let a = document.querySelector("#bb");

2、ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。

3、如果ref 是循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了

<template>
  <div id="app">
    <h2 ref="aa" id="bb">我们在学习vue</h2>
    <button @click="getdom">点击</button>
    <!-- <my-cpn ref="hello" ></my-cpn> -->
    <my-cpn ref="num1" @changenumber='changeclick'></my-cpn>
    <my-cpn ref="num2" @changenumber='changeclick'></my-cpn>
    <h3>总和:{{total}}</h3>
    
    <!-- <button @click="getHello">获取helloworld组件中的值</button> -->
  </div>

</template>

<script>
import MyCpn from "./components/MyCpn.vue";
//ref基本操作,实际上就是把操作dom元素 ,或者子组件实例

export default {
  name: "App",
  data() {
    return {
      total:0
    }
  },
  components: {
    MyCpn,
  },
  methods: {
    getdom() {
      let a = document.querySelector("#bb");
      //传统原生操作dom
      console.log(a);
      console.log(this.$refs);
    },
    // getHello(){
    //   // this.$refs.hello.number++
    //   // ref 父访问子组件,操作子组件数据
    //   console.log(this.$refs.hello.$el.innerHTML);//<h2>我是子组件</h2>
    //   console.log(this.$refs.hello);
    //   console.log(this.$refs.hello.number);
    //   //ref属性操作子组件,指向组件实例vueComponent
    // },
    changeclick(){
this.total=this.$refs.num1.number+this.$refs.num2.number
    }
  },
};
</script>

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到