• vue/composition-api 的使用


    最近我们项目是 vue2,但是要使用 jsx + composition ,所以来学习一下这个 vue/composition-api

    (一)安装

    1. npm install @vue/composition-api
    2. # or
    3. yarn add @vue/composition-api

    (二)注册

    在 main.ts 中

    1. import VueCompositionAPI from '@vue/composition-api'
    2. Vue.use(VueCompositionAPI)

    (三)使用

    最基本的组件:

    1. <template>
    2. <div>HelloWorld</div>
    3. </template>
    4. <script>
    5. import { defineComponent } from '@vue/composition-api'
    6. export default defineComponent({
    7. setup() {
    8. },
    9. })
    10. </script>
    11. <style scoped>
    12. </style>

    defineComponent 本身的功能很简单,但是最主要的功能是为了 ts 下的类型推导~

    1. setup 函数

    setup 在 create 实例在初始化之前调用(setup 函数中不存在 this)。页面上的 属性、方法要从 setup 中拿,需要 setup 中这些属性方法都 return 出去。

    1. <template>
    2. <div>
    3. <div>{{ name }}</div>
    4. <div @click="sayHello">打招呼</div>
    5. <div @click="sayGoodBye">说再见</div>
    6. </div>
    7. </template>
    8. <script>
    9. import { defineComponent } from '@vue/composition-api'
    10. export default defineComponent({
    11. setup() {
    12. // 先注册
    13. const sayGoodBye = () => {
    14. console.log('sayGoodBye')
    15. }
    16. return {
    17. name: 'zfb',
    18. sayHello: () => {
    19. console.log(`hello,`)
    20. },
    21. sayGoodBye,
    22. }
    23. },
    24. })
    25. </script>
    26. <style scoped>
    27. </style>

    2. 相应式 ref,reactive

    使用 ref、reactive 可以使数据变化时,触发页面的更新。ref 处理基础类型数据,是单一的

    改变的时候 改变 .value

    在 @vue/composition-api 中,ref 页面模版渲染是需要 .value 的,reactive 不用

    1. <template>
    2. <div>
    3. <div>{{ name.value }}</div>
    4. <div @click="changeName">改变name</div>
    5. </div>
    6. </template>
    7. <script>
    8. import { defineComponent, ref } from '@vue/composition-api'
    9. export default defineComponent({
    10. setup () {
    11. // 把 name 变成 响应式的 defineObjectProperty
    12. let name = ref('zfb')
    13. // 改变的时候改变 监听的 value
    14. const changeName = () => {
    15. name.value = 'zfb hello'
    16. }
    17. return {
    18. name,
    19. changeName,
    20. }
    21. },
    22. })
    23. </script>
    24. <style scoped>
    25. </style>

    reactive 处理集合

    1. <template>
    2. <div>
    3. <div>{{person.name}}</div>
    4. <div>{{person.age}}</div>
    5. <div>{{person.sex}}</div>
    6. </div>
    7. </template>
    8. <script>
    9. import { defineComponent, reactive } from '@vue/composition-api'
    10. export default defineComponent({
    11. setup () {
    12. // 把 person 变成 响应式的 defineObjectProperty
    13. let person = reactive({
    14. name: 'lyf',
    15. sex: '女',
    16. age: '35'
    17. })
    18. setTimeout(() => {
    19. person.sex = '男'
    20. }, 2000)
    21. return {
    22. person,
    23. }
    24. },
    25. })
    26. </script>
    27. <style scoped>
    28. </style>

    对于数组:

    1. <template>
    2. <div>
    3. <div>{{arr.value}}</div>
    4. <div>{{arr1.value}}</div>
    5. <div>{{arr2.value}}</div>
    6. <div>{{arr3.data}}</div>
    7. </div>
    8. </template>
    9. <script>
    10. import { defineComponent, ref, reactive } from '@vue/composition-api'
    11. export default defineComponent({
    12. setup () {
    13. // 把 person 变成 响应式的 defineObjectProperty
    14. let arr = ref(['123','456','789'])
    15. let arr1 = ref([1])
    16. let arr2 = ref([1, 2, 3])
    17. let arr3 = reactive({
    18. data: [3, 4, 5]
    19. })
    20. setTimeout(() => {
    21. arr.value = ['000','456','789']
    22. arr1.value.push(2)
    23. arr2.value.splice(0, 1, 4)
    24. arr3.data.push(7)
    25. }, 2000)
    26. return {
    27. arr,
    28. arr1,
    29. arr2,
    30. arr3
    31. }
    32. },
    33. })
    34. </script>
    35. <style scoped>
    36. </style>

    readonly 只读:

    1. <script>
    2. import { defineComponent, ref, reactive, readonly } from '@vue/composition-api'
    3. export default defineComponent({
    4. setup () {
    5. const original = reactive({
    6. countA: 0,
    7. foo: {
    8. countB: 0,
    9. }
    10. })
    11. const copy = readonly(original);
    12. original.countA++;
    13. copy.countA++; // 警告
    14. original.foo.countB++;
    15. copy.foo.countB++; // 警告
    16. console.log(original.countA); // 2
    17. console.log(copy.countA); // 2
    18. console.log(original.foo.countB); // 2
    19. console.log(copy.foo.countB); // 2
    20. }
    21. })
    22. </script>
    23. <style scoped>

    能修改 但是会警告

    3. toRefs

    1. <template>
    2. <div>
    3. <!-- 变成了 ref 需要.value
    4. 但是如果在 vue3 中不用 -->
    5. <div>{{ name.value }}</div>
    6. <div>{{ age.value }}</div>
    7. <div>{{ sex.value }}</div>
    8. </div>
    9. </template>
    10. <script>
    11. import { defineComponent, reactive, toRefs } from '@vue/composition-api'
    12. export default defineComponent({
    13. setup () {
    14. // 把 person 变成 响应式的 defineObjectProperty
    15. let person = reactive({
    16. name: 'lyf',
    17. sex: '女',
    18. age: '35'
    19. })
    20. setTimeout(() => {
    21. person.sex = '男'
    22. }, 2000)
    23. // 解构的时候都转换成 ref 的形式
    24. // 不然不具备响应式
    25. const { name, sex, age } = toRefs(person)
    26. return {
    27. name, sex, age
    28. }
    29. },
    30. })
    31. </script>
    32. <style scoped>
    33. </style>

    4. toRef

    toRefs 改变的时候,对象上面是有属性的,但是不排除对象上面一开始没有这个属性的情况,这个时候就需要用到 toRef

    没有使用 toRef 的时候:

    1. <template>
    2. <div>
    3. <!-- 变成了 ref 需要.value
    4. 但是如果在 vue3 中不用 -->
    5. <div>{{ name.value }}</div>
    6. <div>{{ age.value }}</div>
    7. <div>{{ sex.value }}</div>
    8. <div>{{ sex.hobby }}</div>
    9. </div>
    10. </template>
    11. <script>
    12. import { defineComponent, reactive, toRefs } from '@vue/composition-api'
    13. export default defineComponent({
    14. setup () {
    15. // 把 person 变成 响应式的 defineObjectProperty
    16. let person = reactive({
    17. name: 'lyf',
    18. sex: '女',
    19. age: '35'
    20. })
    21. // 解构的时候都转换成 ref 的形式
    22. const { name, sex, age, hobby } = toRefs(person)
    23. // 刚开始没有 hobby 但是后来又有了
    24. // 这个时候发现页面上 2s 之后是不会出现hobby的
    25. setTimeout(() => {
    26. person.hobby = 'ch'
    27. }, 2000)
    28. return {
    29. name, sex, age, hobby
    30. }
    31. },
    32. })
    33. </script>
    34. <style scoped>
    35. </style>

    使用 toRef

    1. <template>
    2. <div>
    3. <!-- 变成了 ref 需要.value
    4. 但是如果在 vue3 中不用 -->
    5. <div>{{ name.value }}</div>
    6. <div>{{ age.value }}</div>
    7. <div>{{ sex.value }}</div>
    8. <div>{{ hobby.value }}</div>
    9. </div>
    10. </template>
    11. <script>
    12. import { defineComponent, reactive, toRef, toRefs } from '@vue/composition-api'
    13. export default defineComponent({
    14. setup () {
    15. // 把 person 变成 响应式的 defineObjectProperty
    16. let person = reactive({
    17. name: 'lyf',
    18. sex: '女',
    19. age: '35'
    20. })
    21. // 解构的时候都转换成 ref 的形式
    22. const { name, sex, age, } = toRefs(person)
    23. // 针对原本对象上没有的情况
    24. let hobby = toRef(person, 'hobby')
    25. // 刚开始没有 hobby 但是后来又有了
    26. // 这个时候发现页面上 2s 之后会出现hobby的
    27. setTimeout(() => {
    28. hobby.value = 'ch'
    29. }, 2000)
    30. return {
    31. name, sex, age, hobby
    32. }
    33. },
    34. })
    35. </script>
    36. <style scoped>
    37. </style>

    但是还是建议,初始化的时候,给一个空的

    1. let person = reactive({
    2. name: 'lyf',
    3. sex: '女',
    4. age: '35',
    5. hobby: ''
    6. })

  • 相关阅读:
    商业数据分析概论
    XXE XML外部实体注入
    c++1237. 找出给定方程的正整数解,四种解法(二分+有限状态机)
    提升药店效率:山海鲸医药零售大屏的成功案例
    设计模式-访问者模式-笔记
    AD拼板技巧
    图神经网络模型扩展(5)--2
    腾讯待办是什么?关停之后如何继续提醒待办事项?
    七大排序:插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序
    AQS源码解析 2.简介 & 内部核心结构
  • 原文地址:https://blog.csdn.net/Luckyzhoufangbing/article/details/126890530