Vue3
01-初始 Setup
<template>
<div class="hello">
<h3>Setup</h3>
<span>姓名: {{ name }}</span>
<span>年龄: {{ age }}</span>
<div>
<button @click="sayHello">说Hello</button>
<button @click="Vue3ReadVue2">Vue3中读取Vue2的内容</button>
</div>
<hr />
<h3>data</h3>
<span>姓名: {{ nameData }}</span>
<span>年龄: {{ ageData }}</span>
<div>
<button @click="sayMethodHello">说Hello</button>
<button @click="Vue2ReadVue3">Vue2中读取Vue3的内容</button>
</div>
<!-- vue2 vue3 都有的时候,以 vue3 为准 -->
<p>{{ a }}</p>
</div>
</template>
<script>
import { h } from "vue";
export default {
name: "Setup",
// vue3 中不建议这么书写, 建议使用 setup
data() {
return {
nameData: "李四",
ageData: 15,
a: 300,
};
},
methods: {
sayMethodHello() {
alert(`我叫${this.nameData},年龄${this.ageData}, 你好啊`);
},
// vue2 可以读取到 vue3 setup里面的数据和方法
Vue2ReadVue3() {
alert(`我叫${this.name},年龄${this.age}, 你好啊`);
console.log(this.sayHello);
},
},
// 此处只是测试 setup 暂时不考虑响应式
setup() {
let name = "张三";
let age = 13;
let a = 200;
// 定义方法
function sayHello() {
alert(`我叫${name},年龄${age}, 你好啊`);
}
// vue3 不可以读取到 vue2 data methods 里面的数据和方法
function Vue3ReadVue2() {
alert(`我叫${nameData},年龄${ageData}, 你好啊`);
}
// 第一种,返回一个 对象,然后 template 就可以直接使用
return {
name,
age,
sayHello,
Vue3ReadVue2,
};
// 第二种, 返回一个渲染函数,会把 template 全部替换掉
// return () => h('h3', '说Hello')
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
main.js
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.mount("#app");
02-ref 函数
<template>
<div class="hello">
<h3>个人信息</h3>
<h4>姓名: {{ name }}</h4>
<h4>年龄: {{ age }}</h4>
<h4>工作类型: {{ job.type }}</h4>
<h4>工作薪水: {{ job.money }}</h4>
<button @click="changeInfo">修改个人信息</button>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "App",
setup() {
let name = ref("张三");
let age = ref(13);
let job = ref({
type: "web",
money: "30K",
});
// 方法
function changeInfo() {
// 基本数据类型
name.value = "李四";
age.value = 14;
console.log(name);
// name 引用对象
// RefImpl : {
// "__v_isShallow": false,
// "dep": {
// "w": 0,
// "n": 0
// },
// "__v_isRef": true,
// "_rawValue": "张三",
// "_value": "张三",
// "value": "张三",
// }
// 引用数据类型
job.value.type = "UI";
job.value.money = "25K";
console.log(job);
// job 引用对象
// RefImpl: {
// "__v_isShallow": false,
// "dep": {
// "w": 0,
// "n": 0
// },
// "__v_isRef": true,
// "_rawValue": {
// "type": "UI",
// "money": "25K"
// },
// "_value": {
// "type": "UI",
// "money": "25K"
// }
// "value" : Proxy(Object) ---> Proxy
// }
}
return {
name,
age,
job,
changeInfo,
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
03-reactive 函数
<template>
<div class="hello">
<h3>个人信息</h3>
<h4>姓名: {{ person.name }}</h4>
<h4>年龄: {{ person.age }}</h4>
<h4>工作类型: {{ person.job.type }}</h4>
<h4>工作薪水: {{ person.job.money }}</h4>
<h4>深层次对象C: {{ person.job.a.b.c }}</h4>
<h4>数组爱好: {{ person.hobby }}</h4>
<button @click="changeInfo">修改个人信息</button>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "App",
setup() {
let person = reactive({
name: "张三",
age: 13,
job: {
type: "web",
money: "30K",
a: { b: { c: 10 } },
},
// 按照下标修改数据也支持了
hobby: ["吃饭", "睡觉", "打游戏"],
});
// 方法
function changeInfo() {
// 基本数据类型
person.name = "李四";
person.age = 14;
person.job.type = "UI";
person.job.money = "60K";
person.job.a.b.c = 11;
person.hobby[1] = "打架";
}
return { person, changeInfo };
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
04-Vue3 响应式原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let person = {
name: "Tom",
age: 12,
};
const p = new Proxy(person, {
get(target, propName) {
console.log(`有人 读取 了P身上的属性: ${propName}`);
return Reflect.get(target, propName);
},
set(target, propName, value) {
console.log(`有人 修改 了P身上的属性: ${propName}`);
Reflect.set(target, propName, value);
},
deleteProperty(target, propName, value) {
console.log(`有人 删除 了P身上的属性: ${propName}`);
return Reflect.defineProperty(target, propName);
},
});
</script>
</body>
</html>
05-props_slots_emit
05-props_slots_emit\App.vue
<template>
<div class="hello">
<Demo @showHello="showHello" six="男" message="吃饭吧">
<template v-slot:lgq>
<div>我是父组件插槽</div>
</template>
</Demo>
</div>
</template>
<script>
import Demo from "./Demo.vue";
export default {
name: "App",
components: { Demo },
setup() {
function showHello(val) {
alert(val);
}
return {
showHello,
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
05-props_slots_emit\Demo.vue
<template>
<div class="hello">
<h3>个人信息</h3>
<h4>姓名: {{ person.name }}</h4>
<h4>年龄: {{ person.age }}</h4>
<button @click="showHello">触发Demo的Hello事件</button>
<slot name="lgq"></slot>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "Demo",
props: ["six", "message"],
emits: ["showHello"], // vue3 的 emit 事件需要在子组件的这里定义一下
// setup 比 beforeCreate 先执行
setup(props, context) {
console.log(props); // 可以直接接收到 props ---> Proxy(Object) {six: '男', message: '吃饭吧'}
console.log(context.attrs); // 相当于 vue2 的 $attrs
// 父组件 这个写法就可以拿到 slots 了 v-slot:lgq
console.log(context.slots);
console.log("------first------");
let person = reactive({
name: "张三",
age: 13,
});
function showHello() {
context.emit("showHello", "showHello事件被Demo触发了");
}
return { person, showHello };
},
beforeCreate() {
console.log("------second------");
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
06-computed
<template>
<div class="hello">
<h3>个人信息</h3>
姓氏: <input type="text" v-model="person.firstName" /><br />
名字: <input type="text" v-model="person.lastName" /><br />
全名: <input type="text" v-model="person.fullname" />
<h4>姓氏: {{ person.firstName }}</h4>
<h4>名字: {{ person.lastName }}</h4>
<h4>全名: {{ person.fullname }}</h4>
</div>
</template>
<script>
import { reactive, computed } from "vue";
export default {
name: "Demo",
// 不要写Vue2的计算属性
// computed: {
// fullname() {
// return this.person.firstName + "-" + this.person.lastName;
// },
// },
setup() {
let person = reactive({
firstName: "张",
lastName: "三",
});
// 计算属性(简写,不考虑计算属性被修改的形式)
// person.fullname = computed(() => {
// return person.firstName + "-" + person.lastName;
// });
// 计算属性(完整写法,不考虑计算属性被修改的形式)
person.fullname = computed({
get() {
return person.firstName + "-" + person.lastName;
},
set(value) {
const nameArr = value.split("-");
person.firstName = nameArr[0];
person.lastName = nameArr[1];
},
});
return { person };
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
07-watch 函数
<template>
<div class="hello">
<h2>当前求和为: {{ sum }}</h2>
<button @click="sum += 1">点我加 1</button>
<hr />
<input type="text" v-model="msg" />
<hr />
<span>{{ person.name }}</span>
<span>-----</span>
<span>{{ person.age }}</span>
<span>-----</span>
<span>{{ person.job.j1.money }}</span> <span>K</span>
<div>
<button @click="person.name += 1">改变名字</button>
<button @click="person.age += 1">改变年龄</button>
<button @click="person.job.j1.money += 1">改变薪资</button>
</div>
<hr />
</div>
</template>
<script>
import { ref, watch, reactive } from "vue";
export default {
name: "Demo",
// Vue2监听
// watch: {
// // 简写,
// // sum(newValue, oldValue) {
// // console.log('sum变化了',newValue, oldValue);
// // },
// // 全写
// // sum: {
// // deep: true,
// // immediate: true,
// // handler(newValue, oldValue) {
// // console.log('sum变化了',newValue, oldValue);
// // },
// // },
// },
setup() {
let sum = ref(0);
let msg = ref("hello");
let person = reactive({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
// Vue3监听;
// 情况一: 监听 ref 定义的一个数据
// watch(
// sum,
// (newValue, oldValue) => {
// console.log("sum变化了", newValue, oldValue); // sum变化了 1 0
// },
// {
// immediate: true,
// }
// );
// 情况二: 监听 ref 定义的多个数据
// watch(
// [sum, msg],
// (newValue, oldValue) => {
// console.log("sum或者msg变化了", newValue, oldValue); // sum变化了 (2) [1, 'hello'] (2) [0, 'hello']
// },
// {
// immediate: true,
// }
// );
// 情况三: 监听 reactive 定义的响应式数据
// 注意1: 无法正确拿到 newValue, oldValue
// 注意2: 强制开启了深度检测,deep: false,也没用
// watch(
// person,
// (newValue, oldValue) => {
// console.log("person 变化了", newValue, oldValue); // sum变化了 (2) [1, 'hello'] (2) [0, 'hello']
// },
// {
// immediate: true,
// deep: false, // 此处的deep无效
// }
// );
// 情况四: 监听 reactive 定义的响应式数据中的某一个属性
// watch(
// () => person.name, // 检测某一个属性需要写成函数的形式
// (newValue, oldValue) => {
// console.log("name 变化了", newValue, oldValue); // sum变化了 (2) [1, 'hello'] (2) [0, 'hello']
// },
// {
// immediate: true,
// }
// );
// 情况五: 监听 reactive 定义的响应式数据中的某些属性
// watch(
// [() => person.name, () => person.age], // 检测某一个属性需要写成函数的形式
// (newValue, oldValue) => {
// console.log("name 或者 age 变化了", newValue, oldValue); // sum变化了 (2) [1, 'hello'] (2) [0, 'hello']
// },
// {
// immediate: true,
// }
// );
// 特殊情况: 监听一个对象,却修改对象深层里的数据,那么这个时候需要开启 deep: true
watch(
() => person.job, // 检测某一个属性需要写成函数的形式
(newValue, oldValue) => {
console.log("job 变化了", newValue, oldValue); // sum变化了 (2) [1, 'hello'] (2) [0, 'hello']
},
{
immediate: true,
deep: true,
}
);
return { sum, msg, person };
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
09-watch 监听是否加 value
<template>
<div class="hello">
<h2>当前求和为: {{ sum }}</h2>
<button @click="sum += 1">点我加 1</button>
<hr />
<input type="text" v-model="msg" />
<hr />
<span>{{ person.name }}</span>
<span>-----</span>
<span>{{ person.age }}</span>
<span>-----</span>
<span>{{ person.job.j1.money }}</span> <span>K</span>
<div>
<button @click="person.name += 1">改变名字</button>
<button @click="person.age += 1">改变年龄</button>
<button @click="person.job.j1.money += 1">改变薪资</button>
</div>
<hr />
</div>
</template>
<script>
import { ref, watch, reactive } from "vue";
export default {
name: "Demo",
setup() {
let sum = ref(0);
let msg = ref("hello");
let person = ref({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
// 监听 ref 定义的一个数据,不能加value,加了value就是常亮了
watch(
sum,
(newValue, oldValue) => {
console.log("sum变化了", newValue, oldValue);
},
{
immediate: false,
}
);
// person 这个是一个对象,里面很多数据,也不能加 value
// person.value 的意思就是监视的 reactive 创建的深度对象,这样就可以拿到 oldvalue
watch(
person,
(newValue, oldValue) => {
console.log("person变化了", newValue, oldValue);
},
{
deep: true,
}
);
return { sum, msg, person };
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
10-watchEffect
<template>
<div class="hello">
<h2>当前求和为: {{ sum }}</h2>
<button @click="sum += 1">点我加 1</button>
<hr />
<input type="text" v-model="msg" />
<hr />
<span>{{ person.name }}</span>
<span>-----</span>
<span>{{ person.age }}</span>
<span>-----</span>
<span>{{ person.job.j1.money }}</span> <span>K</span>
<div>
<button @click="person.name += 1">改变名字</button>
<button @click="person.age += 1">改变年龄</button>
<button @click="person.job.j1.money += 1">改变薪资</button>
</div>
<hr />
</div>
</template>
<script>
import { ref, watch, reactive, watchEffect } from "vue";
export default {
name: "Demo",
setup() {
let sum = ref(0);
let msg = ref("hello");
let person = reactive({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
// watch 监听
// watch(
// sum,
// (newValue, oldValue) => {
// console.log("sum变化了", newValue, oldValue);
// },
// {
// immediate: true,
// }
// );
// watchEffect监听,监视器中用到了哪个数据,就监视他
watchEffect(() => {
const x1 = sum.value;
const x2 = person.job.j1.money;
console.log("watchEffect监听上来就会执行一次,默认 immediate为true");
console.log(sum);
});
return { sum, msg, person };
},
};
</script>
11-生命周期
<template>
<div class="hello">
<h2>当前求和为: {{ sum }}</h2>
<button @click="sum += 1">点我加 1</button>
<hr />
</div>
</template>
<script>
import {
ref,
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
} from "vue";
export default {
name: "Demo",
setup() {
let sum = ref(0);
// 通过组合式API的形式书写生命周期 (比配置项的形式书写生命周期快一些)
// beforeCreate() created(),就直接书写在 setup 里面即可
onBeforeMount(() => {
console.log("----01-onBeforeMount----");
});
onMounted(() => {
console.log("----02-onMounted----");
});
onBeforeUpdate(() => {
console.log("----03-onBeforeUpdate----");
});
onUpdated(() => {
console.log("----04-onUpdated----");
});
onBeforeUnmount(() => {
console.log("----05-onBeforeUnmount----");
});
onUnmounted(() => {
console.log("----06-onUnmounted----");
});
return { sum };
},
// 通过配置项的形式书写生命周期
// beforeCreate(){
// console.log('----01-beforeCreate----');
// },
// created(){
// console.log('----02-created----');
// },
// beforeMount(){
// console.log('----03-beforeMount----');
// },
// mounted(){
// console.log('----04-mounted----');
// },
// beforeUpdate(){
// console.log('----05-beforeUpdate----');
// },
// updated(){
// console.log('----06-updated----');
// },
// beforeUnmount(){
// console.log('----07-beforeUnmount----');
// },
// unmounted(){
// console.log('----08-unmounted----');
// }
};
</script>
12-自定义 hook 函数
12-自定义 hook 函数\App.vue
<template>
<div class="hello">
<button @click="isShowDemo = !isShowDemo">切换显示隐藏</button>
<Demo v-if="isShowDemo" />
</div>
</template>
<script>
import { ref } from "vue";
import Demo from "./Demo.vue";
export default {
name: "App",
components: { Demo },
setup() {
let isShowDemo = ref(true);
return { isShowDemo };
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
12-自定义 hook 函数\Demo.vue
<template>
<div class="hello">
<h2>当前求和为: {{ sum }}</h2>
<button @click="sum += 1">点我加 1</button>
<hr />
<h2>当前点击的坐标为{{ point.x }},{{ point.y }}</h2>
</div>
</template>
<script>
import { ref } from "vue";
import usePoint from "./hooks/usePoint";
export default {
name: "Demo",
setup() {
let sum = ref(0);
let point = usePoint();
return { sum, point };
},
};
</script>
12-自定义 hook 函数\hooks\usePoint.js
import { onBeforeUnmount, onMounted, reactive } from "vue";
export default function savePoint() {
let point = reactive({
x: 0,
y: 0,
});
function savePoint(event) {
console.log(event);
point.x = event.x;
point.y = event.y;
}
onMounted(() => {
window.addEventListener("click", savePoint);
});
onBeforeUnmount(() => {
window.removeEventListener("click", savePoint);
});
return point;
}
13-toRef toRefs
<template>
<div class="hello">
<h4>{{ person }}</h4>
<span>{{ name }}</span>
<span>-----</span>
<span>{{ age }}</span>
<span>-----</span>
<span>{{ job.j1.money }}</span> <span>K</span>
<div>
<button @click="name += 1">改变名字</button>
<button @click="age += 1">改变年龄</button>
<button @click="job.j1.money += 1">改变薪资</button>
</div>
<hr />
</div>
</template>
<script>
import { reactive, toRef, toRefs } from "vue";
export default {
name: "Demo",
setup() {
let person = reactive({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
return {
person,
// toRefs 快捷把所有数据都 toRef
...toRefs(person),
// name: toRef(person, "name"),
// age: toRef(person, "age"),
// money: toRef(person.job.j1, "money"),
// 这样的写法就会导致修改的时候 person 里面的数据不会改,
// 因为你是把这个值取出来,把他搞成了 ref
// name: toRef(person.name),
// age: toRef(person.age),
// money: toRef(person.job.j1.money),
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
14-shallowReactive 和 shallowRef
<template>
<div class="hello">
<h4>当前x值为{{ x.y }}</h4>
<button @click="x.y += 1">x+1</button>
<hr />
<h4>{{ person }}</h4>
<span>{{ name }}</span>
<span>-----</span>
<span>{{ age }}</span>
<span>-----</span>
<span>{{ job.j1.money }}</span> <span>K</span>
<div>
<button @click="name += 1">改变名字</button>
<button @click="age += 1">改变年龄</button>
<button @click="job.j1.money += 1">改变薪资</button>
</div>
<hr />
</div>
</template>
<script>
import { reactive, toRefs, shallowReactive, shallowRef, ref } from "vue";
export default {
name: "Demo",
setup() {
// shallowReactive 只处理对象最外层属性的响应式(浅响应式).
// let person = shallowReactive({
let person = reactive({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
// shallowRef 只处理基本数据类型的响应式, 不进行对象的响应式处理.
let x = ref(0);
// let x = shallowRef({
// y: 0,
// });
console.log(x);
return {
person,
x,
...toRefs(person),
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
15-readonly 和 shallowReadonly
<template>
<div class="hello">
<h4>当前求和为{{ sum }}</h4>
<button @click="sum++">点我++</button>
<hr />
<h4>{{ person }}</h4>
<span>{{ name }}</span>
<span>-----</span>
<span>{{ age }}</span>
<span>-----</span>
<span>{{ job.j1.money }}</span> <span>K</span>
<div>
<button @click="name += 1">改变名字</button>
<button @click="age += 1">改变年龄</button>
<button @click="job.j1.money += 1">改变薪资</button>
</div>
<hr />
</div>
</template>
<script>
import { reactive, toRefs, readonly, shallowReadonly, ref } from "vue";
export default {
name: "Demo",
setup() {
let person = reactive({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
// readonly 让一个响应式数据变为只读的(深只读).
// person = readonly(person);
// shallowReadonly 让一个响应式数据变为只读的(浅只读).
person = shallowReadonly(person);
let sum = ref(0);
sum = readonly(sum);
return {
sum,
...toRefs(person),
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
16-toRaw 和 markRaw
<template>
<div class="hello">
<h4>当前求和为{{ sum }}</h4>
<button @click="sum++">点我++</button>
<hr />
<span>{{ name }}</span>
<span>-----</span>
<span>{{ age }}</span>
<span>-----</span>
<span>{{ job.j1.money }}</span> <span>K</span>
<span>-----</span>
<span>{{ person.car }}</span>
<br />
<button @click="name += 1">改变名字</button>
<button @click="age += 1">改变年龄</button>
<button @click="job.j1.money += 1">改变薪资</button>
<br />
<button @click="addCar">给人添加一台车</button>
<button @click="person.car.name += 1">换车名</button>
<button @click="person.car.price += 1">换价格</button>
<hr />
</div>
</template>
<script>
import { reactive, toRefs, ref, toRaw, markRaw } from "vue";
export default {
name: "Demo",
setup() {
let person = reactive({
name: "TOM",
age: 12,
job: {
j1: {
money: 13,
},
},
});
let sum = ref(0);
// toRaw 将一个由reactive生成的对象变为不具有响应式的原始对象
// person = toRaw(person);
function addCar() {
let car = { name: "BMW", price: "50W" };
// markRaw 标记一个对象,使其永远不会再成为响应式对象.
// 数据是变化了,仅仅是因为不具有响应式,页面不会更新了
person.car = markRaw(car);
}
return {
sum,
person,
addCar,
...toRefs(person),
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
17-customRef
<template>
<input type="text" v-model="keyword" />
<h3>{{ keyword }}</h3>
</template>
<script>
import { ref, customRef } from "vue";
export default {
name: "App",
setup() {
// 自定义ref myRef
function myRef(value, delay) {
let timer;
return customRef((track, trigger) => {
return {
get: () => {
console.log(`有人读取了 myRef 中数据 我把 ${value} 给他了`);
track(); // 告诉vue这个值需要追踪 value 这个数据的变化
return value;
},
set: (newValue) => {
console.log(`有人修改了 myRef 中数据 改为了: ${newValue} `);
value = newValue;
clearTimeout(timer);
timer = setTimeout(() => {
trigger(); // 通知vue去重新解析模板,这样视图就会重新读取数据,那么就会重新走 get,
}, delay);
},
};
});
}
// let keyword = ref("hello"); // 使用 vue 提供的内置 ref
let keyword = myRef("hello", 500); // 使用 开发者 自己定义的 ref
return {
keyword,
};
},
};
</script>
<style>
#app {
text-align: center;
}
</style>
18-provide 和 inject
18-provide 和 inject\App.vue
<template>
<div class="App">
<h2>我是 App----{{ name }}----{{ price }}</h2>
<Child />
</div>
</template>
<script>
import Child from "./components/Child.vue";
import { provide, reactive, toRefs } from "vue";
export default {
name: "App",
components: { Child },
setup() {
let car = reactive({
name: "BMW",
price: "10k",
});
provide("car", car);
return {
...toRefs(car),
};
},
};
</script>
<style>
.App {
padding: 10px;
background-color: rgb(207, 90, 180);
}
</style>
18-provide 和 inject\components\Child.vue
<template>
<div class="Child">
<h2>我是 Child</h2>
<Son />
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
name: "Child",
components: { Son },
};
</script>
<style>
.Child {
padding: 10px;
background-color: yellow;
}
</style>
18-provide 和 inject\components\Son.vue
<template>
<div class="Son">
<h2>我是 Son-----{{ car.name }}----{{ car.price }}</h2>
</div>
</template>
<script>
import { inject } from "vue";
export default {
name: "Son",
setup() {
let car = inject("car");
return { car };
},
};
</script>
<style>
.Son {
background-color: rgb(91, 187, 147);
padding: 10px;
}
</style>
19-响应式数据的判断
<template>
<div class="App">
<h2>我是 App----{{ name }}----{{ price }}</h2>
</div>
</template>
<script>
import {
reactive,
readonly,
ref,
toRefs,
isRef,
isReactive,
isReadonly,
isProxy,
} from "vue";
export default {
name: "App",
setup() {
let sum = ref(0);
let car = reactive({
name: "BMW",
price: "10k",
});
let car2 = readonly(car);
// - isRef: 检查一个值是否为一个 ref 对象
console.log(isRef(sum)); // true
// - isReactive: 检查一个对象是否是由 `reactive` 创建的响应式代理
console.log(isReactive(car)); // true
// - isReadonly: 检查一个对象是否是由 `readonly` 创建的只读代理
console.log(isReadonly(car2)); // true
// - isProxy: 检查一个对象是否是由 `reactive` 或者 `readonly` 方法创建的代理
console.log(isProxy(car)); // true
console.log(isProxy(sum)); // false
return {
...toRefs(car),
};
},
};
</script>
<style>
.App {
padding: 10px;
background-color: rgb(207, 90, 180);
}
</style>
20-teleport 组件
20-teleport 组件\App.vue
<template>
<div>
<button @click="isShow = true">点我弹窗</button>
<teleport to="body">
<div class="mask" v-if="isShow">
<div class="dialog">
<h4>我是弹窗内容</h4>
<h4>我是弹窗内容</h4>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
</teleport>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "Dialog",
setup() {
let isShow = ref(false);
return { isShow };
},
};
</script>
<style>
.mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.dialog {
width: 200px;
height: 200px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #ffffff;
border-radius: 4px;
padding: 10px;
}
</style>
21-Suspense 组件
21-Suspense 组件\App.vue
<template>
<div class="Child">
<h2>我是 Child</h2>
<h3>{{ sum }}</h3>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "Child",
async setup() {
let sum = ref(0);
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ sum });
}, 1000);
});
return await p;
},
};
</script>
<style>
.Child {
padding: 10px;
background-color: yellow;
}
</style>
21-Suspense 组件\components\Child.vue
<template>
<div class="Child">
<h2>我是 Child</h2>
<h3>{{ sum }}</h3>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "Child",
async setup() {
let sum = ref(0);
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ sum });
}, 1000);
});
return await p;
},
};
</script>
<style>
.Child {
padding: 10px;
background-color: yellow;
}
</style>