vue组件传值、emit、v-model、ref、provide、inject、attrs

总结:
1.子组件$emit抛出 父组件响应

父组件

<template>
  <div>
    <Son :parentsData="num" @updateParents="changeNum" />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    Son,
  },
  methods: {
    changeNum(params) {
      this.num = params;
    },
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件

<template>
  <div>
    {{ parentsData }}

    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  props: {
    parentsData: {
      type: Number,
    },
  },
  methods: {
    add() {
      this.$emit("updateParents", 1);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>

2.父组件xx.sync="xx"也是双向绑定 子组件$emit('update:xx')抛出 语法糖

父组件语法糖写法

<template>
  <div>
    <Son :parentsData.sync="num"  />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    Son,
  },
  methods: {
    // changeNum(params) {
    //   this.num = params;
    // },
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件语法糖写法

<template>
  <div>
    {{ parentsData }}

    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  props: {
    parentsData: {
      type: Number,
    },
  },
  methods: {
    add() {
      this.$emit("update:parentsData", 1);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>

不使用语法糖

父组件

<template>
  <div>
    <Son :parentsData.sync="num" @changeNum="(e) => (num = e)" />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    Son,
  },
  methods: {
    // changeNum(params) {
    //   this.num = params;
    // },
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件

<template>
  <div>
    {{ parentsData }}

    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  props: {
    parentsData: {
      type: Number,
    },
  },
  methods: {
    add() {
      this.$emit("changeNum", 1);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


3.父组件v-model响应 子组件抛出input事件 接收value参数 可以通过model参数配置响应事件与接收参数
父组件

<template>
  <div>
    <Son v-model="num" />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    Son,
  },
  methods: {

  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件   定义model  vue3.0model内key有改变

<template>
  <div>
    {{ num }}

    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Number,
    },
  },
  model:{
    prop:"num",
    event:"changeNum"
  },
  mounted(){
    console.log(this.num);
  },
  methods: {
    add() {
      this.$emit("changeNum", 1);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>

另一种写法

父组件

<template>
  <div>
    <Son v-model="num" @input="(e) => (num = e)" />
// @input="(e) => (num = e)"  可以不用加上input也能生效
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    Son,
  },
  methods: {

  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件、只能用value接收父传来参数

<template>
  <div>
    {{ value }}

    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: Number,
    },
  },
  mounted() {
    console.log(this.num);
  },
  methods: {
    add() {
      this.$emit("input", 1);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>

4.parents访问父组件实例,官方文档建议谨慎使用,看个人需求

父组件

<template>
  <div>
    <Son :parentsNum="num" />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
    };
  },
  components: {
    Son,
  },
  methods: {
    changeNum() {
      this.num++;
    },
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件

<template>
  <div>
    {{ parentsNum }}

    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  props: {
    parentsNum: {
      type: Number,
    },
  },
  methods: {
    add() {
      this.$parent.changeNum()
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


5.通过provide inject传递函数与参数

父组件   重点:传递的对象在有响应式,否则子组件没有响应式

<template>
  <div>
    <Son />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      obj: {
        num: 0,
      },
    };
  },
  provide() {
    return {
      _parents: this,
      obj: this.obj,
      changeNum: this.changeNum,
    };
  },
  components: {
    Son,
  },
  methods: {
    changeNum() {
      this.obj.num++;
    },
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件

<template>
  <div>
    {{ obj.num }}
    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  inject: ["obj", "changeNum", "_parents"],
  mounted() {
    console.log(this._parents);//拿到父组件实例,单页面应用控制某些状态
  },
  methods: {
    add() {
      this.changeNum();
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


5.通过ref来获取组件实例,ref不能再template上使用,compute也不能用
父组件 在搜索参数触发子组件方法

<template>
  <div>
    <Son ref="sonModule" />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  components: {
    Son,
  },
  mounted() {
    this.$refs.sonModule.add();
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件

<template>
  <div>
    {{ num }}
    <button @click="add">加1</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 0,
    };
  },
  methods: {
    add() {
      this.num++;
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


6.可以通过扩展函数在原型上绑定广播/派发这个是在1.0中有的,但是2.0去除了,原理就是通过$children $parent循环emit事件
7.重新创建一个实例实现eventBus事件总线 原理为在新的实例上通过$on $emit传递与响应
8.传递参数时可以用v-bind/$attrs传递  传递函数可以用v-on/$listeners

父组件  

<template>
  <div>
    {{ num }}
    <Son :parentsNum="num" :parentsName="name" @parentsEvent="changeNum" />
  </div>
</template>

<script>
import Son from "./text.vue";
export default {
  data() {
    return {
      num: 0,
      name: "baby",
    };
  },
  components: {
    Son,
  },
  methods: {
    changeNum(params) {
      this.num = params;
    },
  },
};
</script>

<style  scoped>
div {
  padding: 50px;
}
</style>

子组件   

$attrs内部值被prios接收,则值被存到$props内部,没有被props接收,则存在$attrs内部,子组件内部把$attrs赋值给孙子组件该值会一直传递

$listeners不受影响

<template>
  <div>
    {{ parentsNum }}
    <button v-on="$listeners" @click="add">孩子组件传递加1</button>
    <Child v-bind="$attrs" v-on="$listeners" />
  </div>
</template>

<script>
import Child from "./child.vue";
export default {
  //这里接收了一个props,当前实例里$attrs只剩下boby
  //$listeners会一直随着传递下去
  props: {
    parentsNum: {
      type: Number,
    },
  },
  components: {
    Child,
  },
  mounted() {
    console.log(this.$attrs);
  },
  methods: {
    add() {
      this.$emit("parentsEvent", 456);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>

孙子组件

<template>
  <div>
    <button v-on="$listeners" @click="add">孙子组件传递加1</button>
  </div>
</template>

<script>
export default {
  mounted() {
    console.log(this.$attrs, "child");
    console.log(this, "child");
  },
  methods: {
    add() {
      this.$emit("parentsEvent", 132);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


不建议用$parent/$children 以及组件派发/广播,dispatch1.0是有得,2.0就没有了,因为这样结构不清晰

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值