vue项目实战中常见的数据通信方式

一、父组件传递数据到子组件中(属性传递)

  • 1、父组件

    <template>
      <div>
        <child01 :names="names" v-if="isLoading"/>
      </div>
    </template>
    
    <script>
    import child01 from './child01'
    export default {
      data () {
        return {
          names: [],
          isLoading: false
        }
      },
      methods: {
        getData () {
          setTimeout(() => {
            this.names = ['哈哈', '嘻嘻', '美美']
            this.isLoading = true
          }, 2000)
        }
      },
      mounted () {
        this.getData()
      },
      components: {
        child01
      }
    }
    </script>
  • 2、子组件

    <template>
      <div>
        <ul>
          <li v-for="(item, index) of names" :key="index">{{item}}</li>
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        names: {
          type: Array
        }
      }
    }
    </script>

二、子组件传递值到父组件(方法传递)

  • 1、子组件

    <li v-for="(item, index) of names" :key="index" @click="sendVal(item)">{{item}}</li>
    ...
    methods: {
        sendVal (val) {
          this.$emit('sendVal', val)
        }
    }
    ...
  • 2、父组件

    <child01 :names="names" v-if="isLoading" @sendVal="sendVal"/>
    ...
    methods: {
        sendVal (val) {
          console.log(val)
        }
    },
    ...

三、父组件调用子组件的方法(直接使用ref)[也可以获取子组件的属性]

  • 1、子组件

    methods: {
        sendVal (val) {
            this.$emit('sendVal', val)
        },
        foo () {
            console.log('我是子组件的方法')
        }
    }
  • 2、父组件

    foo () {
      console.log('子组件中的数据===>', this.$refs.child)
      this.$refs.child.foo()
    }

四、子组件调用父组件的方法(属性)

  • 1、子组件

    bar () {
        console.log(this.$parent)
        this.$parent.names.push('张三')
    }

五、子组件同步修改父组件的值(在属性后面加sync)

  • 1、父组件

    <child01 :names="names" v-if="isLoading" @sendVal="sendVal" ref="child" :aa.sync="text"/>
  • 2、子组件

    post () {
      this.$emit('update:aa', '子组件的值')
    }

六、父组件传递给子组件,子组件又传递给孙组件

常见的方法:

  • 1、父传给给子,子传递给孙组件,逐级传递(非常麻烦而且不易于维护的)
  • 2、使用vuex状态机(杀鸡用牛刀,大材小用)
  • 3、使用Vue提供了【inheritAttrs】【attrs】
  • 4、使用provide/inject进行多级组件值传递

步骤

  • 1、定义一个父组件,传递两个参数到子组件和孙组件

    <template>
      <div>
        <child02 :text="text" :count="count"/>
      </div>
    </template>
    
    <script>
    import child02 from './child02'
    export default {
      data () {
        return {
          text: '父组件的值',
          count: 123456
        }
      },
      components: {
        child02
      }
    }
    </script>
    
    <style scoped>
    </style>
  • 2、子组件

    <template>
      <div>
        <h2>第二个组件</h2>
        <div>{{text}}</div>
        <child03 v-bind="$attrs"/>
      </div>
    </template>
    
    <script>
    import child03 from './child03'
    export default {
      props: {
        text: {
          type: String | Number
        }
      },
      // 解决父组件传递过来的值,没被使用的情况下挂载在本组件上(类似自定义属性)
      inheritAttrs: false,
      components: {
        child03
      },
      mounted () {
        console.log(this.$attrs)
      }
    }
    </script>
    
    <style scoped>
    </style>
  • 3、孙组件

    <template>
      <div>
        <h3>我是孙组件</h3>
      </div>
    </template>
    
    <script>
    export default {
      mounted () {
        console.log('我是孙组件', this.$attrs)
      }
    }
    </script>
    
    <style scoped>
    </style>

七、provide/inject多级组件传递值

  • 1、父组件中使用provide(也不需要写属性传递)

    provide: {
        parent: '父组件的值===='
    },
  • 2、在需要使用的子孙组件中使用

    export default {
      inject: ['parent'],
      mounted () {
        console.log(this.parent)
      }
    }

八、provide/inject异步创建数据

  • 1、父组件

    <template>
      <div>
        <child02 :text="text" :count="count" v-if="isLoad"/>
      </div>
    </template>
    
    <script>
    import child02 from './child02'
    export default {
      provide () {
        let parent = {}
        setTimeout(() => {
          Object.defineProperty(parent, 'value', {
            get: () => this.text,
            enumerable: true
          })
          this.isLoad = true
        }, 1000)
        return {
          parent
        }
      },
      data () {
        return {
          text: '父组件的值',
          count: {
            name: 'haa'
          },
          isLoad: false
        }
      },
      mounted () {
      },
      components: {
        child02
      }
    }
    </script>
    
    <style scoped>
    </style>
  • 2、子组件跟之前的一样

九、混入mixins的使用

其实这个功能有些类似于es6中的Object.assign()方法。根据一定的规则合并两个配置,常用于抽取相同的地方

  • 1、单独定义一个文件(自动关闭弹框)

    export const mixin = {
        methods: {
            autoClose () {
                setTimeout(() => {
                  this.$Modal.remove();
                }, 2000);
            }
        }
    }
  • 2、使用

    import {mixin} from './../utils/minx'
    export default {
      mixins: [mixin],
      methods: {
        childClose () {
          // close在本组件中没有定义,其实就是使用了minx里面的
          this.close()
        }
      }
    }

十、源码下载传送门

猜你喜欢

转载自blog.csdn.net/kuangshp128/article/details/80327429