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

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

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Documenttitle>
  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>

效果图如下:
12-Vue的组件化开发(二)_第1张图片


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

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Documenttitle>
  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)
  }
}

效果图如下:
12-Vue的组件化开发(二)_第2张图片


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

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

  <body>
    <div id="app">
      <cpn>cpn>
      <cpn ref="test">cpn>
      <button @click="btnClick1">按钮1button>
      <button @click="btnClick2">按钮2button>
    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">按钮1button>
  <button @click="btnClick2">按钮2button>
div>
methods: {
  btnClick1() {
    console.log(this.$children)
    console.log(this.$children[1].name)
  }
}

效果图如下:
12-Vue的组件化开发(二)_第3张图片

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

效果图如下:
12-Vue的组件化开发(二)_第4张图片


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

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

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

    <template id="cpn">
      <div>
        
        <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.上文代码逻分析

12-Vue的组件化开发(二)_第5张图片
你猜的没错,又是套娃,准确的说是父组件也有自己的父组件。那子组件使用$ p a r e n t parent parent访问自己的父组件,使用$root访问自己的根组件(太太太太…太爷爷)。效果图如下:
12-Vue的组件化开发(二)_第6张图片


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

你可能感兴趣的:(Vue学习)