Vue.js知识——父子组件的通信、父子组件的访问方式

x33g5p2x  于2021-11-21 转载在 Vue.js  
字(4.8k)|赞(0)|评价(0)|浏览(395)

父子组件的通信

在开发中,往往一些数据确实需要从上层传递到下层:

比如在一个页面中,我们从服务器请求到了很多的数据,其中一部分数据,并非是整个页面的大组件来展示,而是需要下面的子组件进行展示。这个个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件将数据传递给小组件。

如何进行父子组件间的通信?

通过props向子组件传递数据(properties)

const cpn2 = Vue.extend({
      template: ` <div> <h1>{{cmovies}}</h1> <h3>哈哈哈<h3> </div> `,
      props:['cmovies'],
    });
    const app = new Vue({
      el: "#app",
      components: {
        cpn2,
      },
      data:{
        movies:["美国队长1","美国队长2","美国队长3"]
      }
    })

props不仅仅可以是传入数组,也可以传入对象

props:{
        //1、类型限制
        cmoives:Array,
        //2、提供一些默认值
        cmoives:{
          type:Array,
          default(){
            return []
          },//默认值,如果默认值是个数组,就必须写成函数形式
          required:true,//如果为true,就是必须传入
        }
      }

props驼峰标识

在命名子组件的props属性时,往往会采取驼峰体,但是在html中是无法有效识别驼峰体代码。
例如:

<body>
  <div id="app">
    <cpn2 :cMovies="movies"></cpn2><!--这里无法识别驼峰体代码-->
  </div>

  <script> const cpn2 = Vue.extend({ template: ` <div> <h1>{{cMovies}}</h1> <h3>哈哈哈</h3> </div> `, props:{ cMovies:{ //命名为驼峰体 type:Array, default(){ return [] }, required:true, } } }); const app = new Vue({ el: "#app", components: { cpn2, }, data:{ movies:["美国队长1","美国队长2","美国队长3"] } }) </script>
 </body>

此时,数组中什么也没有传过来,所以显示了默认值。需要将html代码中的cMovies改成c-movies,才能显示。
<cpn2 :c-movies="movies"></cpn2>

子组件通过自定义事件向父组件发送消息

什么时候需要自定义事件呢?
当子组件需要向父组件传递数据时,就要用到自定义事件了,之前学习的v-on不仅仅用于监听DOM事件,也可以用于组件间的自定义事件。

<body>
  <div id="app">
    <cpn2 @itemclick="cpnclick"></cpn2>
  </div>

  <script> const cpn2 = Vue.extend({ template: ` <div> <button v-for="item in categories" @click="btnclick(item)">{{item.name}}</button> </div> `, data(){ return{ categories:[ {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", components: { cpn2, }, methods:{ cpnclick(item){ console.log(item); } } }) </script>
</body>

通信案例

<body>
 <div id="app">
  <cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change"></cpn>
 </div>
 
 <template id="cpn">
  <div>
    <h2>props:{{number1}}</h2>
    <h2>data:{{dnumber1}}</h2>
    <input type="text" :value="dnumber1" @input="num1Input">
    <h2>props:{{number2}}</h2>
    <h2>data:{{dnumber2}}</h2>
    <input type="text" :value="dnumber2" @input="num2Input">
  </div>
 
</template>
 <script> const app= new Vue({ el:"#app", data:{ num1:1, num2:0 }, methods:{ num1change(value){ this.num1 = parseFloat(value); }, num2change(value){ this.num2 = parseFloat(value); } }, components:{ cpn:{ template:"#cpn", props:{ number1:Number, number2:Number, }, data(){ return { dnumber1:this.number1, dnumber2:this.number2, } }, methods:{ num1Input(event){ this.dnumber1 = event.target.value; this.$emit("num1change",this.dnumber1); this.dnumber2 = this.dnumber1*100; this.$emit("num2change",this.dnumber2); }, num2Input(event){ this.dnumber2 = event.target.value; this.$emit("num2change",this.dnumber2); this.dnumber1 = this.dnumber2 / 100; this.$emit("num1change",this.dnumber1); }, } } } }) </script>
</body>

父子组件的访问方式

有时候需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。

父组件访问子组件:使用$children或 $refs 引用

子组件访问父组件:使用$parent

$children

通过对button进行绑定事件,然后直接获取子组件中的属性。
但是要注意使用$children获取的是一个数组。

<body>
  <div id="app">
    <cpn></cpn>
    <button @click="btnclick">按钮</button>
  </div>

  <template id="cpn">
    <div>
      <h2>我是内容</h2>
    </div>
  </template>

  <script> const app=new Vue({ el:"#app", methods:{ btnclick(){ console.log(this.$children[0].name); this.$children[0].name = "李四"; console.log(this.$children[0].name); } }, components:{ cpn:{ template:"#cpn", data(){ return {name:"张三"} } } } }) </script>
</body>

如果有多个数组就需要通过索引值来确定获取的需要修改的子组件,这样就造成了一个问题,如果子组件的位置变化,例如中间插入了新的子组件,就要修改索引值,非常麻烦。

这就用到了第二个方法

$refs

通过对子组件进行refs赋值,就可以确定需要获取的子组件。

注意的是不是refs,而是ref
<cpn ref="cpn1"></cpn>

console.log(this.$refs.cpn1.name);

$parent

子组件可以访问父组件,但是不建议使用,因为复用性不高,如果该子组件运用在其他父组件中,如果该父组件没有该属性就会报错。

<body>
  <div id="app">
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>我是内容</h2>
      <button @click="btnclick">按钮</button>
    </div>
  </template>

  <script> const app = new Vue({ el: "#app", data:{ age:18, }, components: { cpn: { template: "#cpn", data() { return { name: "张三" } }, methods: { btnclick() { console.log(this.$parent); } }, } } }) </script>
</body>

$ root

可以直接访问到Vue实例中的属性。
用法与上述相似。

相关文章