vue3中知识点总结(持续更新)

2023-11-01

1、具名插槽

Vue3 具名插槽 Named Slots 文档地址

// 具名插槽添加
<slot name="submit"></slot>
 
// 具体地方使用submit插槽时
// v-slot:submit 可以缩写为#submit
<template v-slot:submit>
  <span class="btn btn-danger">Submit</span>
</template>
// 或者
<template #submit>
  <span class="btn btn-danger">Submit</span>
</template>

2、watch监听

应用场景代码:

// watch 简单应用
watch(data, () => {
  document.title = 'updated ' + data.count
})
// watch 的两个参数,代表新的值和旧的值
watch(refData.count, (newValue, oldValue) => {
  console.log('old', oldValue)
  console.log('new', newValue)
  document.title = 'updated ' + data.count
})

// watch 多个值,返回的也是多个值的数组
watch([greetings, data], (newValue, oldValue) => {
  console.log('old', oldValue)
  console.log('new', newValue)
  document.title = 'updated' + greetings.value + data.count
})

// 使用 getter 的写法 watch reactive 对象中的一项
// 注意这里不能直接用data.count;因为data.count不是一个响应式数据,所以用() => data.count 箭头函数的方式
watch([greetings, () => data.count], (newValue, oldValue) => {
  console.log('old', oldValue)
  console.log('new', newValue)
  document.title = 'updated' + greetings.value + data.count
})

示例代码:

<!--
* @Description: Vue3新特性之watch监听 
* @Author: Rulyc
* @Operating:
-->
<template>
  <h1>{{ count }}</h1>
  <h2>{{ double }}</h2>
  <button @click="btnClick">点击+1</button>
</template>

<script lang="ts">
  import { ref, computed, reactive, toRefs, watch } from 'vue' // 引入ref,computed 才能使用
  interface DataProps { // 定义数据类型
    count: number;
    double: number;
    btnClick: () => void;
  }
  export default {
    name: "watch",
    setup() {
     const data: DataProps = reactive({
       count: 0,
       /** 点击事件 */
       btnClick: ()=>{ data.count ++; },
       /** 计算属性 */
       double : computed(()=>{ return data.count * 2 })
     })
      const refData = toRefs(data)
      /** watch监听 */
      // data.double不是响应式数据,故而需要用箭头函数的方式()=> data.double,或者toRefs后的refData.count
      watch([refData.count, ()=> data.double], (newValue, oldValue) => {
        console.log('old', oldValue)
        console.log('new', newValue)
        document.title = 'updated ' + data.count+data.double
      })
      return {
        ...refData
      }
    }
  }
</script>

结果:
在这里插入图片描述

3、ref语法(数据定义)

在这里插入图片描述

代码:

<!--
* @Description: Vue3新特性之Ref 语法
* @Author: Rulyc
* @Operating:
-->
<template>
  <h1>{{ count }}</h1>
  <h2>{{ double }}</h2>
  <button @click="btnClick">点击+1</button>
</template>
<script>
  import { ref, computed } from 'vue' // 引入ref,computed 才能使用
  export default {
    name: "ref_computed",
    setup() {
      // ref是一个函数,他接受一个参数,返回的就是一个神奇的响应式对象
      const count = ref(0)
      /** 计算属性用法 */
      const double = computed(()=>{
        return count.value * 2
      })
      /** 点击事件 */
      const btnClick = ()=> {
        // 更改值用xx.value; 渲染时用xx; 原因vue3底层自动在渲染时处理了
        count.value ++
      }
      return {
        count,
        double,
        btnClick
      }
    }
  }
</script>
<style scoped>
</style>

4、Reactive函数

在这里插入图片描述
在这里插入图片描述

导致这个的原因是:
在这里插入图片描述

如果需要优化,且避免上述问题,我们需要引入toRefs;优化后的完整代码如下:

<!--
* @Description: Vue3新特性之Reactive 语法
* @Author: Rulyc
* @Operating:
-->
<template>
  <h1>{{ count }}</h1>
  <h2>{{ double }}</h2>
  <button @click="btnClick">点击+1</button>
</template>

<script lang="ts">
  import { ref, computed, reactive, toRefs } from 'vue' 
  interface DataProps { // 定义数据类型
    count: number;
    double: number;
    btnClick: () => void;
  }
  export default {
    name: "Reactive_toRefs",
    setup() {
     const data: DataProps = reactive({
       count: 0,
       /** 点击事件 */
       btnClick: ()=>{ data.count ++; },
       /** 计算属性 */
       double : computed(()=>{ return data.count * 2 })
     })
      const refData = toRefs(data)
      return {
        // 此时的数据不是响应式的数据,而是取出的为数据类型,number
       /* count: data.count,
        double: data.double,
        btnClick: data.btnClick*/
        ...refData
      }
    }
  }
</script>
<style scoped>
</style>

使用 ref 还是 reactive 可以选择这样的准则:
第一,就像刚才的原生 javascript 的代码一样,像你平常写普通的 js 代码选择原始类型和对象类型一样来选择是使用 ref 还是 reactive。
第二,所有场景都使用 reactive,但是要记得使用 toRefs 保证 reactive 对象属性保持响应性

5、Vue3中的生命周期函数

在 setup 中使用的 hook 名称和原来生命周期的对应关系
beforeCreate -> 不需要 use setup()
created -> 不需要 use setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy-> onBeforeUnmount
destroyed -> onUnmounted
activated -> onActivated
errorCaptured -> onErrorCaptured
// 新增的(调试用的debugger工具函数)
renderTracked -> onRenderTracked
renderTriggered -> onRenderTriggered在这里插入图片描述

<!--
* @Description: 生命周期函数
* @Author: Rulyc
* @Operating:
-->
<template>
  <h1>{{ count }}</h1>
  <h2>{{ double }}</h2>
  <button @click="btnClick">点击+1</button>
</template>

<script lang="ts">
  import { ref, computed, reactive, toRefs, onMounted,  onUpdated, onRenderTriggered } from 'vue' // 引入ref,computed 才能使用
  interface DataProps { // 定义数据类型
    count: number;
    double: number;
    btnClick: () => void;
  }
  export default {
    name: "onMounted",
    setup() {
      /** 挂载 */
      onMounted(() => {
        console.log('mounted')
      })
      /** 数据更新  */
      onUpdated(() => {
        console.log('updated')
      })
      /** 调试 */
      onRenderTriggered((event) => {
        console.log(event)
      })
      const data: DataProps = reactive({
        count: 0,
        /** 点击事件 */
        btnClick: ()=>{ data.count ++; },
        /** 计算属性 */
        double : computed(()=>{ return data.count * 2 })
      })
      const refData = toRefs(data)
      return {
        ...refData
      }
    }
  }
</script>

<style scoped>

</style>

在这里插入图片描述

6、Teleport-瞬间移动组件

Teleport组件的出现时为了解决一个问题: 让元素直接挂在到根元素中(常见的场景就是Dialog弹窗,在界面中使用时包裹在其他组件之中,容易被干扰;样式也在其他组件之中,容易变得非常乱),这时候我们需要把弹窗组件渲染到顶层DOM节点之中,如elementUI中,弹窗、气泡是用的js挂在到body中,虽然解决上述说的问题,但是也存在一些bug,比如气泡的bug; vue3推出了teleport组件解决上述问题。
如下:
在这里插入图片描述
在这里插入图片描述
代码部分:model组件
在与html文件中:
在这里插入图片描述
model组件:

<template>
  <!-- teleport组件有一个to属性,去界面中使用使用id="#modal" -->
  <teleport to="#modal">
    <div id="center" v-if="isOpen">
      <h1>
        this is a modal
        <slot></slot>
      </h1>
      <button @click="btnClick">close</button>
    </div>
  </teleport>
</template>

<script lang="ts">
  import { defineComponent } from 'vue'
  export default defineComponent({
      name: "Teleport",
      props: { // 属性
          isOpen: Boolean
      },
      emits: { // 事件名称
          'close-model': null
      },
      setup(props, context) {
          const btnClick = ()=>{
              context.emit('close-model')
          }
          return {
              btnClick
          }
      },

  })
</script>

<style scoped>
  #center {
    width: 200px;
    height: 200px;
    border: 2px solid black;
    background: white;
    position: fixed;
    left: 50%;
    top: 50%;
    margin-left: -100px;
    margin-top: -100px;
  }
</style>

具体界面使用
button @click=“openBtn”>Open Modal

<TeleportDemo :isOpen=“modelIsOpen” @close-model=“closeBtn”>

import { ref} from ‘vue’;

setup() {
const modelIsOpen = ref(false)
/** 打开弹窗按钮事件 /
const openBtn = ()=>{
modelIsOpen.value = true
}
/
* 关闭弹窗按钮事件 */
const closeBtn = ()=>{
modelIsOpen.value = false
}

return {
    modelIsOpen, // 返回数据
    openBtn, // 返回事件
    closeBtn // 返回事件
}

}

7、Suspense异步组件

Suspense组件是Vue3中的知名功能之一。
它们允许我们的应用程序在等待异步组件时渲染一些后备内容,可以让我们创建一个平滑的用户体验。
值得庆幸的是,Suspense组件非常容易理解,它们甚至不需要任何额外的导入!

可以解决异步请求的困境; Suspense是Vue3推出的一个内置的特殊组件; 如果使用Suspense,需要返回一个Promise

本文主要是展示一哈加载多个异步组件的场景,遇到不稳定问题,及解决方法(加载单个,只需要引入单个组件即可)

创建第一个组件:
AsyncShow

<!--
* @Description: Suspense - 异步请求好帮手
* @Author: Rulyc
* @Operating:
-->
<template>
  <h1>{{ result }}</h1>
</template>

<script lang="ts">
  import { defineComponent } from 'vue'
  export default defineComponent({
      name: "10_AsyncShow",
      setup() {
          /** 需要返回一个Promise, 使用Suspense */
          return new Promise((resolve) => {
              setTimeout(()=>{
                  return resolve({
                      result: 42
                  })
              }, 3000)
          })
      }
  })
</script>

使用 async await , 新建一个 10_AsyncShow_Img组件

<template>
  <img :src="result && result.url" alt="">
</template>

<script lang="ts">
  import { defineComponent } from 'vue'
  import axios from 'axios'
  export default defineComponent({
      name: "10_AsyncShow",
      async setup() {
         const rawData = await axios.get('https://images.dog.ceo/breeds/terrier-irish/n02093991_4404.jpg')
          return {
             result: rawData.config
          }
      }
  })
</script>

使用界面中:(自行引入两个组件,然后使用如下图中)

在这里插入图片描述
在这里插入图片描述

警告中说:是一个实验性的特性,它的API很可能会改变slots,除非只有一个根节点。在

故而这里目前应该暂时展示一个根节点(之前的版本中,是可以展示多个异步组件作为根节点的; 以后版本未确定,还不够稳定)

解决这个问题,初步采用了增加一个div包裹(即增加一个根节点)

<Suspense>
  <template #default>
    <div>
      <AsyncShow></AsyncShow>
      <AsyncShowImg></AsyncShowImg>
    </div>
  </template>
  <template #fallback>
    <div>
      Loading... ---- 异步加载中
    </div>
  </template>
</Suspense>

在4.5.8版本中,是需要增加一个根节点的。目前博主使用的是4.5.8; 之前的版本貌似是不用增加一个根节点。
在这里插入图片描述

补充

单个组件及template上属性说明如下图:
在这里插入图片描述

8、getCurrentInstance获取父元素内容

import { defineComponent, computed, getCurrentInstance } from 'vue'
 setup: function (props, context) {
    const colStyle = computed(() => {
      let {parent} = getCurrentInstance()
      while (parent && parent.type.name !== 'LcRow') {
        parent = parent.parent
      }
      const colGutter : any = parent ? parent.props.gutter : 0
      return {
        paddingLeft: colGutter / 2 + 'px',
        paddingRight: colGutter / 2 + 'px',
      }
    })
    return {
     colStyle
    }
  }

这里我是需要拿到父组件的gutter属性绑定值

9、toRefs、unref

  • toRefs(props) 获取当前绑定的所有属性
  • toRefs(props)[size] // 获取名为size属性的对象
  • unref(toRefs(props)[size] // 获取名为size属性对象的value
import { defineComponent, computed, getCurrentInstance, toRefs, unref } from 'vue'

const classList = []
 /**
   *   toRefs(props) 获取当前绑定的属性
   *   toRefs(props)[size] // 获取名为size属性的对象
   *   unref(toRefs(props)[size] // 获取名为size属性对象的value
   * */
;['xs', 'sm', 'md', 'lg', 'xl'].forEach((size) => {
  if(size == 'xs') { // 为了查看打印效果
    console.log(toRefs(props), 'toRefs(props)')
    console.log(toRefs(props)[size], 'toRefs(props)[size]')
    console.log(unref(toRefs(props)[size]), 'unref(toRefs(props)[size]')
  }
/** 具体判断示例 */
  if (typeof unref(toRefs(props)[size]) === 'number') {
    classList.push(`lc-col-${size}-${unref(toRefs(props)[size])}`)
  } else if (typeof unref(toRefs(props)[size]) === 'object') {
    const propsData = unref(toRefs(props)[size])
    Object.keys(propsData).forEach((prop) => {
      classList.push(
        prop !== 'span'
          ? `lc-col-${size}-${prop}-${propsData[prop]}`
          : `lc-col-${size}-${propsData[prop]}`
      )
    })
  }
})

在这里插入图片描述

10、路由跳转

第一步,引入

import { useRouter } from "vue-router" // 引入路由文件

第二步:setup中

// 路由
 const router = useRouter();

第三步跳转:

router.push('/');

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3中知识点总结(持续更新) 的相关文章

随机推荐

  • 动态代理 [用jdk实现]

    一 java 的jdk動態代理 用JDK實現的動態代理 被代理的對象必須實現一個接口才可以 其實現主是通過java lang reflect Proxy類和 java lang reflect InvocationHandler接口 二 本
  • android实现夜间模式_Android中的夜间模式实现

    android实现夜间模式 Easiest way to implement night mode in android 在Android中实现夜间模式的最简单方法 Android has recently introduced Dark
  • Vue环境搭建(node安装,环境配置,运行项目)

    Vue环境搭建 node安装 环境配置 运行项目 一 安装node 1 去官网下载node之后 推荐安装稳定版本 LTS node官网下载地址 2 查看node安装成功否 node v 查看node版本 npm v 查看npm版本 wher
  • ctkPluginFramework编译qt_vs2017_gcc

    ctkPluginFramework编译qt5 12 vs2017 gcc4 8 前言 使用ctkPluginFramework作为插件系统框架的确有着众多开发上的优势 最近收到一些站内信 大家都想使用ctkPluginFramework但
  • Appium+Python自动化测试(二)--运行App程序示例

    在上一篇博客中 已经将环境搭建好了 现在 我们利用搭建的环境来运行一条测试脚本 脚本中启动一个计算器的应用 并实现加法的运算 创建模拟器 在运行App之前 首先需要创建一个Android模拟器 也可以使用真机来运行 效果更佳 进到Andro
  • mysql 1045 错误解决办法

    ERROR 1045 28000 Access denied for user ODBC localhost using password NO ERROR 1045 28000 Access denied for user ODBC lo
  • [Samuel Ko]——我的2020年回顾

    0 写在前面 其实一直以来 CSDN博客就完全是我个人的技术成长方面的记录和总结 由于工作的原因 一些更新 更好的资料没办法上传上来 之前的CSDN对我来讲 更像是一个纯技术文档 在这已经几年了 也完全没有发一些关于个人的动态或者经历 现在
  • MySQL批量插入数据的四种方案(性能测试对比)

    关注后回复 进群 拉你进程序员交流群 本文记录个人使用MySQL插入大数据总结较实用的方案 通过对常用插入大数据的4种方式进行测试 即for循环单条 拼接SQL 批量插入saveBatch 循环 开启批处理模式 得出比较实用的方案心得 一
  • 上传文件(Servlet)

    HttpServletRequest 类 法 Part 类 法
  • Python深度学习-U2:神经网络的数学基础

    理解深度学习 需要熟悉很多简单的数学概念 张量 张量运算 微分 梯度下降等 本章就是建立对这些概念的直觉 MNIST数据集 包括 60 000张训练图片和 10 000张测试图像 解决 MNIST问题是深度学习的 Hello World 神
  • Mybatis Plus基础07 type-aliases-package配置(实体对象扫描包)

    学习目标 简化操作 配置 type aliases package实体对象扫描包 学习产出 1 为什么配置这个 简单的说就是简化一个操作步骤 简化哪里的操作 简化xml文件中resultType中指定路径配置 2 哪里配置 在项目的appl
  • linux部署项目

    linux部署项目 一 安装jdk 1 二 安装tomcat 1 官网下载tomcat 官网地址 https tomcat apache org 2 部署项目 将下载的tomcat文件放入linux文件夹下 输入命令 tar zxvf ap
  • 离线pip安装paddlepaddle时存在的问题

    由于内网限制 只能从清华源安装软件包 而清华源没有满足条件的paddlepaddle安装包 为了成功在内网环境安装paddlepaddle 可以按照如下步骤 在开始使用 飞桨 源于产业实践的开源深度学习平台 官网平台 按照操作系统 计算平台
  • JDBC数据库连接 及JDBC使用讲解

    目录 1 什么是JDBC 2 JDBC 作原理 3 JDBC 使 3 1 创建项目并添加MySQL驱动 DataSource实现操作数据库 3 2 使用代码操作数据库 1 什么是JDBC Java 数据库连接 是 种 于执 SQL 语句的
  • 用Python编写代码,实现输出自己的姓名,班级,学号等信息

    可以使用以下代码实现输出自己的姓名 班级 学号等信息 name 你的姓名 class name 你的班级 student id 你的学号 print 姓名 name print 班级 class name print 学号 student
  • shell-环境变量以及环境变量的配置文件

    环境变量定义 用户自定义变量只在当前的shell中生效 而环境变量会在当前shell和这个shell的所有子shell当中生效 如果把环境变量写入相应的配置文件 那么这个环境变量就会在所有的shell中生效 设置环境变量 export 变量
  • Unity Shader小技巧-制作Shader时在Scene显示实时动态效果

    直接上截图 在编辑shader时 我们会使用到很多动态效果 例如 Time的函数 但是在Unity中会是静态效果 点击这个选项之后就以看到Scene窗口的Shader有动态效果了
  • malloc函数的使用

    调用被调函数 将主函数中动态内存分配的内存中的数据放大十倍 malloc动态分配了1字节的内存空间 最多能存放的整数是255 int型变量并不是一定占4字节 C语言从来没有规定一个整型必须要强制占几字节 C语言只规定了 短整型的长度不能大于
  • ASP.net DropDownList数据绑定及使用详解

    1 dropdownlist 绑定数据 1 1 固定绑定 适合已经固定的数据绑定到dropdownlist 实例
  • vue3中知识点总结(持续更新)

    1 具名插槽 Vue3 具名插槽 Named Slots 文档地址 具名插槽添加