vue3 笔记

39 篇文章 0 订阅
19 篇文章 0 订阅
<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
  <!-- 瞬间移动 
  组件中  一些 结构 是放在组件中  写样式 定位时  会受其外层多级父元素的 定位干扰
  teleport to 将组件移动到 指定 结构中  这样在写定位至于 这个结构有关系
  一般指定 body  这样不受所有起外层组件的干扰  也可以 选择器 .class 指定结构 或 html
  -->
  <teleport to="body">
    <h3>弹窗</h3>
    <h3>弹窗</h3>
    <h3>弹窗</h3>
    <h3>弹窗</h3>
  </teleport>
  <!-- 
    异步组件 不是异步的组件先出来  异步组件等一等 在出来,且有骨架屛占位
    等一等 1 网络慢   2  组件setup返回Promise 里面延迟
    1 引入异步组件
    2 使用 suspense 包裹异步组件
    配制好 默认的具名插槽 default->异步组件  fallback->骨架屏

    3 组件的 setup 函数 可以是 Promise 
    async setup(){
      let sum = ref(0)
      let D = await new Promise((resolve,reject)=>{
        setTimeout(()=>resolve(sum),3000)
      })
      return D
    }
     -->
  <suspense> 
    <template v-slot:default>
      <hello-world/>
    </template>
    <template v-slot:fallback>
      <h3>我是占位的 骨架屛</h3>
    </template>
  <suspense />
  <router-view />
</template>
<script>
// 1 引入异步组件
import { defineAsyncComponent } from "vue"
// 异步组件包裹 自定义组件 且异步引入
const HelloWorld = defineAsyncComponent(() => import("./components/HelloWorld"))
import {
  /* h, */
  ref,
  reactive,
  computed,
  watch,
  watchEffect,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  toRef,
  toRefs,
  shallowReactive,
  shallowRef,
  customRef,
  provide,
  inject,
  isRef,
  isReactive,
  isReadonly,
  isProxy,
} from "vue"
// hook 导入
import usePoint from "./hooks/usePoint"
import HelloWorld from './components/HelloWorld.vue'
// 组合式 API Composition API
// setup  值 是 函数
// setup  是 所有 Composition API  表演的 舞台
// 以前的所有东西 都写在 setup中
export default {
  name: "App",
  components: { HelloWorld },
  props: [],
  emits: [],
  setup(props, context) {
    // data  非响应式的数据
    let name = "aa"

    // ref函数 使数据变为响应式
    // 引用对象 ref将 age 变为一个对象 {value:18}
    // 模板解析时  自动 读取了 value值
    let age = ref(18)
    let age2 = ref(20)

    // ref 处理对象类型
    const job = ref({
      type: "前端",
      salary: "100000",
    })

    // reactive  只能处理对象 数组类型 ,基本类型用ref  ref全部可以处理
    // refImp job.value=Proxy{type:"",salary:""}
    // Proxy  job2=Proxy{type:"",salary:""} 直接使用 job2.type
    const job2 = reactive({
      type: "前端",
      salary: "100000",
      j: {
        s: 10000,
      },
    })

    // methods
    function sayHello() {
      console.log(`我的名字是${name}年龄是${age}`)
    }
    // 引用对象  age 变为一个对象 {value:18}
    function changeInfo() {
      // age 是 refImpl对象 .value 获得值
      age.value = 20

      // 对象类型 的 修改  job是 refImpl对象 .value 获得值
      //  job.value=Proxy{type:"",salary:""}
      job.value.type = "XXXXX"
      job.value.salary = "600000"
      job2.salary = "600000"
    }

    // ref 得到ref对象  必须value reactive 得到Proxy对象直接用
    // 所以可以定义一个对象P={ name:"",info:{}} 全部使用 reactive
    // Proxy{ name:"",info:{}}  直接使用 p.name p.info.a
    // data.d1.XXX
    const data = reactive({
      d1: {},
      person: { name: "张三" },
    })

    /*
      计算属性  computed   要使用
      是一个函数  () 调用   传入一个函数  箭头 fun 都可 没有this
      返回结果 给 定义
      或者直接新增已有对象 key
      return 出去
    */
    let fullName = computed(() => name + "aaa")
    job2.salary2 = computed(() => job2.salary * 100)
    let fullName = computed({
      set(v) {},
      get() {
        return name + "aaa"
      },
    })

    // 监视属性  watch   要回调
    // 数据源  回调  配置项
    // 1 监视  ref一个数据   三个参数  基本数据类型 无需 deep: true
    // ref包裹对象类型  1 ref.value==reactive 或 2 deep: true  也可检测到
    watch(age, (newValue, oldValue) => {}, { immediate: true })
    // 2 监视  ref多个数据  newValue==[新变化的 数组] 或者重复写
    watch([age, age2], (newValue, oldValue) => {})
    /*
       3 监视  reactive 包裹的 对象类型的数据 全部属性
       注意  1 无法正确获取 oldValue  都是 newValue  目前无法解决
             2 强制开启了 深度监视模式  deep配置无效
    */
    watch(job2, (newValue, oldValue) => {})
    // 4 监视  reactive 某个属性
    // 要求是一个函数的返回值  oldValue有效
    watch(
      () => job2.type,
      (newValue, oldValue) => {}
    )
    // 5 监视  reactive 某些属性
    // 数组模式
    watch([() => job2.type, () => job2.salary], (newValue, oldValue) => {})
    // 6 深度监视  监视的是reactive对象中某个属性是  一个对象  deep: true
    watch(
      () => job2.j,
      (newValue, oldValue) => {},
      { deep: true }
    )

    /*
      watchEffect  监视效应
      1 上来就执行
      2 回调函数里面使用谁 就监视了谁的变化
      3 像computed 但是 像computed依赖返回值 watchEffect依赖回调执行过程 无需返回值
    */
    watchEffect(() => {
      let x = name.value
      let y = age.value
    })

    /*
      setup 注意点
      vue2 中 props没写  $attrs 兜底接收  写了vc接收 $attrs不接收
      没有定义slot  但是 父组件 使用子组件传递了 Dom 节点 会在 $slots中接收
      setup() 执行时机   在  beforeCreate()之前   this 是 undefined
      props:[],组件外部传递过来 且组件内部声明接收的属性
      emits:[],
      setup(props,context)
      context
      .attrs   $attrs
      .slots   $slots
      .emit    $emit         context.$emit 触发自定义事件
     */

    /*
      setup中 实现生命周期
      beforeCreate -->created 相当于  setup
      setup中的执行时机 先于 配置项的时机
    */
    onBeforeMount(() => {})
    onMounted(() => {})
    onBeforeUpdate(() => {})
    onUpdated(() => {})
    onBeforeUnmount(() => {})
    onUnmounted(() => {})
    /*
    自定义  hook 函数   把Composition API  进行封装  复用已存在的逻辑
    hook.js中 返回值
    setup中 调用 接收
    setup中 return point
    模板使用

    组合式API  依靠  hook 提现  将  数据 方法  计算属性  生命周期  分类抽离 导入
    hook  是一个 function  return {data,methods,computed}
    const { data,methods,computed } = usePoint()
   */
    let point = usePoint()

    /*
     toref
     return data.person.name  相当于一个单纯的 String 没有响应式
     哪个对象   哪个key

     该新属性不是新建的 而是还是指向 原数据的 data.person.name
     修改同步修改原数据  页面响应

     直接 ref(data.adress) 新创建了一个 refImpl对象
     点击事件 修改的是return出去的新建数据   页面虽然响应  但是原数据没有被修改
     return {name:toRef(data.person, "name")}
    */
    toRef(data, "adress") //refImpl对象
    toRef(data.person, "name") //refImpl对象
    /*
     toRefs(data)  将data中所有 属性都变成 refImpl 且指向原数据
     return {name:xxx,age:xxx}
     return { ...toRefs(data) }
     模板中只能省略第一层级的 data.   person.name 第二级开始还得.
    */
    toRefs(data)

    /*
     优化时会用

     shallowReactive 浅层次的 响应式  只考虑对象第一层数据的响应式{name:"aa",info:{}}

     shallowRef 基本数据类型和 ref  一样都是响应式的  没区别
     对象类型 不处理为响应式 不借助reactive ,所以ref({ }) 第一层级为value
     一般用在 整体替换 整个对象 对象内无需响应式  替换后触发页面更新  refImpl value 替换

     readonly  接收一个响应式数据  返回的数据不可以被修改

     shallowreadonly   第一层不可修改{name:"aa",info:{}} name不可修改
     使用场景  接受别人传过来的数据  只做显示 可以readonly 确保不会修改

     toRaw  将响应式数据还原为非响应式  只针对  reactive处理的对象类型
     toRaw(data)

     markRaw 标记一个对象 使其永远不会是响应式的
     data.car = {name:"大众"}  data是proxy 添加KEY  是响应式的
     data.car = marRaw({})  data.car 就不是响应式的
     1 第三方库 不应被设置为响应式
     2 复杂的数据 要求还不需要变化 不设为响应式可提高性能

     customRef   自定义ref
     get track() return value + set value=newValue  trigger()  相当于 ref
     其他是就是自定义的逻辑
    */
    function myRef(value, delay) {
      let timer
      return customRef((track, trigger) => {
        return {
          get() {
            track() //通知Vue追踪value的变化,不然只有初始化模板才会get一次
            return value //模板解析读取
          },
          set(newValue) {
            clearTimeout(timer)
            timer = setTimeout(() => {
              value = newValue //修改value 值 get中 value被修改
              trigger() //通知Vue重新解析模板
            }, delay)
          },
        }
      })
    }
    let data1 = myRef("hello", 500)

    /*
      祖孙 组件的 数据通信  儿子也可不过 儿子一般props
      provide   提供      名字   数据
      inject    注入
    */
    provide("data", data) //给后代组件传递数据
    const data = inject("data") // 后代组件获取数据

    /*
      响应式数据的判断  API  boolean
      isProxy  Proxy被Readonly修饰后Proxy 仍然是  Proxy
    */
    console.log(isRef(name), isReactive(data), isReadonly(data), isProxy(data))

    //fragment  vue3 可以没有根标签,内部将多个标签包裹在一个Fragment虚拟元素中,减少层级

    /*
      返回渲染函数 相当于渲染函数中 button替换了 容器#app
      return () => h("button", "按钮")
    */

    // 返回的是一个对象  对象内配置可以在模板中直接使用
    return {
      name,
      age,
      job,
      job2,
      data,
      sayHello,
      changeInfo,
      fullName,
      point,
      ...toRefs(data),
      data1,
    }
  },
  /*
     生命周期
     beforeUnmount() unmounted()  取代之前的  destroy
   */
  mounted() {},

 /* 
  1 全局API的 转移
  2 过渡类名的修改
  3 移除 keyCode(数字) 作为 v-on 的修饰符  不支持 config.keyCodes
    @keyUp.enter    13不行
  4 移除 v-on.native 修饰符
    @click="increament"
    emits: ["close"], 子组件中不添加  就是原生事件,添加了就是自定义事件
  5 移除  filter   计算属性 代替也可
   */
  
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值