组件通信

1.父子组件通信: Props Down

父组件给子组件传递数据通过props来传递

  • 1.现在父组件中往子组件的标签上添加属性的方式来传递数据

  • 2.然后在子组件中声明props来接收父组件传递的数据

  • 3.然后在子组件中就可以直接通过this来访问props中的数据了

  • 注意:props是单向数据流,当父组件数据变化时会传到给子组件,子组件却不能影响父组件,这是是为了防止子组件无意间修改了父组件的状态,让数据变得无序化难以理解,另外每次父组件更新时,子组件的所有props都会更新为最新值,

  • 如果你只想拿到父组件的数据却不受父组件更新数据的影响,子组件还想自己修改数据

    props:['initialCoumter'],
    data function(){
    //使用的时候使用count
    //这样的话虽然initialCoumter还会随着父组件更新,但是我的counter传递拷贝过来的变量将不会受父组件的影响,已经是独立的
    //而且我也可以修改counter
    //这样的话就是在局部备份了一下,互不影响
        return {counter:this.initialCoumter}
    }
    

    Prop 验证

    我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。

    为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

    Vue.component('my-component', {
      props: {
        // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
        propA: Number,
        // 多个可能的类型
        propB: [String, Number],
        // 必填的字符串
        propC: {
          type: String,
          required: true
        },
        // 带有默认值的数字
        propD: {
          type: Number,
          default: 100
        },
        // 带有默认值的对象
        propE: {
          type: Object,
          // 对象或数组默认值必须从一个工厂函数获取
          default: function () {
            return { message: 'hello' }
          }
        },
        // 自定义验证函数
        propF: {
          validator: function (value) {
            // 这个值必须匹配下列字符串中的一个
            return ['success', 'warning', 'danger'].indexOf(value) !== -1
          }
        }
      }
    })
    

    当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

2.父子组件通信: Events Up

  • 1.子组件在内部通过this.$emit(自定义事件名称,[可选参数])
  • 2.父组件在使用子组件的标签上通过@自定义事件名称 ="事件处理函数"的方式订阅子组件内部的发布事件
  • 3.这样的话,当子组件内部this.$emit的时候,则父组件订阅的自定义事件就会执行

分页组件例子

Vue.component('itcast-pagination',{
        props: {
          total:{
              type:Number,
              required:true
          },
          pageSize:{
              type:Number,
              required:true
          },
           propCurrentPage:{
               type:Number,
               default:1
           }
        },
        data(){
          return{
              //备份为局部变量
              currentPage:this.propCurrentPage
          }
        },
        computed:{
            //计算总页码
          totalPage(){
              return Math.ceil(this.total/this.pageSize)
          }
        },
        methods:{
        pageChange (page){
            if (page <= 0){
                page = 1
            }
            if (page > this.totalPage){
                page = this.totalPage
            }
          this.currentPage = page
            //这里处理完毕currentPage之后,通知父组件,让父组件调用自己的方法
           console.log(this.currentPage)
            //Events Up向上通知,父组件订阅了current-page事件
            this.$emit('current-page',page)
        }
    },
        template:`
        <nav aria-label="Page navigation">
  <ul class="pagination">
    <li>
      <a @click.prevent="pageChange(currentPage - 1)" href="#" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>
    <li class="(active:currentPage === n)" @click="pageChange(n)"  v-for="n in totalPage"><a  href="#">{{n}}</a></li>
    <li>
      <a@click.prevent="pageChange(currentPage + 1)" href="#" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>
</nav>`,
    })

在模板中使用分页组件

div id="app">
             <itcast-pagination
                        @current-change="handleCurrentChange"
                        :current-page="1"
                        :page-size="pageSize"
                        :total="total">
                </itcast-pagination>
</div>
<script>
      let app = new Vue({
        el:'#app',
        data: {
            total: 100,
            pageSize: 5
        },
        methods:{
            handleCurrentChange(page) {
                //拿到page页码发送请求列表数据
                console.log(page)
            }
        }
    })
</script>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。