VUE3新特性

187 阅读2分钟

搭建一个Vue3项目

npm install -g@vue/cli // 保证vue-cli在4.5版本以上
vue create 项目名

setup

新的组件选项,在创建组件之前执行,并作为组合式 API 的入口点

  • setup执行时机
在beforeCreate之前执行(执行一次),此组件对象还没有创建,
this是undefined,不能通过this来访问data\computed\methods\props

此时要想使用组件怎么办呢?
可以通过getCurrentInstance这个函数来返回当前组件的实例对象,也就是当前vue这个实例对象
  • setup返回值
一般都返回一个对象:为模版提供数据,也就是模版中可以直接使用此对象中的所欲属性方法
返回对象中属性会与data函数返回对象的属性合并为组件对象的属性
返回对象中的方法会与methods中的方法合并成功组件对象的方法
<template>
  <div>
    {{ msg }}
  </div>
</template>

<script lang="ts">
import { defineComponent, getCurrentInstance } from "vue";

export default defineComponent({
  // 在beforeCreate之前执行(执行一次)
  setup() {
    console.log("setup执行了");
    const msg = "Hello Vue3!";
    const { proxy }: any = getCurrentInstance(); // 返回当前组件的实例对象,也就是当前vue这个实例对象
    console.log(proxy);

    function fun1() {
      console.log("setup");
    }

    return {
      msg,
      fun1,
    };
  },

  data() {
    return {
      name: "Steven",
    };
  },

  beforeCreate() {
    console.log("beforeCreate执行了");
  },

  mounted() {
    console.log(this);
  },

  methods: {
    fun2() {
      console.log("methods");
    },
  },
});
</script>

setup的参数

props:是一个对象,里面有父级组件向子级组件传递的数据,并且是在子级组件中使用props接收到的所有属性,并且获取到的数据将保持响应性。

context:context 是一个 JavaScript 对象,这个对象暴露了三个组件的属性,我们可以通过 解构 的方式来分别获取这三个属性   { attrs, slots, emit }
    attrs:它是绑定到组件中的 非 props 数据,并且是非响应式的。
    emit:vue2 this.$emit();
    slots: 是组件的插槽,同样也不是 响应式的
  • app.vue
<SetUp @testEmit="testEmit" msg="Hello SetUp!" />
  • setup.vue
<template>
  <div>
    {{ msg }}
    <button @click="testEmit">测试emit</button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  props: ["msg"],
  setup(props, context) {
    console.log("props", props.msg);
    // console.log("context", context.attrs.msg);

    function testEmit() {
      context.emit("testEmit", "测试emit");
    }

    return {
      testEmit,
    };
  },
});
</script>

ref

  • 接受一个内部值并返回一个响应式且可变的 ref 对象。
<template>
  {{ count }}
  <button @click="add">加1</button>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const count = ref(1);

    function add() {
      count.value++;
    }

    return {
      count,
      add,
    };
  },
});
</script>
  • 另外一个用法,利用ref来自动获取焦点
<template>
  <div>
    文本框1:<input type="text" /> 文本框2:<input type="text" ref="value2" />
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";

export default defineComponent({
  setup() {
    const value2 = ref<HTMLElement | null>(null);

    onMounted(() => {
      value2.value && value2.value.focus();
    });

    return {
      value2,
    };
  },
});
</script>

reactive

  • 作用:定义多个数据的响应式
const proxy=reactive(obj):接收一个普通对象然后返回该普通对象的响应式代理器对象
  • 响应式转换是“深层的”:会影响对象内部所有的嵌套的属性
<template>
  <br />
  {{ person.name }}
  <button @click="changeName">改名</button>
</template>

<script lang="ts">
import { defineComponent, reactive } from "vue";

export default defineComponent({
  setup() {
    const person = reactive({
      name: "John",
    });

    function changeName() {
      person.name = "Steven";
    }

    return {
      person,
      changeName,
    };
  },
});
</script>

vue3新特性中的生命周期钩子函数

  • vue2对比vue3
<template>
  <div></div>
</template>

<script lang="ts">
import { defineComponent, onBeforeMount, onMounted } from "vue";

export default defineComponent({
  setup() {
    onBeforeMount(() => {
      console.log("vue3生命周期onBeforeMount");
    });

    onMounted(() => {
      console.log("vue3生命周期onMounted");
    });

    return {};
  },

  beforeMount() {
    console.log("vue2生命周期beforeMount");
  },

  mounted() {
    console.log("vue2生命周期beforeMount");
  },
});
</script>
  • 控制台
vue3生命周期onBeforeMount
vue2生命周期beforeMount
vue3生命周期onMounted
vue2生命周期beforeMount

vue3中computed(计算属性)

注意:两种写法

<template>
  姓:<input type="text" v-model="firstName" /><br />
  名:<input type="text" v-model="lastName" /><br />
  姓名:<input type="text" v-model="name" />
</template>

<script lang="ts">
import { computed, defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const firstName = ref<string>("");
    const lastName = ref<string>("");
    // 使用 getter 函数,返回的值返回一个不变的响应式 ref 对象。
    // const name = computed(() => {
    //   return firstName.value + lastName.value;
    // });
    // 使用具有 get 和 set 函数的对象来创建可写的 ref 对象。
    const name = computed({
      get: () => {
        return firstName.value + lastName.value;
      },
      set: () => {
        console.log("set");
      },
    });

    return {
      firstName,
      lastName,
      name,
    };
  },
});
</script>

vue3中watch(监听器)

  • vue3中watch的配置
watch:中的第一个参数监视源  count   第二个参数 回调函数 第三个参数watch配置项

第三个配置项中有两个参数
immediate:默认值为false, 开启后默认会执行一次watch
deep:开启深度监视
  • watch监听多个源
watch([参数一,参数二],()=>{});
<template>
  <div>{{ obj.name }}:{{ obj.age }}岁</div>
  <button @click="changeAge">长了一岁(测试watch)</button>
</template>

<script lang="ts">
import { defineComponent, reactive, watch } from "vue";

export default defineComponent({
  setup() {
    const obj = reactive({
      name: "Steven",
      age: 18,
    });

    function changeAge() {
      obj.age++;
    }

    watch(
      [obj],
      () => {
        console.log("又过了一年");
      },
      {
        immediate: true, // 默认值为false,开启后默认会执行一次watch,
        // deep:开启深度监视
      }
    );

    return {
      obj,
      changeAge,
    };
  },
});
</script>

vue3新特性中provide和inject

利用provide/inject实现跨层组件的信息通信

  • Grand.vue
<template>
  <p>{{ color }}</p>
  <button @click="changeColor('red')"></button>
  <button @click="changeColor('green')">绿</button>
  <button @click="changeColor('blue')"></button>
  <Son />
</template>

<script lang="ts">
import { defineComponent, provide, ref } from "vue";
import Son from "./Son.vue";

export default defineComponent({
  components: {
    Son,
  },

  setup() {
    const color = ref("red");
    provide("color", color);

    function changeColor(value) {
      color.value = value;
    }

    return {
      color,
      changeColor,
    };
  },
});
</script>
  • Son.vue
<template>
  <h1 :style="{ color }">Son组件</h1>
</template>

<script lang="ts">
import { defineComponent, inject, ref } from "vue";

export default defineComponent({
  setup() {
    const color = inject("color");

    return {
      color,
    };
  },
});
</script>