12-Vue的组件化开发(二)


组件通信-父组件向子组件传递数据

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <div id="app">
      <cpn v-bind:cmessage="message" v-bind:cmovies="movies"></cpn>
    </div>

    <template id="cpn">
      <div>
        <h2>这是一个cpn标题</h2>
        <ul>
          <li v-for="item in cmovies">{
   
   {item}}</li>
        </ul>
        <p>{
   
   {cmessage}}</p>
      </div>
    </template>

    <script src="../js/vue.js"></script>
    <script>
      const cpn = {
     
     
        template: "#cpn",
        // 对象形式
        props: {
     
     
          cmessage: {
     
     
            type: String,
            // 默认值
            default: "aaaa",
            // 必须传值
            required: true
          },
          // 类型是对象或者数组时,默认值必须是一个函数
          cmovies: {
     
     
            type: Array,
            default() {
     
     
              return []
            }
          }
        }
      }
      const app = new Vue({
     
     
        el: "#app",
        data: {
     
     
          message: "你好",
          movies: ["海王", "火影忍者", "进击的巨人", "星际穿越"]
        },
        components: {
     
     
          cpn
        }
      })
    </script>
  </body>
</html>
1.父组件如何向子组件传递信息
  • 在子组件的props中定义cmessage和cmovies,并标出基数据类型。代码如下:
// 无属性要求
props:{
    
    
	// 1.类型限制
	cmovies: Array,
	cmessage: String
	// 2.多种类型
	cname: [String, Array] 
	// 3.类型种类
	// String, Number, Boolean, Array, Object, Data, Function, Symbol
	// 4.自定义种类
	function Person(firstName, lsatName) {
    
    
	}
	author: Person
}
// 有属性要求
props: {
    
    
	cmessage: {
    
    
	    // 变量类型
    	type: String,
    	// 变量默认值
    	default: "aaaa",
    	// 父组件是否必须传值
        required: true
    },
    // 类型是对象或者数组时,默认值必须是一个函数
    cmovies: {
    
    
    	type: Array,
    	default() {
    
    
    		return []
    	}
    }
}
  • 父组件在调用子组件时将本组件的信息传入,父组件中使用v-bind将子组件中的变量名绑定,绑定的信息为父组件中想要传递的信息变量。代码如下:
<cpn v-bind:cmessage="message" v-bind:cmovies="movies"></cpn>
  • 此时即可在子组件中使用在props中定义的变量,子组件中cmessage的值等于父组件中message的值,同理子组件中cmovies的值等于父组件中movies的值。子组件模版代码如下:
<template id="cpn">
  <div>
    <h2>这是一个cpn标题</h2>
    <ul>
      <li v-for="item in cmovies">{
   
   {item}}</li>
    </ul>
    <p>{
   
   {cmessage}}</p>
  </div>
</template>

效果图如下:
在这里插入图片描述


组件通信-子组件向父组件传递数据

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <!-- 父组件模版 -->
    <div id="app">
      <cpn @item-click="cpnClick"></cpn>
    </div>

    <!-- 子组件模版 -->
    <template id="cpn">
      <div>
        <button
          v-for="item in categories"
          :key="item.id"
          @click="btnClick(item)"
        >
          {
   
   {item.name}}
        </button>
      </div>
    </template>

    <script src="../js/vue.js"></script>
    <script>
      // 1.子组件
      const cpn = {
     
     
        template: "#cpn",
        data() {
     
     
          return {
     
     
            categories: [
              {
     
      id: "aaa", name: "热门推荐" },
              {
     
      id: "bbb", name: "手机数码" },
              {
     
      id: "ccc", name: "家用家电" },
              {
     
      id: "ddd", name: "电脑办公" }
            ]
          }
        },
        methods: {
     
     
          btnClick(item) {
     
     
            // 子组件将得到的数据传递给父组件
            // 发射一个事件
            this.$emit("item-click", item)
          }
        }
      }

      // 2.父组件
      const app = new Vue({
     
     
        el: "#app",
        data: {
     
     
          message: "你好"
        },
        components: {
     
     
          cpn
        },
        methods: {
     
     
          cpnClick(item) {
     
     
            console.log("cpnClick", item.id, item.name)
          }
        }
      })
    </script>
  </body>
</html>
1.子组件如何向父组件传递信息
  • 在子组件的data变量中定义想要传递给父组件的内容。代码如下:
const cpn = {
    
    
  template: "#cpn",
  data() {
    
    
    return {
    
    
      categories: [
        {
    
     id: "aaa", name: "热门推荐" },
        {
    
     id: "bbb", name: "手机数码" },
        {
    
     id: "ccc", name: "家用家电" },
        {
    
     id: "ddd", name: "电脑办公" }
      ]
    }
  }
}
  • 子组件绑定点击事件,向父组件发射数据。代码如下:
<template id="cpn">
  <div>
    <button
      v-for="item in categories"
      :key="item.id"
      @click="btnClick(item)"
    >
      {
   
   {item.name}}
    </button>
  </div>
</template>
methods: {
    
    
  btnClick(item) {
    
    
    // 子组件发射一个事件将得到的数据传递给父组件
    this.$emit("item-click", item)
  }
}
  • 父组件在调用子组件时在本地新建一个事件接收数据传递,v-bind绑定发射的事件名,注意此时父组件的在调用本组件函数时不用传递参数。代码如下:
<cpn @item-click="cpnClick"></cpn>
methods: {
    
    
  cpnClick(item) {
    
    
    console.log("cpnClick", item.id, item.name)
  }
}

效果图如下:
在这里插入图片描述


组件访问-父访问子(children/refs)

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <div id="app">
      <cpn></cpn>
      <cpn ref="test"></cpn>
      <button @click="btnClick1">按钮1</button>
      <button @click="btnClick2">按钮2</button>
    </div>

    <template id="cpn">
      <div>
        我是子组件
      </div>
    </template>

    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
     
     
        el: "#app",
        data: {
     
     
          message: "你好"
        },
        methods: {
     
     
          btnClick1() {
     
     
            // 1.$children
            console.log(this.$children)
            console.log(this.$children[1].name)
          },
          btnClick2() {
     
     
            // 2.$refs => 对象类型,默认是一个空的对象 ref='test'
            // 可以获得指定的子组件,一般都是用这种
            console.log(this.$refs.test.name)
          }
        },
        components: {
     
     
          cpn: {
     
     
            template: "#cpn",
            data() {
     
     
              return {
     
     
                name: "我是子组件的name"
              }
            }
          }
        }
      })
    </script>
  </body>
</html>
1.$children的使用场景

有时同一个子组件,在父组件中可能会用到多次,那么在父组件中想使用子组件中的data变量,即可使用$ c h i l d r e n children children直接获得。如上文代码中,父组件多次使用子组件,则在父组件中打印children可以遍历所有的子组件。代码如下:

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <button @click="btnClick1">按钮1</button>
  <button @click="btnClick2">按钮2</button>
</div>
methods: {
    
    
  btnClick1() {
    
    
    console.log(this.$children)
    console.log(this.$children[1].name)
  }
}

效果图如下:
在这里插入图片描述

2.$refs的使用场景

看了$ c h i l d r e n children children之后,我想大家都意识到一个问题,就是父组件中需要确定子组件的下标,这在开发中肯定是不方便的,而$refs能帮我们找到指定的子组件,只需在调用子组件时添加一个标记即可。代码如下:

<div id="app">
  <cpn></cpn>
  <cpn ref="test"></cpn>
  <button @click="btnClick1">按钮1</button>
  <button @click="btnClick2">按钮2</button>
</div>
methods: {
    
    
  btnClick2() {
    
    
    // 可以获得指定的子组件,一般都是用这种
    console.log(this.$refs.test.name)
  }
}

效果图如下:
在这里插入图片描述


组件访问-子访问父(parent/root)

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

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

    <template id="cpn">
      <div>
        <!-- 我是子组件
      <button @click="btnClick">按钮</button> -->
        <h2>我是cpn组件</h2>
        <ccpn></ccpn>
      </div>
    </template>

    <template id="ccpn">
      <div>
        我是子组件
        <button @click="btnClick">按钮</button>
      </div>
    </template>

    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
     
     
        el: "#app",
        data: {
     
     
          message: "你好"
        },
        components: {
     
     
          cpn: {
     
     
            template: "#cpn",
            data() {
     
     
              return {
     
     
                name: "这是cpn组件的name"
              }
            },
            components: {
     
     
              ccpn: {
     
     
                template: "#ccpn",
                methods: {
     
     
                  btnClick() {
     
     
                    // 1.访问父组件$parent
                    console.log(this.$parent);
                    console.log(this.$parent.name);

                    // 2.访问根组件$root
                    console.log(this.$root)
                    console.log(this.$root.message)
                  }
                }
              }
            }
          }
        }
      })
    </script>
  </body>
</html>
1.上文代码逻分析

在这里插入图片描述
你猜的没错,又是套娃,准确的说是父组件也有自己的父组件。那子组件使用$ p a r e n t parent parent访问自己的父组件,使用$root访问自己的根组件(太太太太…太爷爷)。效果图如下:
在这里插入图片描述


第一次记录自己的学习笔记,如果您发现问题,欢迎指点。

猜你喜欢

转载自blog.csdn.net/qq_42647711/article/details/104643046