1.computed的基本使用
<template>
<div>
<!-- 1.直接显示,这种拼接是可以实现响应式 -->
<h1>{{ lastName }} {{ fristName }}</h1>
<hr />
<!-- 2. 拼接的方式显示 ---这种拼接的不是响应式的 -->
<h1>{{ fullName }}</h1>
<!-- 3. setup中使用computed可以实现响应式 一 get函数的使用 -->
<h1>{{ fullsNameOne }}</h1>
<button @click="changeName">改变姓名</button>
</div>
</template>
<script>
import { ref, computed } from "vue";
export default {
// vue 2.0的写法
// computed: {}
setup() {
const fristName = ref("zhenchu");
const lastName = ref("hu");
// 2.这种拼接的不是响应式的
const fullName = lastName.value + " " + fristName.value;
// 3. 在setup中使用计算属性,这个地方直接对应的是一个get 使用方式一 get函数的使用
const fullsNameOne = computed(() => lastName.value + " " + fristName.value);
const changeName = () => {
lastName.value = "wang";
};
return {
fristName,
lastName,
fullName,
fullsNameOne,
changeName,
};
},
};
</script>
<style>
</style>
实际截图
image.png
2. computed对象的使用
<template>
<div>
<!-- 4. setup中使用computed可以实现响应式 二 对象的使用 -->
<h1>{{ fullsNameTwo }}</h1>
<button @click="changeName">改变姓名</button>
</div>
</template>
<script>
import { ref, computed } from "vue";
export default {
setup() {
const fristName = ref("zhenchu");
const lastName = ref("hu");
// 1. 在setup中使用计算属性,这个地方直接对应的是一个get 使用方式二 对象的使用 对象包含getter/setter
const fullsNameTwo = computed({
get: () => lastName.value + " " + fristName.value,
set(newValue) {
console.log(newValue);
const names = newValue.split(" ");
console.log(names);
fristName.value = names[0];
lastName.value = names[1];
},
});
const changeName = () => {
fullsNameTwo.value = "coder hu";
};
return {
fullsNameTwo,
changeName,
};
},
};
</script>
<style>
</style>
实际截图
image.png
3. watch侦听器-watchEffect的基本使用
<template>
<div>
<h1>{{ names }} -- {{ age }}</h1>
<button @click="changeName">修改name</button>
<button @click="changeAge">修改age</button>
</div>
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
// watchEffect用于自动收集响应式数据的依赖;
setup() {
const names = ref("hzc");
const age = ref(18);
const changeName = () => (names.value = "wang");
const changeAge = () => age.value++;
// 需求: 我现在想监听 names 和age的发生的变化: 方式一: 使用watchEffect函数
/**
* PS: 注意watchEffect回调函数: 默认在第一次不管三七二十会先执行一次的,
* 因为这个函数会在刚开始的时候就是立即执行一次,他会先观察那些数据是响应式的数据
*
* **/
watchEffect(() => {
console.log("names:", names.value);
console.log("age:", age.value);
});
return {
names,
age,
changeName,
changeAge,
};
},
};
/**
* ps: 当侦听到某些响应式数据变化时,我们希望执行某些操作,这个时候可以使用 watchEffect。
* -- 首先,watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;
* -- 其次,只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行;
*
* **/
</script>
<style>
</style>
实际截图
image.png
4.watchEffect的停止侦听
<template>
<div>
<h1>{{ names }} -- {{ age }}</h1>
<button @click="changeAgeMore20StopWatch">修改年纪大于20 停止侦听</button>
</div>
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
/**
* PS: 如果在发生某些情况下,我们希望停止侦听,这个时候我们可以获取watchEffect的返回值函数,调用该函数即可
* 当age达到20的时候就停止侦听:
*
*
* **/
setup() {
const names = ref("huzhenchu");
const age = ref(18);
// 当你在调用 watchEffect 这个函数的时候 他是有一个返回值的,他返回的是一个函数
const stopWatch = watchEffect(() => {
console.log("names:", names.value, "age:", age.value);
});
console.log(stopWatch); // stopWatch他是一个函数
const changeAgeMore20StopWatch = () => {
age.value++;
if(age.value > 25) stopWatch(); // 当age.value 大于25 以后 上面侦听器中的打印不会再执行了, 但是html中的年纪是会变化的
};
return {
names,
age,
changeAgeMore20StopWatch,
};
},
};
</script>
<style>
</style>
实际截图
image.png
5. watchEffect清除副作用
<template>
<div>
<h1>{{ names }} -- {{ age }}</h1>
<button @click="changeAgeMore20StopWatch">修改年纪大于20 停止侦听</button>
</div>
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
/**
* PS: 什么是清除副作用呢?
* -- 比如在开发中我们需要在侦听函数中执行网络请求,但是在网络请求还没有请求回来的时候,
* 我们停止了侦听器,或者侦听器侦听函数被再次执行了。
* -- 那么上一次的网络请求应该被取消掉,这个时候我们就可以清除上一次的副作用;
*
*
* 1. 在我们给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate
* -- 当副作用即将重新执行 或者 侦听器被停止 时会执行该函数传入的回调函数;
* -- 我们可以在传入的回调函数中,执行一些清除工作;
* **/
setup() {
const names = ref("huzhenchu");
const age = ref(18);
// 在我们给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate 他本身也是一个回调函数
const stopWatch = watchEffect((onInvalidate) => {
// 根据names 和age 两个变量发送网络请求
const timer = setTimeout(() => {
console.log("300ms后执行的操作");
}, 300);
onInvalidate(() => {
// 在这个函数中清除额外的副作用
clearTimeout(timer);
});
console.log("names:", names.value, "age:", age.value);
});
const changeAgeMore20StopWatch = () => {
age.value++;
if (age.value > 25) stopWatch(); // 当age.value 大于25 以后 上面侦听器中的打印不会再执行了, 但是html中的年纪是会变化的
};
return {
names,
age,
changeAgeMore20StopWatch,
};
},
};
</script>
<style>
</style>
实际截图
image.png
6.setup中使用ref
<template>
<div>
<!-- 1.Vue2.0的获取方式: -->
<h1 ref="title">哈哈哈哈</h1>
<button @click="foo">获取h1标签的内容信息</button>
<hr />
<!-- 2.Vue3.0的获取方式:在setup中如何使用ref获取元素获取组件 -->
<h1 ref="setupTitle">嘿嘿嘿黑</h1>
<button @click="setupGetTitle">在setup中获取h1标签的内容信息</button>
<!-- 把获取到的值放入到 div盒子中 -->
<div class="context-box">{{ getH1InnerHTML }}</div>
</div>
</template>
<script>
import { ref } from "vue";
export default {
// 2.在setup中如何使用ref获取元素获取组件?
setup() {
const setupTitle = ref(null);
const getH1InnerHTML = ref();
const setupGetTitle = () => {
console.log(setupTitle.value.innerHTML); // 嘿嘿嘿黑
getH1InnerHTML.value = setupTitle.value.innerHTML;
};
return {
setupTitle,
getH1InnerHTML,
setupGetTitle,
};
},
// 1. 以前在Vue 2.0 中 获取一个html 的元素 或者 标签 一般是使用: this.$refs.xxx
methods: {
foo() {
console.log(this.$refs.title.innerHTML); // 哈哈哈哈
},
},
};
</script>
<style scoped>
.context-box {
width: 200px;
height: 200px;
background-color: pink;
color: red;
font-weight: bold;
margin-top: 10px;
text-align: center;
line-height: 180px;
font-size: 28px;
}
</style>
实际截图
image.png
7. setup中使用ref使用watchEffect来监听一
<template>
<div>
<!-- 2.Vue3.0的获取方式:在setup中如何使用ref获取元素获取组件 -->
<h1 ref="setupTitle">嘿嘿嘿黑</h1>
</div>
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
// 2.在setup中如何使用ref获取元素获取组件?
setup() {
const setupTitle = ref(null);
/**
* 我们会发现打印结果打印了两次:
* -- 这是因为setup函数在执行时就会立即执行传入的副作用函数,这个时候DOM并没有挂载,所以打印为null;
* -- 而当DOM挂载时,会给title的ref对象赋值新的值,副作用函数会再次执行,打印出来对应的元素;
* **/
watchEffect(() => {
console.log("setupTitle:", setupTitle.value);
});
return {
setupTitle,
};
},
};
</script>
<style>
</style>
实际截图
image.png
8. setup中使用ref使用watchEffect来监听二
<template>
<div>
<!-- 2.Vue3.0的获取方式:在setup中如何使用ref获取元素获取组件 -->
<h2 ref="setupTitle">嘿嘿嘿黑</h2>
</div>
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
setup() {
const setupTitle = ref(null);
/**
* 我们会发现打印结果打印了两次:
* -- 这是因为setup函数在执行时就会立即执行传入的副作用函数,这个时候DOM并没有挂载,所以打印为null;
* -- 而当DOM挂载时,会给title的ref对象赋值新的值,副作用函数会再次执行,打印出来对应的元素;
*
*
*
* 需求: 如果我们希望在第一次的时候就打印出来对应的元素呢?
* -- 这个时候我们需要改变副作用函数的执行时机;
* -- 它的默认值是pre,它会在元素 挂载 或者 更新 之前执行;
* -- 所以我们会先打印出来一个空的,当依赖的title发生改变时,就会再次执行一次,打印出元素;
*
* 我们可以设置副作用函数的执行时机:
* **/
watchEffect(() => {
console.log("setupTitle:", setupTitle.value);
},{
flush: "post" // sync:不推荐使用, pre: 提前执行, post: 希望demo 挂载完成以后 再执行
});
return {
setupTitle,
};
},
};
/**
* PS: watchEffect 第一个参数是: 回调函数;
* 第二个参数是: flush (flush 选项还接受 sync,这将强制效果始终同步触发。然而,这是低效的,应该很少需要)
*
* **/
</script>
<style>
</style>
实际截图
image.png
9.setup中使用-watch-reactive对象
<template>
<div>
<h2>{{info.name }}</h2>
<button @click="changeData">修改数据</button>
</div>
</template>
<script>
import { reactive, watch } from "vue";
export default {
/**
* Watch的使用:
* -- watch的API完全等同于组件watch选项的Property:
* -- watch需要侦听特定的数据源,并在回调函数中执行副作用;
* -- 默认情况下它是惰性的,只有当被侦听的源发生变化时才会执行回调;
*
* 区别:
* 与watchEffect的比较,watch允许我们:
* -- 懒执行副作用(第一次不会直接执行);
* -- 更具体的说明当哪些状态发生变化时,触发侦听器的执行;
* -- 访问侦听状态变化前后的值;
* **/
/**
* 侦听单个数据源:
* -- watch侦听函数的数据源有两种类型:
* -- 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
* -- 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
* **/
setup() {
const info = reactive({ name: "huzhenchu", age: 18 });
// 参数一: 监听的对象源头, 参数二: 回调函数
// reactive对象获取到的newValue和oldValue本身都是reactive对象
watch(info, (newValue, oldValue) => {
console.log("newValue:", newValue);
console.log("oldValue:", oldValue);
});
console.log(info);
const changeData = () => {
info.name = "chuchuhu";
};
return {
changeData,
info
};
},
};
</script>
<style>
</style>
实际截图
image.png
10. setup中使用-watch-单个数据的侦听
<template>
<div>
<h2>{{info.name }}</h2>
<button @click="changeData">修改数据</button>
</div>
</template>
<script>
import { reactive, watch } from "vue";
export default {
/**
* 侦听单个数据源:
* -- watch侦听函数的数据源有两种类型:
* -- 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
* -- 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
* **/
setup() {
const info = reactive({ name: "huzhenchu", age: 18 });
// 参数一: 监听的对象源头, 回调函数
watch(()=> info.name, (newValue, oldValue) => {
console.log("newValue:", newValue); // newValue: chuchuhu
console.log("oldValue:", oldValue); // oldValue: huzhenchu
});
// console.log(info);
const changeData = () => {
info.name = "chuchuhu";
};
return {
changeData,
info
};
},
};
</script>
<style>
</style>
实际截图
image.png
11.setup中使用-watch-ref对象
<template>
<div>
<h2>{{ name }}</h2>
<button @click="changeData">修改数据</button>
</div>
</template>
<script>
import { ref, watch } from "vue";
export default {
/**
* 侦听单个数据源:
* -- watch侦听函数的数据源有两种类型:
* -- 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
* -- 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
* **/
setup() {
const name = ref("chuchuhu");
watch(name, (newValue, oldValue) => {
console.log("newValue:", newValue);
console.log("oldValue:", oldValue);
});
const changeData = () => {
name.value = "guxiaohu"
};
return {
name,
changeData,
};
},
};
</script>
<style>
</style>
实际截图
image.png
12. setup中使用-watch-侦听多个数据源
<template>
<div>
<h1>{{ name }}</h1>
<button @click="changeName">修改名称</button>
</div>
</template>
<script>
import { reactive, ref, watch } from "vue";
export default {
setup() {
const name = ref("chuchuhu");
const info = reactive({ name: "guxiaohu", age: 18 });
const changeName = () => {
name.value = "楚楚胡";
};
// 侦听多个数据
watch([info, name], ([newInfo, newName], [oldInfo, oldName]) => {
console.log(newInfo);
console.log(newName);
console.log(oldInfo);
console.log(oldName);
});
return {
name,
changeName,
};
},
};
</script>
<style>
</style>
实际截图
image.png
13.setup中使用-watch-深度侦听
<template>
<div>
<h1>{{ info.friend.name }}</h1>
<button @click="changeName">修改名称</button>
</div>
</template>
<script>
import { reactive, ref, watch } from "vue";
export default {
setup() {
const info = reactive({
name: "guxiaohu",
age: 18,
friend: {
name: "Kobe",
},
});
// 1.侦听多个数据,这种默认是可以侦听的
// watch(info, (newValue, oldValue) => {
// console.log(newValue);
// console.log(oldValue);
// });
// 2.这种是不会默认侦听的,所以要加上第三个参数了他是一个对象
watch(()=> ({...info}),(newValue,oldValue)=> {
console.log(newValue,oldValue);
},{
deep:true, // 设置深度侦听
immediate: true // 设置这个的时候就是当你进来的第一次就会执行 里面的监听操作
})
const changeName = () => {
info.friend.name = "乔丹";
};
return {
info,
changeName,
};
},
};
</script>
<style>
</style>
实际截图
image.png
网友评论