vue父子组件传值学习记录

生命周期

  • beforeCreate 创造之前
    此时数据和事件方法还未绑定到对象上

  • created 创造
    将数据和事件绑定到对象上

  • beforeMount 渲染之前
    根据数据生成的dom对象是获取不到的

  • mounted 渲染
    可以拿到dom对象

  • beforeUpdate 更新之前

  • update 更新

  • beforeDestroy 摧毁

  • destroy 摧毁

生命周期函数可以帮助我们快速了解整个页面的组成情况

组件传值

我们在使用vue定义组件的时候,通常有以下两种情况

  • 父组件传值到子组件
  • 子组件传值到父组件

对于这两种情况,vue都提供了解决方法

父子传值

我们只需要在子组件中定义props属性,并定义子组件所需的数据变量名
在父组件中使用v-bind进行绑定子组件定义的变量名传值即可

案例

  • 父组件html
<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>
  • 父组件js
new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})
  • 子组件html
Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

子父传值(传递数据,做数据监听)

  • 父组件
<div id="app">
			<ul>
				<product v-for="item,index in proList" :pro="item" :key='index' @choose='changeEvent'></product>
			</ul>
		<h2>选中的商品是:{{ this.fruits }}</h2>
</div>
  • 子组件
Vue.component("product", {
				props: ['pro'],
				template: `<li>
							<h3>{{pro.title}}</h3>
							<h4>{{pro.price}}</h4>
							<p>{{pro.brief}}</p>
							<button @click="chooseEvent(pro.title)">选择</button>
						</li>`,
				methods:{
					chooseEvent(title){
						console.log(title)
						// 子父传参
						// 触发事件名称为choose
						this.$emit('choose',title)
					}
					
				}
			})
			let app = new Vue({
				el: '#app',
				data: {
					proList: [{
						title: '苹果',
						price: 12,
						brief: '新鲜的苹果'
					}, {
						title: '香蕉',
						price: 10,
						brief: '新鲜的香蕉'
					} ],
					fruits:""
				},
				methods:{
					changeEvent(data){
						console.log("触发监听事件",data)
						this.fruits=data
						console.log(this.fruits)
					}
				}

			})

子父传值是通过vue实例的$emit函数触发监听事件,在父组件上做监听,当子组件的事件被触发时,父组件进行相关的操作

父子传值(传递方法)

父子组件之间传递不仅仅可以传递数据,还可以传递一个方法,因为组件的方法也是一个对象【函数对象】,这样就可以在父组件的方法中对父组件的内容进行修改,然后传递方法给子组件,相当于让子组件也有权利去做修改

传递父组件的方法传递到子组件中

案例演示

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title></title>
  <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
  <ul>
    <product v-for="(item,index) in proList" :pro="item" :key='index' :action="changeEvent"></product>
  </ul>
  <h2>选中的商品是:{{ this.fruits }}</h2>
</div>

<script type="text/javascript">
  <!--子组件-->
  Vue.component("product", {
    props: ['pro','action'],
    template: `
      <li>
        <h3>{{pro.title}}</h3>
        <h4>{{pro.price}}</h4>
        <p>{{pro.brief}}</p>
        <button @click="chooseEvent(pro.title)">选择</button>
      </li>`,
    methods: {
      chooseEvent(title) {
        // 子父传参,传递方法
        console.log(this.action(title))
        console.log("子组件对象",this)
      }

    }
  })
  //父组件
  let app = new Vue({
    el: '#app',
    data: {
      proList: [{
        title: '苹果',
        price: 12,
        brief: '新鲜的苹果'
      }, {
        title: '香蕉',
        price: 10,
        brief: '新鲜的香蕉'
      }],
      fruits: ""
    },
    methods: {
      changeEvent(data) {
        console.log("触发父组件监听事件", data)
        this.fruits = data
        console.log(this.fruits)
        console.log("父组件对象",this)
      }
    }
  })
</script>
</body>
</html>

传递方法就相当于第三方调用接口一样,只需要在子组件中使用一个对象变量接收父组件传递的方法,然后由子元素进行调用

$parent(当前元素的父元素)

子组件可以通过该属性找到父元素的vue对象,从而直接调用父元素的方法和变量

<div id="app">
  <ul>
    <product v-for="(item,index) in proList" :pro="item" :key='index' :action="changeEvent"></product>
  </ul>
  <h2>选中的商品是:{{ this.fruits }}</h2>
</div>
  • 子组件js
<!--子组件-->
  Vue.component("product", {
    props: ['pro','action'],
    template: `
      <li>
        <h3>{{pro.title}}</h3>
        <h4>{{pro.price}}</h4>
        <p>{{pro.brief}}</p>
        <button @click="chooseEvent(pro.title)">选择</button>
      </li>`,
    methods: {
      chooseEvent(title) {
        // 子父传参,传递方法
        //console.log(this.action(title))
        console.log("子组件方法")
        console.log(this)
        this.$parent.changeEvent(title)
      }

    }
  })
  • 父组件
 //父组件
  let app = new Vue({
    el: '#app',
    data: {
      proList: [{
        title: '苹果',
        price: 12,
        brief: '新鲜的苹果'
      }, {
        title: '香蕉',
        price: 10,
        brief: '新鲜的香蕉'
      }],
      fruits: ""
    },
    methods: {
      changeEvent(data) {
        console.log("父组件方法")
        this.fruits = data
        console.log(this.fruits)
      }
    }
  })

该方法也可以直接写在方法定义的事件中,(只适合简单的逻辑,复杂的还是需要写成方法调用)

 Vue.component("product", {
    props: ['pro','action'],
    template: `
      <li>
        <h3>{{pro.title}}</h3>
        <h4>{{pro.price}}</h4>
        <p>{{pro.brief}}</p>
        <button @click="$parent.changeEvent(title)">选择</button>
      </li>`,
  })

也可以直接修改父元素的变量

Vue.component("product", {
    props: ['pro','action'],
    template: `
      <li>
        <h3>{{pro.title}}</h3>
        <h4>{{pro.price}}</h4>
        <p>{{pro.brief}}</p>
        <button @click="$parent.fruits = title">选择</button>
      </li>`,
  })

$root

获得根组件,使用方法和$parent 属性是一样的使用方法

$children(当前元素的子元素)

父组件可以通过该属性找到子元素的vue对象,从而直接调用子元素的方法和变量
但是子元素有多个,获得的是一个数组对象,需要明确知道是第几个组件,通过下标获取进行具体的调用

总结

为了满足低耦合的特性,我们推荐使用props和$emit进行父子组件之间的传值

父组件传递子组件 ,子组件定义props接收,接收之后可以直接调用该变量(无论是数据还是方法)
子组件传递父组件,使用this.$emit(“父组件定义的监听方法”,数据)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值