vue3总结

一、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的值
}
// 子组件
ler a = ref(1);
let b = ref(2);
const c =()=>{
b.value = '测试改变'
}
defineExpose({a,b,c})

// $refs可获取所有子组件实例化对象 实现父子通信   $refs.fa
// $parent可获取父组件参数,实现子父通信,父组件也需要defineExpose

 四、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)

 

posted @ 2024-01-18 18:38  暮雪上的晨星  阅读(38)  评论(0编辑  收藏  举报