vue组件父子间传值

一、prop(官方)

通过Prop向子组件传递数据: 我们可以在组件上注册一些自定义的属性, 值传给这个属性的时候,该属性就变成该组件实例的一个property,我们在组件实例中用props选项将这些属性包含在其中,然后我们就能在组件实例中访问这个值,就像访问data中的值一样。一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

Vue.component('blog-post', {
    
    
  props: ['title'],
  template: '<h3>{
    
    { title }}</h3>'
})
<blog-post title="My journey with Vue"></blog-post>

prop的写法:

字符串形式:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

对象形式:
希望每个 prop 都有指定的值类型时,可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型:

props: {
    
    
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

Prop在html与javascript的写法:

html中的属性名大小写不敏感,所以浏览器会把所有大写字符解释成小写字符,
所以在使用DOM的模板时,驼峰命名法的prop需要使用等价的短横线分隔命名。
Vue.component('blog-post', {
    
    
  // 在 JavaScript 中是 驼峰式命名 的
  props: ['postTitle'],
  template: '<h3>{
    
    { postTitle }}</h3>'
})
<!--HTML 中是 短横线分隔的 -->
<blog-post post-title="hello!"></blog-post>

传递静态或动态prop

(1)传递静态值:

<blog-post title="My journey with Vue"></blog-post>

(2)传递动态值(通过v-bind动态绑定):

<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post>

<!-- 动态赋予一个复杂表达式的值 -->
<blog-post
  v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>

任何类型的值都可以传给prop:

数字:

<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<blog-post v-bind:likes="42"></blog-post>
<!-- 用一个变量进行动态赋值。-->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="post.likes"></blog-post>

布尔值:

<!-- 包含该 prop 没有值的情况在内,都意味着 `true`-->
<blog-post is-published></blog-post>

<!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post>

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>

数组:

<!-- 即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:comment-ids="post.commentIds"></blog-post>

对象:

<!-- 即便对象是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post
  v-bind:author="{
    
    
    name: 'Veronica',
    company: 'Veridian Dynamics'
  }"
></blog-post>

<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:author="post.author"></blog-post>

传入一个对象的所有property:

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>

二、父向子传值:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <blog-li v-for='item in blogs' v-bind:item='item'></blog-li>
  </div>
  <script>
    Vue.component('blog-li',{
     
     
      props:['item'],
      //每个组件必须只有一个根元素
      template:`
        <div class='blog-li'>
          <h3>{
      
      {item.title}}</h3>
          <h2>{
      
      {item.id}}</h2>
        </div>
      `
    })
    const app = new Vue({
     
     
      el: '#app',
      data: {
     
     
        blogs: [{
     
     
            id: 1,
            title: '第一篇博文'
          },
          {
     
     
            id: 2,
            title: '第二篇博文'
          },
          {
     
     
            id: 3,
            title: '第三篇博文'
          }
        ]
      }
    })
  </script>
</body>
</html>

运行效果:
在这里插入图片描述
在这里插入图片描述

子组件像父组件传值:(监听子组件事件)

子组件向父组件发射信号,父组件接收信号做出操作。

子组件去改变父组件的值(子组件向父组件传值,父组件再使用该值进行处理,再通过Prop作用于子组件);

子组件与父组件之间需要进行沟通,官方案例:子组件中添加一个按钮点击改变博文的字体大小。
思路:父组件添加一个blogFontSize数据,使用在子组件模板中控制子组件博文字体大小。每个模板需求里面有一个按钮可以控制博文大小。

Vue提供一个自定义事件系统,父级组件就可以通过v-on监听子组件实例的任意事件。 同时子组件可以通过调用内建的 $emit 方法并传入事件名称来触发事件

子组件:v-on:click="$emit('enlarge-text')"
			emit中文发射的意思,可以将其理解成子组件向父组件发射信号
			
父组件:v-on:enlarge-text="blogFontSize += 0.1"  监听器,父级组件就能接收并更新blogFontSize得值。
		   理解为 父元素接收信号
<!DOCTY<!DOCTYPE html>
  <html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>

  <body>
    <div id="app">
      <!-- v-on:enlarge-text 理解为 父元素接收信号-->
      <div class="box" :style="{fontSize:blogFontSize+'px'}">
        <blog-li v-for='item in blogs' v-bind:item='item' v-on:enlarge-text='blogFontSize+=10' :size='blogFontSize'>
        </blog-li>
      </div>
    </div>
    <script>
      Vue.component('blog-li', {
    
    
        props: ['item', 'size'],
        //每个组件必须只有一个根元素  emit中文发射的意思,可以将其理解成子组件向父组件发射信号
        template: `
        <div class='blog-li'>
          <button v-on:click="$emit('enlarge-text')">点击字体变大{
     
     {size}}</button>
          <h3>{
     
     {item.title}}</h3>
          <h2>{
     
     {item.id}}</h2>
        </div>
      `
      })
      const app = new Vue({
    
    
        el: '#app',
        data: {
    
    
          blogFontSize: 16,
          blogs: [{
    
    
              id: 1,
              title: '第一篇博文'
            },
            {
    
    
              id: 2,
              title: '第二篇博文'
            },
            {
    
    
              id: 3,
              title: '第三篇博文'
            }
          ]
        }
      })
    </script>
  </body>

  </html>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43812504/article/details/114700149