美文网首页
Vue3 组合式API.md

Vue3 组合式API.md

作者: RayLightUp | 来源:发表于2021-09-24 15:37 被阅读0次

    组合式API

    介绍

    什么是组合式 API(composition API)

    • 组合式 API 是 Vue3 提供的新功能,为我们提供了另一种编写组件的方式
    • 代码共享。在 setup 钩子里面,可以按逻辑上的关注点来对代码进行分组,并与其他组件共享代码。

    组合式 API 的出现解决了什么样的问题

    • 随着Vue项目规模和复杂性的增加,现有 Option API 变得难以应付
    • 逻辑并没有真正地按功能分组,这可能会让人很难读懂一个庞大而复杂的组件文件。
    • 通过 Option API 实现组件间共享重复的逻辑(共享代码)比较麻烦
    • 通过组合时 API 我们可以将重用逻辑封装为功能,这个功能可以组件间共享,这样你就可以在整个应用程序的不同组件中使用这些逻辑。

    接口

    setup

    执行时间

    优先于beforeCreate 和 created。setup 选项在组件创建之前执行,一旦 props 被解析,就将作为组合式 API 的入口。

    参数
    1. props:组件传入的属性
    2. context

    setup中接受的props是响应式的,当传入新的props会被及时更新。在setup中不能直接访问到this对象。

    所以在setup中定义props,用这样的方式

    defineProps({
      msg: String
    })
    

    context是一个普通的JavaScript对象,它暴露组件的三个property
    context.attrs, context.slots, context.emit

    组合式API生命周期函数
    组合式api生命周期
    
    onBeforeMount
    onMounted
    onBeforeUpdate
    onUpdated
    onUnmounted ( -> destroyed)
    onActivated ( -> activited)
    onDeacitivated ( ->deacitivated)
    onRenderTriggered
    onRenderTricked
    

    reactive 和 ref

    reactive 和 ref的作用都是定义和跟踪需要双向绑定的变量。也就是数据定义,将一个普通对象变为响应式对象。

    ref 接收参数并将其包裹在一个带有 value property 的对象中返回,然后可以使用该 property 访问或更改响应式变量的值

    toRefs的作用就是,将一个reactive对象转化为属性全部为ref对象的普通对象

    <template>
    <div> {{ month }}</div>
    </template>
    <script>
    import {ref,reactive,toRefs } from "vue"
    
    export default defineComponent({
     setup() {
        const year = ref(0)
        const date = reactive({
            month: 1
            minutes:200
        })
        
        return {
            year,
            ...toRefs(date)
        }
     }
    )
    </script>
    
    
    

    isRef

    isRef用于判断变量是否为ref对象

    const unwrapped = isRef(foo) ? foo.value : foo
    

    computed

    computed函数与vue2中computed功能一致,它接收一个函数并返回一个value为getter返回值的不可改变的响应式ref对象。

    const count = ref(1)
    const plusOne = computed(() => count.value + 1)
    console.log(plusOne.value) // 2
    plusOne.value++ // 错误,computed不可改变
    
    // 同样支持set和get属性
    onst count = ref(1)
    const plusOne = computed({
      get: () => count.value + 1,
      set: val => { count.value = val - 1 }
    })
    plusOne.value = 1
    console.log(count.value) // 0
    
    

    watch

    用法

    • 指定依赖源:
      在基础用法中,
      当依赖了多个reactive或ref是无法直接看到的,需要在回调中寻找.
    <template>
      <div>
        <input type="text" v-model="state.count">{{state.count}}
        <input type="text" v-model="inputRef">{{inputRef}}
      </div>
    </template>
    <script>
      import {watch, reactive, ref} from 'vue'
    
      export default {
        setup() {
          const state = reactive({count: 0})
          const inputRef = ref('')
          // state.count与inputRef中任意一个源改变都会触发watch
          watch(() => {
            console.log('state', state.count)
            console.log('ref', inputRef.value)
          })
          return {state, inputRef}
        }
      }
    </script>
    
    
    • 指定依赖源
    <template>
      <div>
        state2.count: <input type="text" v-model="state2.count">
        {{state2.count}}<br/><br/>
        ref2: <input type="text" v-model="ref2">{{ref2}}<br/><br/>
      </div>
    </template>
    <script>
      import {watch, reactive, ref} from 'vue'
    
      export default {
        setup() {
          const state2 = reactive({count: ''})
          const ref2 = ref('')
          // 通过函数参数指定reative依赖源
          // 只有在state2.count改变时才会触发watch
          watch(
            () => state2.count,
            () => {
              console.log('state2.count',state2.count)
              console.log('ref2.value',ref2.value)
          })
          // 直接指定ref依赖源
          watch(ref2,() => {
            console.log('state2.count',state2.count)
            console.log('ref2.value',ref2.value)
          })
    
          return {state, inputRef, state2, ref2}
        }
      }
    </script>
    
    
    • 指定多个数据源
    <template>
      <div>
        <p>
          <input type="text" v-model="state.a"><br/><br/>
          <input type="text" v-model="state.b"><br/><br/>
        </p>
        <p>
          <input type="text" v-model="ref1"><br/><br/>
          <input type="text" v-model="ref2"><br/><br/>
        </p>
      </div>
    </template>
    
    <script>
      import {reactive, ref, watch} from 'vue'
    
      export default {
        setup() {
          const state = reactive({a: 'a', b: 'b'})
          // state.a和state.b任意一个改变都会触发watch的回调
          watch(() => [state.a, state.b],
           // 回调的第二个参数是对应上一个状态的值
           ([a, b], [preA, preB]) => {
            console.log('callback params:', a, b, preA, preB)
            console.log('state.a', state.a)
            console.log('state.b', state.b)
            console.log('****************')
          })
    
          const ref1 = ref(1)
          const ref2 = ref(2)
          watch([ref1, ref2],([val1, val2], [preVal1, preVal2]) => {
            console.log('callback params:', val1, val2, preVal1, preVal2)
            console.log('ref1.value:',ref1.value)
            console.log('ref2.value:',ref2.value)
             console.log('##############')
          })
          return {state, ref1, ref2}
        }
      }
    </script>
    
    
    • 取消watch
    <template>
      <div>
        <input type="text" v-model="inputRef">
        <button @click="onClick">stop</button>
      </div>
    </template>
    
    <script>
      import {watch, ref} from 'vue'
    
      export default {
        setup() {
          const inputRef = ref('')
          const stop = watch(() => {
            console.log('watch', inputRef.value)
          })
          const onClick = () => {
            // 取消watch,取消之后对应的watch不会再执行
            stop()
          }
          return {inputRef, onClick}
        }
      }
    </script>
    
    
    • onCleanyp函数:watch提供了一个onCleanup的副作用清除函数,该函数接收一个函数,在该函数中进行副作用清除。那么onCleanup什么时候执行?

      • watch的callback即将被第二次执行时先执行onCleanup。
      • watch被停止时,即组件被卸载之后。
        -watch选项
    • deep
      深层对象的任意一个属性的改变都会出发回调的执行

    <template>
      <div>
        <button @click="onClick">CHANGE</button>
      </div>
    </template>
    <script>
      import {watch, ref} from 'vue'
    
      export default {
        setup() {
          const objRef = ref({a: {b: 123}, c: 123})
          watch(objRef,() => {
            console.log('objRef.value.a.b',objRef.value.a.b)
          }, {deep: true})
          const onClick = () => {
            // 设置了deep之后,深层对象任意属性的改变都会触发watch回调的执行
            objRef.value.a.b = 780
          }
          return {onClick}
        }
      }
    </script>
    
    

    相关文章

      网友评论

          本文标题:Vue3 组合式API.md

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