Vue组件创建和父子组件通信数据传递(三)

Vue组件基础学习(三)

1 全局的自定义组件

  • 方法Vue.component(id,[definition])

    • {string} id

    • {Function | Object} [definition]

    • 用法 注册或获取全局组件。注册还会自动使用给定的id设置组件的名称(截取官网介绍)

      // 注册组件,传入一个扩展过的构造器
      Vue.component('my-component', Vue.extend({ /* ... */ }))
      
      // 注册组件,传入一个选项对象 (自动调用 Vue.extend)
      Vue.component('my-component', { /* ... */ })
      
      // 获取注册的组件 (始终返回构造器)
      var MyComponent = Vue.component('my-component')
      
  • 简单实例 ( data必须是一个函数

        <div id="app">
              <my-component></my-component>
        </div>
        <script>
        //全局的自定义组件 是可复用的Vue实例,所以也具备例如 data computed,watch methods 以及生命周期钩子等
        //命名如果是驼峰命名法,那么创建时以 -加小写
            //my-component
        Vue.component('myComponent',{
            //组件的data参数是一个函数方法,返回对象
            data:function(){
                return{
                    count:0
                }
            },
            //模板定义
            template:'<button @click="count++">点击次数:{{count}}</button>'
        })
        var vm=new Vue({
            el:"#app",
            data:{
                msg:"aaa"
            }
        })
        </script>
    

2.父子组件之间的数据传递

1. 父组件向子组件传递,通过Prop向子组件传递数据
  <div id="app">
        <!-- 静态传值 -->
        <my-component-prop title="参数传递"></my-component-prop>
        <!-- 动态传值 -->
        <my-component-prop :title="msg"></my-component-prop>
        <!-- 动态循环渲染使用 -->
        <my-component-prop v-for="title in titles" :title="title"></my-component-prop>
        <!-- 静态传递数字,布尔值,数组,对象也要通过v-bind绑定的方式来告诉Vue 这是一个表达式而不是字符串。例如以下-->
      <my-component-prop :number="40"></my-component-prop>
      <my-component-prop :isTrue="false"></my-component-prop>
      <my-component-prop :titles="["aa","bbb"]"></my-component-prop>
      <my-component-prop :object="{name:'lisi',age:18}"></my-component-prop>
      <!-- 当然这些也可以动态传递 -->
    </div>
    <script>
  Vue.component('my-component-prop',{
        props:['title'],
        //模板定义
        template:'<h3>{{title}}</h3>'
    })
    var vm=new Vue({
        el:"#app",
        data:{
            msg:"参数传递",
            titles:["a",'b','c']
        }

    })
    </script>

你想将一个对象的所有属性都作为 prop 传入

  <my-component-prop v-bind="post"></my-component-prop>
  <!-- 等价与 -->
 <my-component-prop v-bind:title="post.title" :name="post.name" :age="post.age"></my-component-prop>
  post:{title:'aaa',name:'lisi',age:18}
  Vue.component('my-component-prop',{
        //组件的data参数是一个函数方法
        props:['title','name','age'],
        //模板定义
        template:'<h3>{{title}} {{name}}{{age}}</h3>'
    })

  • 父组件向子组件传递数据是单向数据流

    以上通过Prop向子组件动态的传递数据, 当数据改变时 那么对应子组件的也会刷新改变

    <div id="app">
    <!-- 例如 -->
    <!-- 通过表单控件来双向绑定数据 -->
    <input v-model="msg">
    <!-- 自定义组件 -->
    <my-component-prop :msg="msg"></my-component-props>
    </div>
    <script>
       //当msg值发生改变时 定义的组件mgs值也会改变
       Vue.component('my-component-props',{
            props:['msg'],
            //模板定义
            template:'<h3>{{message}}</h3>'
        })
       var vm=new Vue({
            el:"#app",
            data:{
                msg:"参数传递"
            }
        })
    </script>
    

    而子组件需要使用这个参数,而不改变父组件这个参数的值。子组件接下来希望将其作为一个本地的 prop 数据来使用,这是就可以定义一个本地的data属性 并将prop的初始值赋给他

    • 1.可以在子组件内部定义参数,并将父组件传递的值赋给他
    Vue.component('my-component-prop',{
            //组件的data参数是一个函数方法
            props:['msg'],
            data:function(){
                return {
                    message:this.msg
                }
            },
            //模板定义
            template:'<h3>{{message}}</h3>'
        })
    

    2.这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
    
  • 也可以为props指定传参类型

    props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise 
    }
    

    **注意:**如果props要为某个参数或对象指定类型就用{}以对象的形式来包裹,反之用[]以字符串数组形式列出

2.子组件向父组件传值,通过发布自定义事件,让父组件监听从而达到子组件向父组件传递参数,使用**this.$emit()**方法

第一步定义子组件 (这里定义的是全局,也可以定义局部)

//自定义组件
var my_children = Vue.component('children', {
            //绑定点击事件
            template: '<button @click="incrementCount">添加count={{count}}</button>',
            data: function () {
                return {
                    count: 0
                }
            },
            methods: {
                incrementCount: function () {
                    this.count=this.count+1;
                    //发布一个一个自定义事件并传参
                    this.$emit('addcount', this.count)
                }
            }
        })

第二部父组件调用并获取参数

var vm = new Vue({
            el: "#app",
            components: {
                perent: my_children
            },
            methods: {
                add: function (value) {
                    this.counts.push(value)
                    //console.log(this.counts)
                }
            },
            data: {
                counts: []
            }
        })
<div id="app">
        <perent @addcount="add"></perent>
        <ul>
            <li v-for="count in counts">{{count}}</li>
        </ul>
</div>
  • 其他注意事项

    • 在自定义组件的根元素上监听原生的事件,就可以使用v-on的修饰符.native来实现

      <my-component v-on:click.native="onClick"></my-component>
      
    • 在自定义组件的根元素上使用v-model

      **官网介绍:**一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的model 选项可以用来避免这样的冲突:

      Vue.component('base-checkbox', {
                  //使用model来避免冲突
                  model: {
                      prop: 'checked',
                      event: 'aa'
                  },
                //仍需要在props下定义checked
                  props: {
                      checked: Boolean
                  },
                  //将状态发送给父组件
                  template: `<input
                             type="checkbox"
                             v-bind:checked="checked"
                             v-on:change="$emit('aa', $event.target.checked)">`
              });
      var vm=new Vue({
                  el:"#app",
                  data:{
                      checked:true
                  }
              });
      
      <div id="app">
              <base-checkbox v-model="checked"></base-checkbox>
              <h3>{{checked}}</h3>
      </div>
      
    • 自定义组件内使用v-model

      Vue.component('children', {
                  data:function(){
                      return {
                          checked:false
                      }
                  },
               
                  template: `<input type="checkbox" v-model="checked" @change="change">`,
                  methods:{
                      //将状态发送给父组件
                      change(){
                          this.$emit('change',this.checked)
                      }
                  }
              });
       var vm=new Vue({
                  el:"#app",
                  data:{
                      value:false
                  },
                  methods:{
                      getChange(value){
                          this.value=value
                      }
                  }
              })
      
      <div id="children">
              <aaa @change="getChange"></aaa>
              <h5>{{value}}</h5>
      </div>
      
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

54hake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值