草庐IT

Vue组件通信——父子组件通信的四种方法

黑猫_默雨 2023-04-15 原文

引入组件

  1. 全局引入

    在main.js文件中引入并注册

    import ChildrenDemo from '@/views/components/ChildrenDemo'
    Vue.component('ChildrenDemo',ChildrenDemo)// 第一个参数 全局组件的名字(字符串类型),第二个参数:引入的组件名(一般都与组件名保持一致)
    

    之后就可以全局使用组件了

  2. 局部引入

    在父组件中引入

    import ChildrenDemo from '@/views/components/ChildrenDemo'
    export default {
      components: {
        ChildrenDemo
      },
    }
    

    之后就可以在父组件中使用组件了

    <ChildrenDemo></ChildrenDemo>
    <!-- 或 -->
    <children-demo></children-demo>
    

一、props属性绑定(父组件向子组件传递数据)

在子组件 prop 中可以注册一些自定义组件属性,父组件调用子组件时可以向 prop 中的自定义属性传值。

子组件代码:

<template>
  <div class="ChildrenDemo">
    <h1>{{title}}</h1>
  </div>
</template>

<script>
export default {
  name: 'ChildrenDemo',
  props:['title'],
  components: {
  },
  data () {
    return {
    }
  }
}
</script>

父组件代码

<template>
  <div class="parent">
    <ChildrenDemo title="向子组件传递的title值"></ChildrenDemo>
  </div>
</template>

prop 也可以通过 v-bind 动态赋值

<ChildrenDemo :title="xxx"></ChildrenDemo>

如果要将一个对象的所有 property 都作为 prop 传入,你可以使用不带参数的 v-bind

例如,对于一个给定的对象 post

post: {
  id: 1,
  title: 'My Journey with Vue'
}

传给子组件

<blog-post v-bind="post"></blog-post>

等价于:

<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

props的更多写法

  1. 字符串数组形式

    props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
    
  2. 指定prop值类型

    props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise // or any other constructor
    }
    
  3. 指定 prop 的验证要求

    当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

      props: {
        // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
        propA: Number,
        // 多个可能的类型
        propB: [String, Number],
        // 必填的字符串
        propC: {
          type: String,
          required: true
        },
        // 带有默认值的数字
        propD: {
          type: Number,
          default: 100
        },
        // 带有默认值的对象
        propE: {
          type: Object,
          // 对象或数组默认值必须从一个工厂函数获取
          default: function () {
            return { message: 'hello' }
          }
        },
        // 自定义验证函数
        propF: {
          validator: function (value) {
            // 这个值必须匹配下列字符串中的一个
            return ['success', 'warning', 'danger'].indexOf(value) !== -1
          }
        }
      },
    

    注意: prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 datacomputed 等) 在 defaultvalidator 函数中是不可用的。

prop双向绑定

一般情况下,子组件不能直接修改从父组件接收的属性值,否则会报错,如果子组件需要接收值后处理再使用,可以将接收的值赋值给子组件本身的属性,如data中的属性或计算属性。

如果希望子组件prop父组件中的值改变时,将变化同步到父组件中,可使用事件监听或**.sync修饰符**

.sync修饰符

.sync修饰符是一个语法糖,本质上等同于事件监听的方法

参考:vue的.sync修饰符用法及原理详解_weixin_58206976的博客-CSDN博客_vuesync修饰符

父组件

<h1>父组件title值:{{ title }}</h1>
<ChildrenDemo :title.sync="title"></ChildrenDemo>

子组件

<template>
  <div class="ChildrenDemo">
    <h1>子组件</h1>
    <input type="text" v-model="childTitle" />
  </div>
</template>

<script>
export default {
  props: ["title"],
  data() {
    return {};
  },
  computed: {
    childTitle: {
      get() {
        return this.title;
      },
      set(val) {
        this.$emit("update:title", val);//更新父组件中的title
      },
    },
  }
};
</script>

效果:当子组件中input内容改变时,父组件中的title会同步改变

二、监听子组件事件(子组件向父组件传递数据,子组件触发父组件方法)

通过 vue 实例方法 vm.$emit子组件可以自定义一个事件提交给父组件,触发父组件的方法,父组件通过监听子组件的自定义事件可以接收子组件传递的数据。

子组件

<template>
  <div class="ChildrenDemo">
    <h1>子组件</h1>
    <button @click="changeParentTitle">点击更改父组件title</button>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {};
  },
  methods: {
    changeParentTitle() {
      this.$emit("childEvent", "子组件传给父组件的title")//第一个参数是提交的事件名,后面的参数可以是多个需要传递给父组件的参数
    }
  }
};
</script>

父组件

<template>
  <div class="home">
    <h1>父组件title值:{{ title }}</h1>
    <ChildrenDemo :title="title" @childEvent="changeTitle"></ChildrenDemo>
  </div>
</template>

<script>
import ChildrenDemo from "@/views/components/ChildrenDemo";
export default {
  components: {
    ChildrenDemo,
  },
  data() {
    return {
      title: "My Journey with Vue"
    };
  },
  methods: {
    changeTitle: function (str) {
      this.title = str
    },
  },
};
</script>

上例中的操作和传递的值都比较简单,也可以在事件处理函数中直接使用表达式,父组件通过 $event 访问被子组件抛出的值

子组件:

<button @click="$emit('childEvent', '子组件传给父组件的title')">点击更改父组件title</button>

父组件:

<ChildrenDemo :title="title" @childEvent="title = $event"></ChildrenDemo>

三、使用 $refs (父组件访问子组件的数据和方法)

父组件使用 $refs 可以访问子组件的数据和方法

使用时需在调用子组件时给子组件定义一个 ref 名

<ChildrenDemo ref="childrenDemo"></ChildrenDemo>
<button @click="getChildData">点击获取子组件数据</button>
getChildData: function () {
  let child = this.$refs.childrenDemo//获取子组件实例
  console.log(child.value);//访问子组件属性
  child.childFn() //调用子组件的childFn()方法
},

注意:

  1. $refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs
  2. 由于ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。

四、使用$parent(子组件访问父组件的数据和方法)

$parent property 可以用来从一个子组件访问父组件的实例

子组件:

<button @click="getParentData">点击获取父组件数据</button>
getParentData(){
  let parent = this.$parent //获取父组件实例
  console.log(parent.parentValue) //访问父组件属性
  parent.parentFn() //调用父组件的方法parentFn()
}

有关Vue组件通信——父子组件通信的四种方法的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  8. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

随机推荐