搭建一个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>