当前位置:网站首页>Composite API

Composite API

2022-06-23 05:32:00 tianruine

setup()

Basic use

The principle is what we wrote before options API It has been written. API-composition-api

First let's create one vue Suffix file name , Then the content is like this

Be careful : stay setup() Cannot access this

<script>
import { ref } from 'vue' // from vue Inside handle combination Api Deconstruct 
export default {
  data() {  // This is the same as before optioons API
    return {
      title: 'hello'
    }
  },

  setup() {  // The use in this function is composition API
    const counter = ref(0)

    //  Cannot access  this
    // console.log(this.title)

    return {
      counter
    }
  },

  mounted() {
    console.log(this.counter)
  }
}
</script>

<template>
  <h1>{
   {counter}}</h1>
</template>

<style>
  
</style>

visit props

Be careful : In combination API ref perhaps reactive wait API It has the characteristics of responsiveness , But if you pass props Pass the data with response yes from the parent component to the child element , Use it directly props.obj, Such data is responsive , It refers to passing an object , This object has a response , But if you pass props If a value is passed, there will be no response , There is no response feature when using child elements , If you want him to be responsive , Can pass toRef, perhaps toRefs To pass

Example : In parent element

<script>
import { onMounted, reactive, ref, watchEffect,toRef } from 'vue'
import Child from './Child.vue'
export default {
  setup() {
    const title = ref('hello')

    const obj = reactive({
      x: 100,
      y: 200
    })
    onMounted(() => {
      setTimeout(() => { // Timer change , See if the child element has a response 
        title.value = 'world'
        obj.x = 1000
        obj.y = 2000
      }, 2000)
    })
    return {
      title,
      obj
    }
  },

  components: {
    Child
  }
}
</script>

<template>
  <Child :title="title" :obj="obj"></Child> // Here, the value of the parent element is passed to the child element through the custom attribute 
</template>

In the child component

<script>
import { toRef, toRefs } from 'vue'

export default {
  props: ['title', 'obj'], // Receive the value passed by the parent component here 

  setup(props) {
     const {obj} = props // Directly here 2 deconstruction props The objects passed in are responsive 
    // const{title}=props// There is no response formula for the value inside 
     //const obj=props.obj  What is passed in is that an object has a response 
    const x = toRef(props.obj, 'x')// It was written as const x = props.obj.x There is no response , need toRef To make him responsive 
    const title = toRef(props, 'title')// const title = props.title No response 
    const { title: title2, obj: { value } } = toRefs(props)
    const y = toRef(value, 'y')// adopt toRefs You can directly props The values inside make it responsive , However, when an object is also used, the values inside it need to be toRef perhaps toRefs

    return {
      
      title,
      title2,
      x,
     y,
      obj
      
    }
  }
}
</script>

<template>
  <h1>{
   {title}}</h1>
  <h1>{
   {title2}}</h1>
   <h1>{
   {x}}</h1>
     <h1>{
   {y}}</h1>
  {
   {obj}}

</template>

setup The context of

1、attrs: Value as object , contain : Passed from outside the component , But not in props Properties declared in the configuration , amount to  this.$attrs.

During the communication between parent and child components , The parent component passes the data , If the subcomponent is useless props Receive , It will appear in attrs in , and vm There is no

for example : Passed from the parent component

stay child Not used in component props receive , stay setup in console.log(attrs); Namely

  Be careful. , The difference between adding a colon to an attribute and not adding a colon is , The variables in the parent component are passed by adding a colon , Without a colon is a string obj, character string title, This is also called father son communication , Reasons for adding colons to custom attributes , What is passed without a colon is the string value of the property

2、emit: Functions that distribute custom events , amount to  this.$emit.

In the parent element

The event is triggered in the sub component and the value can be passed

3、slots: Received slot contents , amount to  this.$slots 

4.expose() adopt ref What offspring want to expose to

for example , Bind the child element to the parent element ref

In child element  setup Function

Then go to the parent element ref You can only get this {x:100}

  Used with render functions

import { h } from 'vue'
export default {
  setup() {
    return () => h('div', {class: 'abc'}, h('a', {href: 'http://www.baidu.com'}, ' Baidu '))
  }   //h The first argument to the function is the root node , The second parameter is the attribute , The third parameter is the child node 
}
</script>
<template>
</template>

Page structure

Combine API

import { ref, onMounted, reactive, computed, readonly, watchEffect, watch } from 'vue'

ref Make the attribute responsive

Generally, the basic data types are written inside

Example :

 setup() {
    const counter = ref({
      x: 100,
      y: {
        a: 300
      }
    })
onMounted(() => {
      setTimeout(() => {
        counter.value.x = 10000 // Pay attention here setup When used in a function, you must .value
        counter.value.y.a = 30000
      }, 3000)
    })

    return {
      counter  // If you use it outside, you must return get out 
    }

}

reactive

It is also to make the data responsive , It is usually written in complex data types ,

const count = ref(0)
    const obj = reactive({
      count
    })

    obj.count++
    console.log(obj.count)

    count.value = 100
    console.log(obj.count)

    obj.count = 200
    console.log(count.value)

    const books = reactive([ref('JavaScript Learning Guide ')])
    books[0].value = 'html Learning Guide '
    console.log(books[0].value)

    const map = reactive(new Map([['count', ref(0)]]))
    console.log(map.get('count').value)
    map.set('count.value', 300)
    console.log(map.get('count').value)

computed()  Compute properties

   const count = ref(0)
    const addOne = computed(() => count.value + 1) // Write a callback inside , When the value inside changes, it will trigger 
    console.log(addOne.value)
    count.value++
    console.log(addOne.value)

readonly() Read-only property

const original = reactive({ count: 0 })
    const copy = readonly(original)
    original.count = 100 // But the assignment changes , This read-only will also become 100
    // copy.count = 200 // Because it is read-only, it cannot be changed 
    console.log(copy.count) //100

watchEffect()

There is a characteristic , And mobx Inside autorun equally , At the very beginning

 const count = ref(0)
    const title = ref('line1')
    const stop = watchEffect(() => console.log(count.value + title.value)) //  Always perform once  
    stop()
    count.value = 100
    count.value = 100 // Because the value of the two changes is the same , So it will be executed once 
    title.value = 'line2'

watch() monitor

  const state = reactive({count: 0})
    watch(
      () => state.count, // It becomes two parameters , The first argument is the function , The returned value is the monitored value 
      (count, prevCount) => {
        console.log(count)
        console.log(prevCount)
      }
    )

    state.count++

 watch And watcheffect difference :

  • Execution opportunity :watchEffect It's immediate , It will be actively executed once when the page is loaded , To collect dependency ; and watch Is the inert execution of side effects , It will not be executed immediately , But you can configure immediate, Make it active trigger
  • Different parameters :watchEffect Just pass a callback function , There is no need to pass the listening data , It will actively execute once when the page is loaded , To collect dependency ; and watch There must be at least two parameters ( The third parameter is the configuration item ), The first parameter is the listening data , The second parameter is the callback function
    The results are different :watchEffect Cannot get the value before the change ; and watch You can get both pre - and post - change values
     

Type judgment

import { ref, isRef, readonly, computed, reactive, unref, toRef, toRefs, isProxy, isReactive, isReadonly } from 'vue'

isRef Judgment is not ref type

Pay attention to pass computed To deal with the ref The type is also ref type

  const count = ref(0)
    const count2 = 0
    const count3 = readonly(count)
    const count4 = computed(() => count.valut + 2)
    const count5 = reactive({x: 0})
    console.log(isRef(count)) //1
    console.log(isRef(count2))//0
    console.log(isRef(count3))//0
    console.log(isRef(count4))//1
    console.log(isRef(count5))//0

unref() No ref Type of

unref( Parameters )

isReactive() 

Check whether an object is created by  reactive  perhaps  readonly  Method .

 const msg = readonly(ref(2))    
    const msg1 = reactive({a:2})
    const msg2 = ref(2)
    const msg3 = {}
    console.log(isProxy(msg))//1
    console.log(isProxy(msg1))//1
    console.log(isProxy(msg2))//0
    console.log(isProxy(msg3))//0

isReadonly() Judgment is not readonly type

const msg = readonly(reactive({}))
    const msg2 = ref(0)
    console.log(isReadonly(msg))//1
    console.log(isReadonly(msg2))//0

stay setup The life cycle of a function

- `beforeCreate` -> Use `setup()`
- `created` -> Use `setup()`
- `beforeMount` -> `onBeforeMount`
- `mounted` -> `onMounted`
- `beforeUpdate` -> `onBeforeUpdate`
- `updated` -> `onUpdated`
- `beforeDestroy` -> `onBeforeUnmount`
- `destroyed` -> `onUnmounted`

stay setup Function provide And inject

In the upper assembly

export default {
    components: {
      Child
    },

    setup() {
      const title = ref('hello') // Delivery in this way is responsive 
       provide('title',title) // The first is the variable name , The second is the parameter passed , If there are more than one transmission title Can pass an object , Take the value again at that time , If you want to pass multiple variables, you need to define multiple provide 了 
    }
  }}

In the lower assembly inject When receiving

export default {
  setup() {
    //const title = inject('title', 'hello') r If provide The second parameter is the default value when no value is transferred 
    const title = inject('title')  adopt inject Get it in provide Defined 'title' Variable 
    return {
      title
    }
  }
}

setup Grammatical sugar of function

Only need <script setup></script> The label says setup That's all right.

Example 1:

<script setup>
  import { ref, provide } from 'vue'
  import Child from './Child.vue'
// It was written in the following way , There is no annotation after the label is added , no need return Data , no need components Write subcomponents 
  // export default {
  //   components: {
  //     Child
  //   },

  //   setup() {  //
  //     const title = ref('hello')

  //     // provide('title')
  //   }
  // }
  const title = ref('hello')
  provide('title', title)
</script>
<template>
  <Child></Child>
</template>
<style>
</style>

When there are parameters , for example props Writing

<script>
import { toRef, toRefs } from 'vue'
export default {
  props: ['title', 'obj'],

 setup(props){
     const obj=props.obj
     console.log(props)
       const {title:title4}=props
    const x = toRef(props.obj, 'x')

    return {
      
      x,
      obj,
      title4
    // }
 }
    
}
  
}

</script>

<template>
   <h1>{
   {x}}</h1>
  {
   {obj.x}}
  {
   {title4}}
</template>

How to write sugar , Unwanted return, Unwanted export default, But pay attention to the way the receiving parameters are written props, be used defineProps(), You can write an array or an object

<script setup>
import { toRef, toRefs } from 'vue'

 // props: ['title', 'obj'],

 const props = defineProps(['title', 'obj'])
     //const obj = props
     const obj=props.obj
     console.log(props)
       const {title:title4}=props
    const x = toRef(props.obj, 'x')
    

    // return {
      
    //   //title,
    //  // title2,
    //   x,
    //   obj,
    //   title4
    // }
  

</script>

<template>
   <h1>{
   {x}}</h1>
  {
   {obj.x}}
  {
   {title4}}
</template>

context When the parameter in

defineProps  and  defineEmits

stay  <script setup>  Must use  defineProps  and  defineEmits API To declare  props  and  emits , They have complete type inference and are in  <script setup>  Is directly available in :

emit use defineEmits

<script setup>
const props = defineProps({
  foo: String
})

const emit = defineEmits(['change', 'delete'])
// setup code
</script>
  • defineProps  and  defineEmits  Only in  <script setup>  Can only be used in Compiler macro . They don't need to import and will follow  <script setup>  The process is compiled together .

  • defineProps  Receiving and  props  Options The same value ,defineEmits  Also receive  emits  Options The same value .

  • defineProps  and  defineEmits  After the option is passed in , Will provide appropriate type inference .

  • The incoming to  defineProps  and  defineEmits  The options will be from setup Promoted to the scope of the module . therefore , The passed in option cannot be referenced in setup Local variables declared in the scope . Doing so will cause compilation errors . however , it Sure Reference imported bindings , Because they are also within the scope of the module .

Use  <script setup>  The components of are Off by default Of , That is, through the template ref perhaps  $parent  The public instance of the component obtained by the chain , Will not expose anyone to  <script setup>  Binding declared in .

defineExpose

In order to be in  <script setup>  The explicit attributes to be exposed in the component , Use  defineExpose  Compiler macro :

expose() Writing

<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

defineExpose({
  a,
  b
})
</script>

useSlots  and  useAttrs

stay  <script setup>  Use  slots  and  attrs  The situation should be very rare , Because you can pass through... In the template  $slots  and  $attrs  To visit them . In rare situations where you really need to use them , It can be used separately  useSlots  and  useAttrs  Two auxiliary functions :

<script setup>
import { useSlots, useAttrs } from 'vue'

const slots = useSlots()
const attrs = useAttrs()
</script>

useSlots  and  useAttrs  Is a real runtime function , It will return with  setupContext.slots  and  setupContext.attrs  Equivalent value , It can also be used in ordinary combination API Use in

原网站

版权声明
本文为[tianruine]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230240229647.html