美文网首页Vue
开发知识点

开发知识点

作者: hellomyshadow | 来源:发表于2022-01-11 17:09 被阅读0次

toRaw 与 markRaw

目的是不想使用响应式对象

  1. toRaw,将一个响应式对象转为普通对象,对这个普通对象的操作不会引起页面更新,提高性能。
  2. markRaw,标记一个对象,使其永远不会再成为响应式对象
    • 有些值不应被设置为响应式的,例如复杂的第三方类库等
    • 当渲染具有静态数据源的大列表时,跳过响应式转换可以提高性能

示例一

动态组件<component> is 在接收一个组件时,明确要求不能是一个响应式对象

import { ref, markRaw } from 'vue'
import Foo from './foo/index.vue'

const list = ref([
    {
        // ...
        component: markRaw(Foo)
    }
])
<template>
    <div v-for="(item, index) in list" :key="index">
        <component :is="item.component"></component>
    <div>
</template>

示例二

Vue3 封装 echarts 时,监听窗口大小变化时,调用 echarts resize() 函数更新图表,会发现报错:
TypeError: Cannot read properties of undefined (reading 'type')
原因是,vue3默认把 echarts 实例转为响应式proxy代理,致使 resize() 无法获取 coordSys.type
解决方案

import { ref, markRaw, onMounted } from 'vue'
import * as echarts from 'echarts'
import { EChartsOption, EChartsType } from 'echarts'

const chartRef = ref<EChartsType>()
onMounted(() => {
    chartRef.value = markRaw(echarts.init(document.getElementById("chart")))
})

shallowRef

reactive 底层其实就是通过 ref 创建的;
默认情况下,无论是 ref 还是 reactive 都是深度监听;而 shallowRef / shallReactive 都是非深度监听,只会包装第一层的数据,如果想更改多层的数据,必须先更改第一层的数据,然后在去更改其他层的数据,这样视图上的数据才会发生变化。
所以,当我们试图将一个component组件 变成响应式时,vue3会发出警告:should be avoided by marking the component with markRaw or using shallowRef instead of ref -- 用 markRaw / shallowRef 标记组件

defineProps、defineEmits、defineExpose

defineProps

声明组件 props 传值

<script setup lang="ts">
  // 采用 ts专有声明,无默认值
  defineProps<{
      msg: string,
      num?: number
  }>()

  // 采用ts专有声明,有默认值
  interface Props {
      msg?: string
      labels?: string[]
  }
  const props = withDefaults(defineProps<Props>(), {
      msg: 'hello',
      labels: () => ['one', 'two']
  })

  // 非ts专有声明
  defineProps({
      msg: String,
      num: {
          type:Number,
          default: ''
      }
  })
</script>

defineEmits

子组件声明暴露的事件

<script setup lang="ts">
    /*ts专有*/
   const emit= defineEmits<{
      (e: 'click', num: number): void
   }>()

  /*非ts专有*/
  const emit= defineEmits(['click'])
  
  const clickThis = () => {
      emit('click', 2)
  }
</script>

defineExpose

子组件暴露出去、让父组件访问的属性

// helloword.vue
import { ref, defineExpose } from 'vue'

const count = ref(123)
defineExpose({
   count
})

// Something.vue
<template>
  <helloword ref="hello"></helloword>
  <button @click="helloClick">touch me</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import helloword from './components/HelloWorld.vue'

const hello = ref(null)
const helloClick = () => {
  console.log(hello.value.count) // 123
}

相关文章

  • 测试开发知识点(三)

    传送门 测试开发知识点(一)测试开发知识点(二)测试开发知识点(三)测试开发知识点(四)测试开发知识点(五) 自动...

  • 测试开发知识点(一)

    传送门 测试开发知识点(一)测试开发知识点(二)测试开发知识点(三)测试开发知识点(四)测试开发知识点(五) 软件...

  • 测试开发知识点(二)

    传送门 测试开发知识点(一)测试开发知识点(二)测试开发知识点(三)测试开发知识点(四)测试开发知识点(五) We...

  • 面试被问到的问题

    传送门测试开发知识点(一)测试开发知识点(二)测试开发知识点(三)测试开发知识点(四)测试开发知识点(五) 1、请...

  • Android热修复总结

    插件化和热修复是Android开发较为高级的知识点,是中级开发人员通向高级开发中必备知识点,插件化知识:插件化。下...

  • Android热修复总结

    插件化和热修复是Android开发较为高级的知识点,是中级开发人员通向高级开发中必备知识点,插件化知识:插件化。下...

  • iOS开发Swift知识点总结(一)

    iOS开发Swift知识点总结(一)

  • JavaWeb技能一栏

    知识点列表: 开发: 1、页面开发:HTML,CSS,JavaScript,jQuery,BootStrap,La...

  • 【Android BLE】蓝牙开发「防丢器」的相关知识点(三)

    蓝牙开发「防丢器」的相关知识点(一):扫描并识别设备 蓝牙开发「防丢器」的相关知识点(二):连接设备并检测连接状态...

  • 【Android BLE】蓝牙开发「防丢器」的相关知识点(二)

    蓝牙开发「防丢器」的相关知识点(一):扫描并识别设备 蓝牙开发「防丢器」的相关知识点(二):连接设备并检测连接状态...

网友评论

    本文标题:开发知识点

    本文链接:https://www.haomeiwen.com/subject/btzbcrtx.html