vue3+vite+TypeScript 传值解析

vue3+vite+TypeScript 传值解析

vue3+vite+TypeScript 传值

vue2传值方式

在vue2系列中我们我们把状态都放到data返回的对象中,
父传子是通过给子组件添加属性和值,而子组件通过this.props来接收对应的值。
子传父则是通过this.$emit(‘方法名’,值)的方式去给父组件传值,而父组件通过给子组件注册对应事件来接收传递过来的实参。

vue3相比vue2传值上的改变

首先vue3系列增加了setup函数,那么在写法上就容易造成一定困惑,下面通过小例子来说明:

以下为父组件代码:

<template>
  <div>
    <div>父组件</div>
    <div>父传子counter的值:{{ counter }}</div>
    <button @click="handleClick">点击加值</button>
    <div>子组件传递过来deV的值:{{ deV }}</div>
    <div>------以下为子组件------------</div>
    <my-input @changeV="parentEvent" :counter="counter"></my-input>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import MyInput from "components/MyInput.vue";
export default defineComponent({
  name: "home",
  components: {
    MyInput,
  },
  //   data() {
  //     return {
  //       counter: 1,
  //       deV: "",
  //     };
  //   },
  setup(p, t) {
    const deV = ref("初始父值");
    const counter = ref(1);
    const parentEvent = (v: any) => {
      deV.value = v.value;
    };
    const handleClick = () => {
      counter.value++;
    };
    return { parentEvent, deV, handleClick, counter };
  },
});
</script>

从代码中可以看出父传子方式上是一样的。需要注意的是当传过去的值是绑定ref时 在父组件parentEvent 方法中接收到的参数并不是传递过来的值,打印出来可以看到是一个对象,其中value,_rawValue和_value都能拿到这个值。其中_rawValue是未转换的原始值,而_value是转换后的值
vue3+vite+TypeScript 传值解析_第1张图片

以下为my-input子组件代码

<template>
  <div>
    <div>{{ title }}</div>
    <input type="text" v-model="inputV" />
    <button @click="changeV">点击改变子组件的值</button>
    <div>{{ inputV }}</div>
    <div>{{ count }}</div>
    <div>父组件传过来的值:{{ counter }}</div>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref, Ref } from "vue";
export default defineComponent({
  name: "MyInput",
  data() {
    return {
      title: "输入框子组件",
      inputV: "",
    };
  },
  props: {
    counter: {
      type: String,
      required: false,
    },
  },
  setup(props, context) {
    const { emit } = context;
    const inputV  = ref("好");
    const count  = ref(0);
    const changeV = () => {
      count.value++;
      emit("changeV", inputV);
    };

    return { changeV, count, inputV };
  },
});
</script>

需要注意的是在setup函数中定义的函数和状态都要return出来。

provide和inject传值

//祖先组件
 setup(p, t) {
    const deV = ref("初始父值");
    const counter = ref(1);
    const other = reactive({ msg: counter });
    provide("counter", readonly(counter));
    provide("other", readonly(other));
    const changeCounter = (v: any) => {
      counter.value = v;
    };
    provide("changeCounter", changeCounter);
    
    return { parentEvent, deV, handleClick, counter, other };
  },


//子组件
<template>
  <div>这是other组件,接收到的other对象中的msg值为:{{ getMsg.msg }}</div>
  <div>这是接收到的counter值:{{ counter }}</div>
  <button @click="handleDispatch">点击改公共值</button>
</template>
<script>
import { inject, ref } from "vue";
export default {
  name: "other",
  setup(p, c) {
    const getMsg = inject("other", ref());
    const counter = inject("counter", ref());
    const changeCounter = inject("changeCounter");
    // console.log(getMsg, counter, changeCounter, c);
    const handleDispatch = () => {
      changeCounter(5);
    };
    return { getMsg, counter, handleDispatch, changeCounter };
  },
};
<script>

使用provide和inject可很方便的对子孙组件进行传值

使用方法是:在祖先组件中使用provide(‘名称’,值),在需要使用的地方使用inject(‘名’)获取到传过来的值。如果需要在子孙组件中改值或者传值给祖先组件时,可以在祖先组件中传方法,通过方法获取到参数。

由于我也是这两天才开始写vue cli3所以有不完整或错误之处请见谅。

你可能感兴趣的:(前端-vue,vue-cli3,typescript,vue)