Options API的弊端
大组件的逻辑分散
认识Composition API
setup函数的参数
setup函数的返回值
setup不可以使用this
App.vue
<template>
<div>
<home message="hahahaha" id="aaa" class="bbbb"></home>
</div>
</template>
<script>
import Home from "./Home.vue";
export default {
components: {
Home,
},
};
</script>
<style scoped></style>
02_setup的参数.vue
<template>
<div>
<h3>Home Page</h3>
<h3>{{ message }}</h3>
<h2>{{ title }}</h2>
<h2>当前计数: {{ counter }}</h2>
<button @click="increment">+1</button>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true,
},
},
data() {
return {
counter: 100,
};
},
/**
* 参数一: props, 父组件传递过来属性
*/
// setup函数有哪些参数?
// setup函数有什么样的返回值
// setup(props, context) {
setup(props, { attrs, slots, emit }) {
console.log(props.message);
console.log(attrs.id, attrs.class);
console.log(slots);
console.log(emit);
return {
title: "Hello Home",
counter: 100,
};
},
methods: {
btnClick() {
this.$emit("");
},
},
};
</script>
<style scoped></style>
03_setup的返回值.vue
<template>
<div>
Home Page
<h2>{{ message }}</h2>
<h2>{{ title }}</h2>
<h2>当前计数: {{ counter }}</h2>
<button @click="increment">+1</button>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true,
},
},
setup() {
let counter = 100;
// 局部函数
const increment = () => {
counter++;
console.log(counter);
};
return {
title: "Hello Home",
counter,
increment,
};
},
};
</script>
<style scoped></style>
Reactive API
04_reactiveAPI使用.vue
<template>
<div>
Home Page
<h2>{{ message }}</h2>
<h2>当前计数: {{ state.counter }}</h2>
<button @click="increment">+1</button>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
props: {
message: {
type: String,
required: true,
},
},
setup() {
const state = reactive({
counter: 100,
});
// 局部函数
const increment = () => {
state.counter++;
console.log(state.counter);
};
return {
state,
increment,
};
},
};
</script>
<style scoped></style>
Ref API
Ref自动解包
05_refAPI使用.vue
<template>
<div>
Home Page
<h2>{{ message }}</h2>
<!-- 当我们在template模板中使用ref对象, 它会自动进行解包 -->
<h2>当前计数: {{ counter }}</h2>
<button @click="increment">+1</button>
<show-message :message="counter"></show-message>
</div>
</template>
<script>
import { ref } from "vue";
export default {
props: {
message: {
type: String,
required: true,
},
},
setup() {
// counter编程一个ref的可响应式的引用
// counter = 100;
let counter = ref(100);
// 局部函数
const increment = () => {
counter.value++;
console.log(counter.value);
};
return {
counter,
increment,
};
},
};
</script>
<style scoped></style>
06_ref的浅层解包.vue
<template>
<div>
Home Page
<h2>{{ message }}</h2>
<!-- 当我们在template模板中使用ref对象, 它会自动进行解包 -->
<h2>当前计数: {{ counter }}</h2>
<!-- ref的解包只能是一个浅层解包(info是一个普通的JavaScript对象) -->
<h2>当前计数: {{ info.counter.value }}</h2>
<!-- 当如果最外层包裹的是一个reactive可响应式对象, 那么内容的ref可以解包 -->
<h2>当前计数: {{ reactiveInfo.counter }}</h2>
<button @click="increment">+1</button>
</div>
</template>
<script>
import { ref, reactive } from "vue";
export default {
props: {
message: {
type: String,
required: true,
},
},
setup() {
let counter = ref(100);
const info = {
counter,
};
const reactiveInfo = reactive({
counter,
});
// 局部函数
const increment = () => {
counter.value++;
console.log(counter.value);
};
return {
counter,
info,
reactiveInfo,
increment,
};
},
};
</script>
<style scoped></style>
认识readonly
readonly的使用
readonly.vue
<template>
<div>
<!-- 下面3行, 加的 -->
<div>{{ info1.name }}</div>
<div>{{ info2.name }}</div>
<div>{{ info3 }}</div>
<button @click="updateState">修改状态</button>
</div>
</template>
<script>
import { reactive, ref, readonly } from "vue";
export default {
setup() {
// 1.普通对象
const info1 = { name: "why" };
const readonlyInfo1 = readonly(info1);
// 2.响应式的对象reactive
const info2 = reactive({
name: "why",
});
const readonlyInfo2 = readonly(info2);
// 3.响应式的对象ref
const info3 = ref("why");
const readonlyInfo3 = readonly(info3);
const updateState = () => {
// 【不允许这样修改】
// readonlyInfo3.value = "hahaha"
info3.value = "hahaha";
};
return {
// 下面3行, 加的
info1,
info2,
info3,
updateState,
};
},
};
</script>
<style scoped></style>
Reactive判断的API
Reactive判断的API.vue
<template>
<div></div>
</template>
<script>
import {
reactive,
readonly,
isProxy,
isReadonly,
isReactive,
} from "vue";
export default {
setup() {
const obj = { name: "杰", age: 18, friends: { name: "哈哈", age: 66 } };
const info1 = reactive(obj);
const info2 = readonly(obj);
console.log(isProxy(info1), isProxy(info2)); // true true
console.log(isReadonly(info1), isReadonly(info2)); // false true
console.log(isReactive(info1), isReactive(info2)); // true false
},
};
</script>
<style scoped></style>
toRefs
toRef
01_toRefs和toRef的使用.vue
<template>
<div>
<h2>{{ name }}-{{ age }}</h2>
<button @click="changeAge">修改age</button>
</div>
</template>
<script>
import { reactive, toRefs, toRef } from "vue";
export default {
setup() {
const info = reactive({ name: "why", age: 18 });
// 1.toRefs:将reactive对象中的所有属性都转成ref,建立链接【传入reactive对象】
// let { name, age } = toRefs(info);
// 2.toRef: 对其中一个属性进行转换ref, 建立链接
let { name } = info;
let age = toRef(info, "age"); // toRef返回一个ref值,不能解构age
const changeAge = () => {
age.value++;
};
return {
name,
age,
changeAge,
};
},
};
</script>
<style scoped></style>
ref其他的API
02_refAPI的补充.vue
<template>
<div>
<h2>{{ info }}</h2>
<button @click="changeInfo">修改Info</button>
</div>
</template>
<script>
import { ref, shallowRef, triggerRef } from "vue";
export default {
setup() {
const res = ref({ name: "杰11", age: 18 });
console.log(res.value.name); // 杰11
console.log(unref(res).name); // 杰11
// 这种是深层的响应式 【深层:对象里的属性也是响应式的,浅层:对象里的属性不是响应式的,需要triggerRef触发才能能变成响应式。】
// const info = ref({name: "why"})
const info = shallowRef({ name: "why" });
const changeInfo = () => {
// 【注意,是info.value.name,不是info.name.value】
info.value.name = "james";
// 【副作用:比如页面响应式更新数据。】
triggerRef(info);
};
return {
info,
changeInfo,
};
},
};
</script>
<style scoped></style>
customRef【了解】