<五>子父组件间的交互

组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码。

1、基本定义和使用

    <body>
      <div id="app">
        <child></child>
        <child1></child1>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全局注册
      Vue.component('child', {
        template: '<h1>自定义组件!</h1>'
      })

      var ChildTemplate = {
        template: '<h1>自定义组件!</h1>'
      }

      var app = new Vue({
                          el: '#app' ,
                          components: {
                          // <child1> 将只在父模板可用,局部注册
                          'child1': ChildTemplate
  }                                  
                    });
   </script>

2、父组件向子组件交互,props 单向传递

  <body>
      <div id="app">
        <div>
          <input v-model="parentMsg">
          <br>
          <child v-bind:message="parentMsg"></child>
        </div>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全局注册
      Vue.component('child', {
        props:['message'],
        template: '<h1>{{message}}</h1>'
      })

      var app = new Vue({
                          el: '#app', 
                          data:{
                            parentMsg:''
                          }                               
                    });
   </script>

3、props验证,如上面例子,如果message只接收数值型用于计算,但是该值是用户输入,这时候用户可以随便输入,但是字符型数据并不是我们想要的。

因此传入的参数可能会在开发子组件的人的意料之外,程序就会发生错误,在函数调用之前先检查一下函数一样,props可以进行一个预先检查。

 <body>
      <div id="app">
        <div>
          <input v-model="parentMsg">
          <br>
          <child v-bind:message="parentMsg"></child>
        </div>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全局注册
      Vue.component('child', {
        props:{
          message:Number        //只能传入数值型
        },
        template: '<h1>{{message}}</h1>'
      })

      var app = new Vue({
                          el: '#app', 
                          data:{
                            parentMsg:0
                          }                               
                    });
   </script>

结果:当没有对输入框的输入值限定为数值型时,看结果

 

 vue会自动给出一个warn提示,只是个警告,没有强制报错。这个警告不知道怎么捕捉(噗)

给输入框输入一个限定类型,

 <input v-model.Number="parentMsg">

这样就可以自动将输入值过滤字符并将输入值自动转换成数字型,这样就不会出现这个警告了。

props验证有多种类型。

当允许多种类型时,比如允许输入string和number类型时props的定义

 props:{
          message:[Number,String]        //只能传入数值型
        },

所有的验证如下:

 props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    A: Number,
    // 多种类型
    B: [String, Number],
    // 必传且是字符串
    C: {
      type: String,
      required: true
    },
    // 数字,有默认值
    D: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    E: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    F: {
      validator: function (value) {
        return value > 10
      }
    }
  }

 4、上面是父组件向子组件传递数据,那如果子组件向父组件传递数据呢?

  •     使用 $on(eventName) 监听事件
  •     使用 $emit(eventName) 触发事件

父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

 <body>
      <div id="app">
        <p>{{ total }}</p>
      <child v-on:increment="incrementTotal"></child>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全局注册
      Vue.component('child', {
        template: '<button v-on:click="changeName">{{ counter }}</button>',
        data:function () {
            return {
              counter: 0
            }
          },
        methods: {
          changeName: function () {
            this.counter += 1
            this.$emit('increment')
          }
  },
      })

      var app = new Vue({
                          el: '#app', 
                          data:{
                            total: 0
                          } , 
                          methods: {
                            incrementTotal: function () {
                            this.total += 1
                            }
                          }                              
                    });
   </script>

如代码所示,将一个方法绑定一个别名传递给子组件,然后子组件使用

this.$emit('increment')

触发这个参数就行了。

 

posted @ 2021-12-11 18:46  许轩霖  阅读(80)  评论(0编辑  收藏  举报