Vue学习(二)——父子组件的交互

前言

如果你对组件的基础不是很了解,请先学习前一篇关于vue的文章,或者去官网学习,否则只会让你越学越乱。

Vue的项目实际上就是一堆组件堆积起来的结果,那么组件之间如何相互影响,说白了页面怎么传个参数给组件,组件有改变了又怎么通知页面。这就涉及到父子组件交互的问题。

父子组件交互

父子组件属性的传递

父子组件的交互通常的模式是:子组件获取父组件为其设置的属性,父组件则通过绑定子组件触发的事件回调处理函数。

这里我们直接用上一篇文章创建的项目,就把代码改一下,先改App.vue

<template>
  <div id="app">
    <p>数字一:<input v-model="num1" type="number"/></p>
    <p>数字二:<input v-model="num2" type="number"/></p>
    <button-plus v-bind:a="num1" v-bind:b="num2" v-on:result="showResult"></button-plus>
    结果:<input v-model="res"/>
  </div>
</template>

<script>
import ButtonPlus from './components/ButtonPlus'

export default {
  name: 'App',
  components: {
    ButtonPlus
  },
  data(){
    return{
      num1 : 0,
      num2 : 0,
      res : 0,
    }
  },
  methods : {
    showResult(val){
      this.res = val;
    }
  }
}
</script>

这里我们打算输入两个数,按一下按钮,把输入的两个数传进去子组件ButtonPlus,在组件里面相加,返回结果给父组件,父组件显示结果。其中v-bind:a="num1" v-bind:b="num2",这两个表示把子组件的a属性与变量num1绑定,b属性与变量num2绑定。v-on:result="showResult"表示子组件触发的result事件和父组件的showResult函数绑定。简单理解就是v-bind用于属性绑定,v-on用于事件绑定。

子组件我们在components目录下新建一个文件ButtonPlus.vue:

<template>
  <div>
    <button v-on:click="plusFun">相加</button>
  </div>
</template>

<script>
export default {
  name: "ButtonPlus",
  props: {
    a: String,
    b: String,
  },
  methods: {
    plusFun() {
      this.$emit('result', Number(this.a) + Number(this.b));
    },
  },
};
</script>

props里面的a和b就是用于接收父组件传值的属性。点击按钮会触发plusFun函数,会调用$emit,触发名为result的自定义事件,事件自带的参数为a与b相加的结果。前面父组件使用子组件时把showResult事件绑定到showResult函数中,$emit的第二个参数会带到showResult的参数中。

PS:$emit()格式为:$emit("事件名",参数1,参数2,参数3……)。绑定的函数,其参数、与$emit的参数一一对应。即如果this.$emit('result', Number(this.a) + Number(this.b),2,3,4,5,6,7,8);这样的话,绑定函数可以是showResult(val,val2,val3,val4,val5,val6,val7,val8)这样处理传参。

运行项目,填入数字,计算得到结果。

组件属性传值什么时候加冒号什么时候不加?

这是一个伪命题。我开始做vue的时候是半路出家,经常被这个搞懵,看别人代码费力,自己写更费力,很多时候看着element ui的文档,到底这个属性要不要加冒号,怎么有的还加@。经常看到类似以下情况:

<el-input placeholder="请输入内容" :rows="2" v-model="in" :disabled="true"></el-input>

为什么有些属性前面有个冒号,有些没有呢?说它是伪命题,因为冒号是缩写,实际上是v-bind:,所以如果问题变成要不要加v-bind:,那问题是不是清晰很多了?当有的组件要传的参数很多,写一堆v-bind:就很繁琐了,可读性也不好,作者很贴心,可以缩写成一个冒号。如果不加v-bind:,那给组件属性传值传的是字符串,一般的html标签就是这样。如果加上v-bind:,则表示绑定了变量,或者传布尔值(true、false)、传数值。

所以你再看上面:rows="2"和:disabled="true"为什么前面会有冒号,因为传的是数值和布尔值。为什么v-model前面不用加冒号,因为v-model不是组件的一个属性,它是语法糖,v-model="in"本质类似:value="in" @input="in = $event.target.value",所以已经绑定了value属性与变量了,没理由再加个v-bind在前面。

同样还有v-on:可以缩写成@,例如父组件的v-on:result="showResult"缩写成@result="showResult",所以前面加@号的是绑定了事件对应的处理函数,并不是组件的属性。这下都捋清了吧?

小结

父子交互的内容远远不止这么少,但是熟练掌握props、emit等的使用,就能应付大多数情况了。其他相关的可以到官网上自学。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值