一、Options API (选项式) 和 Composition API(组合式)
结合hooks:提供了一种在函数组件中共享逻辑和状态的方式。(契合组合式api)
例:
1.新建hooks文件夹,存放多个处理文件(js、ts)
import { onMounted , reactive } from "vue"; import axios from "axios"; export default function () { const dogList = reactive([ "https://images.dog.ceo//breeds//pembroke//n02113023_5881.jpg", ]); const getDog = async () => { try { let result = await axios.get( "https://dog.ceo/api/breed/pembroke/images/random" ); dogList.push(result.data.message); } catch (error) { alert(error); } }; onMounted(() => {}); return { dogList, getDog }; }
2.页面中处理
<script setup> import useDogs from "@/hooks/useDogs"; import useSum from "@/hooks/useSum"; const { dogList, getDog } = useDogs(); </script>
二、ref和reactive
ref : 1. 定义基本类型;2.对象类型的响应数据(底层实现逻辑还是借用reactive)
reactive : 只能定义对象类型的相应数据
区别:
reactive重新分配一个对象,会失去响应式(可以使用Object.assign替换整个对象的值)
例: let a = reactive( { id : '1', name : '11'}) ; Object.assion(a, {id : ' 2 ' , name : '22'}); => a被完全覆盖,替代成响应式,普通赋值不能成为响应式
用法:
1.若需要一个基本类型,使用ref;
2.若需要一个响应对象,层次不深,都行;
3.若需要一个响应对象,且层次较深,推荐reactive;
快捷(.value)
TypeScript Vue Plugin (Volar)
三、computed和watch
computed:(定义的值为ref属性)
1.只读
let fullname = computed(() => { return name.value + '-' + age.value}) // 不可强普通赋值和强制修改
2.可读可写
let fullname = computed({ get() { return name.value + '-' + age.value }, set(val) { // 监视当前值变化,更改相关值 } })
watch:
1.只能定义以下四种数据
① ref定义的数据 【基本数据、对象数据】
② reactive定义的数据【隐式开启深度监听】
③ 函数返回一个值(getter函数=>一个函数的返回值)
const person = reactive({
name:'1',
age:'2',
relation:{
sister:2,
brother:1
}
});
watch(() => person.name, (val) => { console.log('变化'); })
// 监视如果是对象里属性,最好函数式,若是对象监视的是地址(当前监听的是整个relation变化,内部变化不会关注),若需要关注对象内部,需手动开启深度监听,如不关注,只会监听 relation.sister和relation.brother
watch(() => person.relation, (val) => { console.log('变化'); },{deep:true}) // 最佳解决方案
④ 一个包含上述内容的数组
watch([()=>person.name,person.relation],()=>{ console.log('变化了‘); },{deep:true})
注:deep 深度 immediate 立即监听
watchEffect:(不用明确指明属性,需要监视哪些就用哪些)
watchEffect(()=>{ if(){} })
三、 ref
ref在组件标签上时,如果父组件需要访问子组件定义的值或方法,需要在子组件引入defineExpose({x,x,x})导出,defineExpose导出值是非响应式的,需通过方法改变
// 父组件
<father ref='fa'></father>
let fa = ref();
console.log(fa) // 就可读取a,b 值
const changeC = ()=>{
fa.value.c() // 调用可改变b的值
}
// 子组件// $refs可获取所有子组件实例化对象 实现父子通信 $refs.fa // $parent可获取父组件参数,实现子父通信,父组件也需要defineExpose
ler a = ref(1);
let b = ref(2);
const c =()=>{
b.value = '测试改变'
}
defineExpose({a,b,c})
四、toref 、torefs、storeTorefs
toref : 单个解构赋值转响应式
torefs : 多个解构赋值转响应式
let person = reactive( { name: "测试", age: 8, } )let { name, age } = person; // 解构为非响应式
let { name, age } = torefs(person);//解构为响应式
let name = person.name // 非响应式
let name = toref(person, 'name'); // 响应式
storeTorefs:只会关注store中的数据,不会对方法进行ref包裹(pinia状态管理专属)
import { storeToRefs } from "pinia"; let { name,age} = storeToRefs(useCount);
$subscribe:store里的订阅(相当于监听)
useCount.$subscribe((mustate,state)=>{ console.log('里面保存的数据保存变化',mustate,state); })
五、组件通信
defineProps (父传子,函数可子传父;祖传孙 子组件做数据转接 v-bind="$attrs" 同理通过函数也可实现孙传祖。只是存在中间人)
<!-- 父组件 --> <div> <child :a="a" :childPro="childPro"></child> </div>
const childPro = (e)=>{
} <!-- 子组件 --> <div> <p>{{ a }}</p> <button @click="childPro(e)">点击我调用父组件方法</button> </div> const getInfo = defineProps(["a","childPro"])
getInfo.a
defineEmits (子传父)
<!-- 父组件 --> <div> <child :a="a" @childPro="childPro"></child> </div> const childPro = (e)=>{ } <!-- 子组件 --> <div> <p>{{ a }}</p> <button @click="emit(childPro,e)">点击我传递参数</button> </div>const emit = defineEmits(["childPro"])
任意组件通信(总线程)
import mitt from "mitt"; const emitter = mitt(); export default emitter; // 引用 import { emitter } from "@/utils/emitter"; // 绑定事件 emitter.on("a", (e) => { console.log("a被调用了"); }); emitter.on("b", (e) => { console.log("b被调用了"); }); // 触发事件 emitter.emit("a", e); emitter.emit("b", e); // 解绑事件 组件卸载时解绑,优化内存 emitter.off("a"); emitter.off("b");
// 清空 emitter.all.clear();
祖孙通信(不存在中间人)
// 祖组件 import { provide, ref } from "vue"; ① const a = ref("");
provide("a1", a);
② const updateA = (e)=>{
a+="-"
}
provide('a1',{a,updateA})
// 孙组件 import { inject } from "vue"; ① let x = inject("a1");
② let { a,updateA } = inject("a1");
updateA(e)
标签:总结,const,name,reactive,let,vue3,组件,ref From: https://www.cnblogs.com/HopeInTheDark/p/17966031