Vue3 快速掌握,了解常用新特性(适用于会 Vue2.0 开发的)(下)

简介: Vue3 快速掌握,了解常用新特性(适用于会 Vue2.0 开发的)(下)

五、toReftoRefs 函数

  • toReftoRefs的使用区别
  • toRef : 将一个数据变成响应式数据。
  • toRefs: 将多个数据变成响应式数据。
  • reactive 定义的对象,如果直接用 ... 解构,就会失去响应式的特点,然而使用 toRef() 或 toRefs() 解构,则可以保留响应式特点。总结:解构之后还具有响应式
let { 属性1, 属性2 } = toRefs(响应式数据)
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton">{{ user.name }}</div>
</template>
<script>
import { defineComponent, toRef, toRefs, reactive } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const user = reactive({
      id: 1,
      name: 'dzm'
    })
    // 通过 toRef 取值,保留响应式特点(通过 key 单个取值)
    // let name = toRef(user, 'name')
    // 通过 toRefs 取值,保留响应式特点
    let { name } = toRefs(user)
    // 点击按钮
    function touchButton () {
      // 修改值
      name.value = 'xyq'
    }
    // 返回
    return {
      user,
      name,
      touchButton
    }
  }
})
</script>

六、computed 函数

  • computed支持getset写法,普通写法只用到了get
  • 普通写法:返回值就是计算属性的值
import { computed } from 'vue'
const 计算属性名 = computed(() => {
  return 响应式数据相关计算
})
  • 高阶写法:get 返回的是计算属性的值,set 监听计算属性的变化( v-model 绑定计算属性)
import { computed } from 'vue'
const 计算属性名 = computed(() => {
  // 取值
  get: () => { }
  // 赋值
  set: (val) => { }
})
  • 普通写法
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton">{{ newAge }}</div>
</template>
<script>
import { defineComponent, ref, computed } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const age = ref(1)
    // 计算方法
    const newAge = computed(() => {
      return age.value * 10
    })
    // 点击按钮
    function touchButton () {
      // 修改值
      age.value += 1
    }
    // 返回
    return {
      age,
      newAge,
      touchButton
    }
  }
})
</script>
  • 高阶写法(getset 组合使用)
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton">{{ newAge }}</div>
</template>
<script>
import { defineComponent, ref, computed } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const age = ref(1)
    // 计算方法
    const newAge = computed({
      // 取值
      get: () => {
        return age.value * 10
      },
      // 赋值
      set: (val) => {
        age.value = val / 10
      }
    })
    // 点击按钮
    function touchButton () {
      // 修改值
      age.value += 1
    }
    // 返回
    return {
      age,
      newAge,
      touchButton
    }
  }
})
</script>

七、watch 函数

  • 监听深层次对象时,新旧对象的值都会发生变化,watch是惰性的,页面第一次加载时不触发watch函数,只有监听的数据发生变化时,才会触发watch函数。
  • 使用 deep为深层次监听
  • 使用 immediate 为第一次直接触发,默认第一次不触发
  • 监听格式
watch(监听参数, 新旧值变化回调, 配置)
// 监听普通属性
watch(age, (newVal, oldVal) => { console.log('变化了') })
// 监听 json 数据
watch(json, (newVal, oldVal) => { console.log('变化了') }, { immediate: true, deep: true })
// 监听多个数据
watch([age, json], (newVal, oldVal) => { console.log('变化了') }, { immediate: true, deep: true })
  • 使用案例
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton">{{ age }}</div>
</template>
<script>
import { defineComponent, ref, reactive, watch } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const age = ref(1)
    const user = reactive({
      id: 1,
      name: 'dzm'
    })
    // 监听普通数据
    watch(age, (newVal, oldVal) => {
      console.log('Age 变化:', newVal, oldVal)
    })
    // 监听深层次数据
    watch(user, (newVal, oldVal) => {
      console.log('User 变化:', newVal, oldVal)
    }, { immediate: true, deep: true })
    // 监听多个数据
    watch([age, user], (newVal, oldVal) => {
      console.log('Age User 变化:', newVal, oldVal)
    }, { immediate: true, deep: true })
    // 点击按钮
    function touchButton () {
      // 修改值
      age.value += 1
      user.id += 1
    }
    // 返回
    return {
      age,
      touchButton
    }
  }
})
</script>

八、watchEffect 函数(高级监听)

  • watchEffect 是非惰性的,一开始就会自动调用一次,可配置 执行时机,还可以监听某个值之前,可以先执行一个函数。
  • 在页面第一次加载时就会触发,并且会一直监听追踪内部使用的响应式数据,只要追踪的响应式数据发生变化,watchEffect 都会运行。
  • 也可以监听多个参数,只是不能监听对象,因为他无法监测对象内部的变化,可能是watchEffect 无法实现深度监听吧(具体原因还不清楚)。
  • 普通监听使用
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton">{{ age }}</div>
  <div @click="touchStop">停止监听</div>
</template>
<script>
import { defineComponent, ref, reactive, watchEffect } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const age = ref(1)
    const user = reactive({
      id: 1,
      name: 'dzm'
    })
    // 普通监听使用
    const stop = watchEffect(() => {
      console.log(age.value, user.id)
    })
    // 点击按钮
    function touchButton () {
      // 修改值
      age.value += 1
      user.id += 1
    }
    // 停止监听
    function touchStop () {
      stop()
    }
    // 返回
    return {
      age,
      touchButton,
      touchStop
    }
  }
})
</script>
  • 高级监听使用
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton">{{ age }}</div>
  <div @click="touchStop">停止监听</div>
</template>
<script>
import { defineComponent, ref, reactive, watchEffect } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const age = ref(1)
    const user = reactive({
      id: 1,
      name: 'dzm'
    })
    // 监听值变化之前,会先执行一下函数,无论什么位置,都会先执行函数,在执行其他内容,只有在监听值发生变化时,才会触发
    const stop = watchEffect((oninvalidata) => {
      // 在函数前面输入一下
      console.log('oninvalidata - 前', age.value, user.id)
      // 先执行这个函数,可以用来提前处理一些需要的东西
      oninvalidata(() => {
        console.log('before')
      })
      // 在函数后面输入一下
      console.log('oninvalidata - 后', age.value, user.id)
    }, {
      // 执行时机: pre(组件更新前)、sync(强制效果始终同步)、post(组件更新后执行)
      flush: 'post', // dom 加载完毕后执行
      // 数据发生变化时,比上面的 oninvalidata 函数还会先调用
      onTrigger(e) {
        console.log('onTrigger')
        // console.log(e) // 数据变化信息,可以在这里拿到新旧值、变化对象、变化类型、变化key
        // debugger // 用于 debugger 调试
      }
    })
    // 这里是上面监听的输出结果:
    // 1、oninvalidata - 前 1 1
    // 2、oninvalidata - 后 1 1
    // 3、onTrigger
    // 4、onTrigger
    // 5、before
    // 6、oninvalidata - 前 2 2
    // 7、oninvalidata - 后 2 2
    // 第 1、2 行是初始化默认调用的第一次
    // 第 3、4 行是监听到值变化之后调用的,如果多个数据同时发生改变,每个数据都会调用一遍
    // 第 5、6、7 行是监听到变化之后调用的,如果多个数据同时发生改变,只触发一次
    // 点击按钮
    function touchButton () {
      // 修改值
      age.value += 1
      user.id += 1
    }
    // 停止监听
    function touchStop () {
      stop()
    }
    // 返回
    return {
      age,
      touchButton,
      touchStop
    }
  }
})
</script>

九、emit 函数 与 emits 自定义事件注册

  • 子组件中所有自定义事件都需要在 emits 中进行注册,不然会报警告:
[Vue warn]: Extraneous non-emits event listeners (success1, success2) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.
  • 子组件自定义事件
<template>
  <div @click="touchButton1">点击按钮1</div>
  <div @click="touchButton2">点击按钮2</div>
</template>
<script>
export default {
  // 申明自定义事件
  emits: ['success1', 'success2'],
  setup (props, context) {
    // 点击按钮1
    function touchButton1 () {
      context.emit('success1')
    }
    // 点击按钮2
    function touchButton2 () {
      context.emit('success2')
    }
    // 返回
    return {
      touchButton1,
      touchButton2
    }
  }
}
</script>
  • 父组件接受事件
<template>
  <Temp @success1="touchButton1" @success2="touchButton2"></Temp>
</template>
<script>
import Temp from './Temp.vue'
import { defineComponent } from 'vue'
export default defineComponent({
  components: {
    Temp
  },
  setup () {
    // 点击按钮1
    function touchButton1 () {
      console.log('点击按钮1')
    }
    // 点击按钮2
    function touchButton2 () {
      console.log('点击按钮2')
    }
    // 返回
    return {
      touchButton1,
      touchButton2
    }
  }
})
</script>

十、readonlyshallowReadonly 函数

  • readonly 为深只读,shallowReadonly 为浅只读。


十、reactiveshallowReactive 函数

  • reactive 为深劫持,shallowReactive 为浅减持。
  • 按上面 九、 的同类型数据,被 reactive 劫持的数据,修改任何层级的数据都会刷新页面,被 shallowReactive 劫持的数据,修改深层级的数据都不会刷新页面,只有第一层次的会刷新页面。

十一、toRaw 函数

  • toRaw: 将一个 reactive 生成的响应式对象转换为普通对象。
<script>
import { defineComponent, reactive, toRaw } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const user = reactive({
      id: 1,
      name: 'dzm',
      job: {
        salary: 30
      }
    })
    // 点击按钮
    function touchButton () {
      console.log(user) // Proxy {id: 1, name: 'dzm', job: {…}}
      const user1 = toRaw(user) // 将一个 reactive 生成的响应式对象转换为普通对象
      console.log(user1) // {id: 1, name: 'dzm', job: {…}}
    }
    // 返回
    return {
      user,
      touchButton
    }
  }
})
</script>

十二、markRaw 函数

  • markRaw:标记一个对象,使其永远不再成为响应式的数据
<template>
  <!-- 模板中使用 -->
  <div @click="touchButton1">新增数据</div>
  <div @click="touchButton2">叠加数据 {{ user.job && user.job.salary }}</div>
</template>
<script>
import { defineComponent, reactive, markRaw } from 'vue'
export default defineComponent({
  setup () {
    // 定义响应式属性
    const user = reactive({
      id: 1,
      name: 'dzm'
    })
    // 新增数据
    function touchButton1 () {
      // 通过 reactive 包装后,默认增加数据,是支持响应式的
      // user.job = { salary: 10 }
      // 但是增加的数据通过 markRaw 包装之后,是不支持响应式的
      user.job = markRaw({ salary: 10 })
    }
    // 增加数值
    function touchButton2 () {
      // user.job.salary 无论是支持或不支持响应式,值都会变化
      // 但是不支持响应式,则值变页面不变,支持响应式,则值变页面也变
      if (user.job) { user.job.salary += 1 }
      // 无论支持与否,输出值是在增加变化的
      console.log(user.job.salary)
    }
    // 返回
    return {
      user,
      touchButton1,
      touchButton2
    }
  }
})
</script>

十三、其他的后续会持续更新

  • 但是基本掌握上面的也就能进入正常开发了,其他情况的现查现用就行了!


相关文章
|
14天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
18天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
40 7
|
19天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
39 3
|
18天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
36 1
|
18天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
39 1
|
20天前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
|
8天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
8天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
8天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
8天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。