vue3知识点总结(二)

145 阅读3分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。

ref操作DOM和组件实例

ref属性可以获取DOM或者组件实例。在vue2中,使用this.$refs.xxx来获取DOM或者组件实例。在vue3中不同。vue3中先通过ref声明响应式数据,然后返回给模板使用,模板再通过ref绑定数据。

<template>
  <h1>ref的使用</h1>
  <h3 ref="aa">我是一个h3的内容</h3>
</template>

<script>
import {onMounted, ref} from 'vue'
export default {
setup() {
  const aa = ref(null)
  
  onMounted(() =>{
    console.log(aa.value);
  }) 
  return {
    aa,
  }
}
}
</script>

<style>

</style>

我们可以看下打印结果,获取到了DOM。 image.png 除了获取DOM,ref还可以获取组件实例,我们可以来调用组件实例中的方法。

创建MyForm.vue

<template>
  <div>我是Form组件</div>
</template>

<script>
export default {
setup() {
  const validate = () => {
    console.log('表单校验');
  }
  return {
    validate
  }
}
}
</script>

<style>

</style>

然后在App.vue中注册引入。在setup函数中通过ref声明响应式数据,通过点击按钮调用MyForm.vue中的validate方法。

<template>
  <h1>ref的使用</h1>
  <h3 ref="aa">我是一个h3的内容</h3>
  <button @click="fn">按钮</button>
  <hr>
  <MyForm ref="form"></MyForm>
</template>

<script>
import MyForm from './MyForm.vue'
import {onMounted, ref} from 'vue'
export default {
  components: {
    MyForm
  },
setup() {
  const aa = ref(null)
  const form = ref(null)
  onMounted(() =>{
    console.log(aa.value);
  }) 
    const fn = () => {
      form.value.validate()
    }
  return {
    aa,
    form,
    fn
  }
}
}
</script>

<style>

</style>

点击按钮,我们看到控制台打印出了结果。

image.png

废弃了过滤器

在vue3中废弃了过滤器。那么我们如果想使用过滤器的功能,该怎么办呢?官方建议我们使用方法调用或者计算属性

<template>
  <h1>ref的使用</h1>
  <h3>{{ formatTime(now) }}</h3>
  <h3>{{ formatTime(otherTime) }}</h3>
</template>

<script>
import moment from "moment";
export default {
  setup() {
    const now = new Date();
    const otherTime = new Date("2022-2-15 12:00:00");
    const formatTime = (value) => {
      return moment(value).format("YYYY-MM-DD");
    };
    return {
      now,
      formatTime,
      otherTime,
    };
  },
};
</script>

<style>
</style>

同样,我们可以看到结果。

image.png

父子组件通讯

父传子

跟vue2中一样,父传子我们通过props,但细节与vue2中不同。

<template>
  <h1>我是一个父组件</h1>
  <div>{{ money }} -- {{ car }}</div>
  <hr />
  <Son :money="money" :car="car"></Son>
</template>

<script>
import { ref } from "vue";
import Son from "./Son.vue";
export default {
  components: {
    Son,
  },
  setup() {
    const money = ref(100);
    const car = ref("玛莎拉蒂");

    return {
      money,
      car,
    };
  },
};
</script>

<style>
</style>

在子组件中通过props接收。

<template>
  <h1>我是子组件</h1>
  <div>{{ money }} - {{ car }}</div>
</template>

<script>
export default {
  props: {
    money: {
      type: Number,
      default: 0,
    },
    car: {
      type: String,
      default: "",
    },
  }
};
</script>

<style>
</style>

如果我们想要使用父组件传过来的值呢,我们怎么在setup中获取到到父组件传递给子组件的值呢?注意:vue3中没有this。

setup函数接受两个参数,第一个参数是父组件传递给子组件的值props,第二个参数是上下文context,context.emit是用来子组件给父组件传值的,可以进行解构{emit}。子传父后续介绍。

  setup(props,{emit}) {
    console.log(props);
  },

我们可以看到打印结果正是父组件传递给子组件的值。

image.png 我们使用计算属性对父组件传递给子组件的money进行处理。

  setup(props,{emit}) {
    console.log(props);
    const allMoney = computed(() => {
      return props.money + 1000
    })
    return {
      allMoney
    }
  },

在模板中进行渲染。

<template>
  <h1>我是子组件</h1>
  <div>{{ money }} - {{ car }}</div>
  <div>总共的钱{{allMoney}}</div>
</template>

image.png

子传父

如果我们在子组件中对父组件传递过来的值进行修改呢?在vue2中是可以在子组件中直接修改,但是不推荐,因为如果存在多个子组件修改值会造成数据混乱。而在vue3中,在子组件中直接是不可以的。

在子组件中,我们写一个按钮,并点击绑定buy事件,修改父组件传过来的值。

  <button @click="buy">买手机</button>

在setup函数中定义buy方法,并返回。

    const buy = () => {
      props.money = props.money - 500;
    };

我们可以看到运行结果,提示修改失败,该值是只读的。

image.png 那么正确做法是使用setup函数的第二个参数,并解构出emit。

  setup(props, { emit }) {
    console.log(props);
    const allMoney = computed(() => {
      return props.money + 1000;
    });
    const buy = () => {
      // props.money = props.money - 500;
      emit('buy', 500)
    };
    return {
      allMoney,
      buy,
    };
  },

在父组件中使用跟vue2一样。

<Son :money="money" :car="car" @buy="buy"></Son>
  setup() {
    const money = ref(100);
    const car = ref("玛莎拉蒂");

    const buy = (value) => {
      money.value -= value;
    };

    return {
      money,
      car,
      buy,
    };

点击按钮,我们可以看到值的变化。

image.png 我们可以看到浏览器有个警告,提示我们增加emits选项。

image.png 我们在子组件中,增加这个emits选项,这样可以很方便地了解到在子组件中传递了父组件哪些东西。

  emits: ['buy'],