Vue3学习笔记

认识Ref全家桶:
ref:接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。
isRef:判断是不是一个ref对象
shallowRef:创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的。虽然打印的数据变了,但不是响应式,视图未更新
triggerRef :强制更新页面DOM。可以配合shallowRef更新视图
customRef:自定义ref(了解)customRef 是个工厂函数要求我们返回一个对象 并且实现 get 和 set  适合去做防抖之类的
bug:ref和shallowRef同时存在时,ref的更新会导致shallowRef的更新
认识Reactive全家桶:
reactive:不可以绑定普通的数据类型,会给我们报错
    不推荐直接赋值,会改变引用类型数据的地址,破坏了数据的响应式。可以push、包裹一层对象来解决该问题
readonly:拷贝一份proxy对象将其设置为只读,修改会报错
shallowReactive:只能对浅层的数据 如果是深层的数据只会改变值,不会改变视图。如果和浅层数据一起改变则都会更新视图
认识to系列全家桶:
toRef:如果原始对象是非响应式的就不会更新视图,数据是会变的
toRefs:可以帮我们批量创建ref对象主要是方便我们解构使用
toRaw:将响应式对象转化为普通对象
Computed计算属性:
写法:
  // const name = computed(()=>{//第一种
  //   return firstName.value + '————————————————' + lastName.value
  // })
  const name = computed({//第二种
    get() {
      return firstName.value + lastName.value
    },
    set() {
      firstName.value + lastName.value
    }
  })
Watch监听器:使用ref时:deep可以开启深度监听    immediate第一次立即执行。    reactive不写也可以监听
  watch([message,message2],(newval,oldval)=>{
    console.log("new:",newval,"old:",oldval);
  },{
    deep:true
    immediate:true
  })
可以监听对象内单一属性    ()=>对象.属性
WatchEffect高级监听器:每次更新都会先执行一次oninvalidate
  watchEffect((oninvalidate)=>{
    console.log('message===>',message.value);
    console.log('message2===>',message2.value);
    oninvalidate(()=>{
      console.log("before先执行");
    })
  })
组件的生命周期:
onBeforeMounted、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted
组件通讯:
    <Menu ref="menus" :data="list" @on-click="getList" @on-click2="getList" title="我是静态标题"></Menu>
  const getList = (list:number[],flag:boolean) => {
    console.log(list,'子组件',flag);
    console.log(menus.value,"aaaaaaaa");
  }

type Props = {
    title:string
    data:number[]
  }
  defineProps<Props>()//子组件defineProps接收父组件传递的数据
  const emit = defineEmits(['on-click','on-click2'])
  const clickTap = () => {
    emit('on-click',list,false)//defineEmits定义,emit发送数据。父组件@on-click="getList"调用
  }
defineExpose({})//可以暴露子组件的属性方法到父组件,使用ref.value访问
type Props = {
    title?:string
    data?:number[]
  }
  withDefaults(defineProps<Props>(),{
    title:"默认值",
    data:() => [1,2,3]
  })//设置默认值,如果没传递值则采用默认值
组件:
全局组件:mian.ts中注册:createApp(App).component('Card',Card).mount('#app')
局部组件:import直接导入实例化,不需要component注册
递归组件:1.在组件内部重新import导入实例化,并调用。2.再定义一个script标签,export default导出name。
    派发内容要在TreeItem和父组件都派发
<template>
  <div v-for="(item,index) in data" :key="index" style="margin-left:10px;">
    {{item.name}}
    <TreeItem v-if="item?.children?.length" :data="item.children"></TreeItem>
  </div>
</template>
<script setup lang="ts">
  // import TreeItem from './index.vue'//第一种
  import { type } from 'os';
import { reactive } from 'vue';
  type TreeList = {
    name:string,
    icon?:string,
    children?:TreeList[] | []
  }
  type Props = {
    data?:TreeList[]
  }
  defineProps<Props>()
</script>

<script lang="ts">
  export default {
    name:"TreeItem"//第二种
  }
</script>
动态组件:
    <component :is="A"></component>//A组件实例的方式来使用
补充:markRow(A)可以跳过Proxy代理,组件不需要是Proxy对象。在vue2中可以绑定字符串,vue3不行,要export default注册
插槽:slot
匿名插槽:<slot></slot>
      <template v-slot>
        <div>
          默认插槽的内容
        </div>
      </template>
具名插槽:<slot name="header></slot>
      <template v-slot:header>
        <div>
          具名插槽的内容
        </div>
      </template>
      <template #footer>//简写。默认插槽#default
        <div>
          具名插槽的内容
        </div>
      </template>
作用域插槽:父组件可以拿到子组件的值
      <template #default="{data}">
        <div>
          {data}//data未<slot :data="item"></slot>传递的值
        </div>
      </template>
动态插槽:
      <template #[name]>
        <div>
          动态插槽的内容
        </div>
      </template>
      let name = ref('default')
      let name = ref('footer')
异步组件:
打包:npm run build    =>生成dist文件
Teleport传送组件:将我们的模板渲染到指定DOM结点。不受父级的v-show、style影响,但受v-if影响
  <teleport to='body'>
    <div>loading.....</div>
  </teleport>
keep-alive缓存组件:(内置组件)
  属性:include(需要缓存的组件)、exclude(不需要缓存的组件)、max(缓存的数量)
  增加的生命周期:onActivated、onDeactivated
transition动画组件:
    <transition name="fade">
      <div v-if="flag" class="box"></div>
    </transition>
    //定义name="fade",在style里定义,fade-enter-from、fade-enter-active、fade-enter-to、fade-leave-from.....
    //也可以在transition内自定义对应类名:enter-from-class="e-from"
  也可以使用第三方类库:animate.css
    安装:npm install animate.css    引入: import 'animate.css'
    <transition
      :duration="500"
      leave-active-class="animate__animated  animate__fadeOut"
      enter-active-class="animate__animated  animate__fadeIn" 
      >
      <div v-if="flag" class="box"></div>
    </transition>
    生命周期(8个):  @before-enter="beforeEnter" //对应enter-from
                  @enter="enter"//对应enter-active
                  @after-enter="afterEnter"//对应enter-to
                  @enter-cancelled="enterCancelled"//显示过度打断
                  @before-leave="beforeLeave"//对应leave-from
                  @leave="leave"//对应enter-active
                  @after-leave="afterLeave"//对应leave-to
                  @leave-cancelled="leaveCancelled"//离开过度打断
        //当只用 JavaScript 过渡的时候,在 enter 和 leave 钩子中必须使用 done 进行回调
    结合gsap 动画库使用 GreenSock
    <transition
      @before-enter="EnterFrom"
      @enter="EnterActive"
      @leave="Leave"
      >
      <div v-if="flag" class="box"></div>
    </transition>
const EnterActive = (el:Element,done:gsap.Callback) => {
  gsap.to(el,{
    width:200,
    height:200,
    onComplete:done
  })
}
    appear:设置初始节点过度 就是页面加载完成就开始动画
transition-group过度列表:
      <transition-group tag="section">//tag给内部元素套一层标签
        <div class="items" v-for="item in list" :key="item">{{item}}</div>
      </transition-group>
      <transition-group
        enter-active-class="animate__animated  animate__hinge"
        leave-active-class="animate__animated  animate__hinge">
        <div class="items" v-for="item in list" :key="item">{{item}}</div>
      </transition-group>
new Array(81)//
Array.apply(null,{length:81} as number[])//会初始化每一条数据为undefined
//案例,随机排列81个1-9的数字,并使用动画(补充:lodash的shuffle()可以创建一个被打乱的集合)
  <div>
    <button @click="random">Shuffle</button>
    <transition-group 
      move-class="mmm"
      tag="div" class="wraps">
      <div class="items" v-for="item in list" :key="item.id">{{item.number}}</div>
    </transition-group>
  </div>
import { shuffle } from 'lodash';
import { ref } from 'vue'
let list = ref(Array.apply(null,{length:81} as number[]).map((_,index)=>{
  return {
    id:index,
    number:(index % 9) + 1
  }
}))
const random = () => {
  list.value = shuffle(list.value)
}
  .mmm {
    transition: all 2s;
  }
状态过度 

Provide / Inject:
    父、祖组件使用provide提供数据或方法,子孙使用inject接收provide提供的数据或方法
    import { provide,ref } from 'vue';
    provide('flag',ref(false))
    import { inject,Ref,ref } from 'vue';
    let data = inject<Ref<boolean>>('flag',ref(false))
    //Ref解决类型推断的报错,第二个参数“ref(false)”设置默认值,避免接收到undefined的情况,使用?.语法会导致无法赋值
兄弟组件传参Event Bus:
定义一个bus.ts公共方法(发布订阅模式)可以使用Mitt代替
TSX:
    定义".tsx"类型的文件,定义并导出。使用小括号调用变量如(v-if={falg})。不能使用v-for,可以使用map代替
Vue3自动引入插件:unplugin-auto-import
    链接:https://blog.csdn.net/qq_42611074/article/details/123036047
    npm i -D unplugin-auto-import =>vite.config.ts中注册=>重新运行项目,自动生成声明文件=>

样式穿透:scoped(给dom结点添加一个不重复的data属性,如data-v-123)Vue2:/deep/ .类名{}    Vue3::deep(.类名){}
CSS新特性:
    插槽选择器::slotted(.a) {}//选择插槽内容的class类名。:deep好像也行
    全局选择器::global(div) {}//设置全局div的属性
    动态 CSS:color: v-bind(style);//动态绑定script内定义的"style"变量
                color: v-bind('style.color');//动态绑定script内定义的"style"对象的color属性。可以动态修改对应的属性值
    css module:
Vue3集成Tailwind CSS
Event Loop时间循环机制:
    所有的同步任务都是在主进程执行的形成一个执行栈,主线程之外,还存在一个"任务队列",异步任务执行队列中先执行宏任务,然后清空当次宏任务中的所有微任务,然后进行下一个tick如此形成循环。
nextTick:nextTick 就是创建一个异步任务,那么它自然要等到同步任务执行完成后才执行。
Vue如何开发移动端:
    vw 视口的最大宽度,1vw等于视口宽度的百分之一
    vh 视口的最大高度,1vh等于视口高度的百分之一
unocss原子化:tips:最好用于vite webpack属于阉割版功能很少。使用一些class类名实现样式布局
函数式编程,h函数:h 接收三个参数
    1.type 元素的类型
    2.propsOrChildren 数据对象, 这里主要表示(props, attrs, dom props, class 和 style)
    3.children 子节点

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值