vue3 onomori-03-toRaw,markRaw, life cycle hook, optional provide and inject, combined provide and inject, add response formula to provide and inject, $refs

Keywords: Javascript Front-end Vue Vue.js

1,toRaw

Returns a proxy object wrapped in reactive or readonly
In fact, it is to convert a proxy object into an ordinary object

<template>
  <div>

  </div>
</template>

<script>

import {ref,reactive,toRaw,readonly,shallowReactive,shallowReadonly,toRefs} from 'vue'

export default {
  name: 'App',
  setup (props,context) {
    //This is an ordinary object
    const obj={
      a:1,
      b:2
    }

    const proxyObj=reactive(obj)//Convert to proxy object
    console.log(proxyObj)//Print as a proxy object
    const newObj=toRaw(proxyObj)//Convert to normal object
    console.log(newObj)//Print as a normal object
    //Before packaging and after conversion are actually equal
    console.log(newObj===obj)//true

    return {

    }
  }
}
</script>

<style>

</style>

2. Mark raw (a bit of raw in photography, original)

Returns the wrapped object itself, which is equal to the original object
This inclusion is shallow, not deep

<template>
  <div>

  </div>
</template>

<script>

import {ref,reactive,toRaw,markRaw,readonly,shallowReactive,shallowReadonly,toRefs} from 'vue'

export default {
  name: 'App',
  setup (props,context) {
    //This is an ordinary object
    const obj={
      a:1,
      b:2
    }

    const rawObj=markRaw(obj)//Wrap as normal object
    console.log(obj)//Print a normal object
    console.log(rawObj)//Still print a normal object
    console.log(obj===rawObj)//true

    const proxyObj=reactive(rawObj)//Wrap as a proxy object
    console.log(proxyObj)//But it still prints ordinary objects

    return {

    }
  }
}
</script>

<style>

</style>

3. Lifecycle hook

Hook, see the previous chapter, omitted

4. Optional provide, inject

Parent component as data provider: Provider


Son.vue

<template>
  <h1>{{sonName}} i am son component</h1>
  <h1>{{directsonname}} directly provider name</h1>

</template>

<script>
  export default {
    name: 'Son',
    inject:['sonName','directsonname'],
    setup(){
      return {

      }
    },
  }
</script>

<style scoped>

</style>

Father.vue

<template>
  <h1>{{fathername}}  i am fahter component</h1>
  <hr/>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  export default {
    name: 'Father',

    setup(){
      const sonName='sonname'

      return {
        sonName
      }
    },
    provide:{
      sonName: 'sonName'
    },
    inject:['fathername'],
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ></Father>
  </div>
</template>

<script>

import {ref,reactive} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {
    const myname=ref('Fathername')

    return {
      myname
    }
  },
  provide:{
    fathername:'Fathername',
    directsonname:'directSonName'
  },
  components:{
    Father,

  }
}
</script>

<style>

</style>

5. Combined Provide,inject

  • It needs to be called in setup
  • provide is used as a function with two parameters. The first parameter is the attribute name and the second parameter is the attribute value
  • The subcomponent inject is the same as the optional provide and inject, and can also be used in the form of functions
  • The inject function also has two parameters, one is the attribute value and the other is the default value

Fther.vue

<template>
  <h1>{{name}}</h1>
  <hr/>
  <h1>{{age}}</h1>
  <hr/>
  <h1>{{hobby}}</h1>
  <hr/>
  <h1>{{career}}</h1>
  <hr/>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  export default {
    name: 'Father',
    inject:['name','age','hobby','career'],

    setup(){
      return {
      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ></Father>
  </div>
</template>

<script>

import {ref,reactive,provide} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {
    provide('name','zhangsan')
    provide('age',30)
    provide('hobby','sing')
    provide('career','programmer')

    return {
    }
  },


  components:{
    Father,

  }
}
</script>

<style>

</style>

Recommended usage (inject is also Ctrip combined):
Father.vue

<template>
  <h1>{{name}}</h1>
  <hr/>
  <h1>{{age}}</h1>
  <hr/>
  <h1>{{hobby}}</h1>
  <hr/>
  <h1>{{career}}</h1>
  <hr/>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  import {inject } from 'vue'
  export default {
    name: 'Father',
    // inject:['name','age','hobby','career'],
    setup(){
      const name=inject('name','the country is prosperous and the people are at peace')
      const age=inject('age','100')
      const hobby=inject('hobby','daqiu')
      const career=inject('career','dadouduo')

      return {
        name,
        age,
        hobby,
        career
      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

app.vue

<template>
  <div>
    <Father ></Father>
  </div>
</template>

<script>

import {ref,reactive,provide} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {
    provide('name','zhangsan')
    provide('age',30)
    provide('hobby','sing')
    provide('career','programmer')

    return {
    }
  },


  components:{
    Father,

  }
}
</script>

<style>

</style>

6. Add a response to provide and inject

Wrap with ref or reactive
Father.vue

<template>
  <h1>{{name}}</h1>
  <hr/>
  <h1>{{age}}</h1>
  <hr/>
  <h1>{{hobby}}</h1>
  <hr/>
  <h1>{{career}}</h1>
  <hr/>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  import {inject } from 'vue'
  export default {
    name: 'Father',
    // inject:['name','age','hobby','career'],
    setup(){
      const name=inject('name','the country is prosperous and the people are at peace')
      const age=inject('age','100')
      const hobby=inject('hobby','daqiu')
      const career=inject('career','dadouduo')

      return {
        name,
        age,
        hobby,
        career
      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ></Father>
    <button @click="changeNumber">change</button>
  </div>
</template>

<script>

import {ref,reactive,provide} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {
    const myname=ref('Xiao San Zhang')
    provide('name',myname)
    provide('age',30)
    provide('hobby','sing')
    provide('career','programmer')

    setTimeout(()=>{
      myname.value='Wang Dana'
    },2000)

    const changeNumber=()=>{
      myname.value='Guo Jingjing'
    }

    return {
      changeNumber
    }
  },


  components:{
    Father,

  }
}
</script>

<style>

</style>

  • Provide can provide not only variables, but also functions
  • Inject can inject (accept) the function provided by provide, so there is no need to write the function (method) in the child component. Because the data is provided by the parent component, it is also recommended to provide a method in the parent component to modify the data. The child component only receives and uses the data transmitted by the parent component
  • When the parent component provides methods, it's best to wrap them with readonly
    Father.vue
<template>
  <h1>{{name}}</h1>
  <hr/>
  <h1>{{age}}</h1>
  <hr/>
  <h1>{{hobby}}</h1>
  <hr/>
  <h1>{{career}}</h1>
  <hr/>
  <button @click="changeName">Change name</button>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  import {inject } from 'vue'
  export default {
    name: 'Father',
    // inject:['name','age','hobby','career'],
    setup(){
      const name=inject('name','the country is prosperous and the people are at peace')
      const age=inject('age','100')
      const hobby=inject('hobby','daqiu')
      const career=inject('career','dadouduo')

      const changeName=inject('changeName')

      return {
        name,
        age,
        hobby,
        career,
        changeName
      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ></Father>
  </div>
</template>

<script>

import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {
    const myname=ref('Xiao San Zhang')
    provide('name',readonly(myname))
    provide('age',30)
    provide('hobby','sing')
    provide('career','programmer')

    const changeName=()=>{
      myname.value='Guo Xiaojing'
    }

    provide('changeName',changeName)



    return {

    }
  },


  components:{
    Father,

  }
}
</script>

<style>

</style>

7. $refs template reference (vue2)

  • Implements a dom operation similar to jquery
  • That is, the subcomponent is named in the form of ref = 'subcomponent name', and the attributes or methods on the subcomponent are operated through $refs. Subcomponent name. Method or attribute
  • $refs can only act as direct child components
    The following example uses the vue2 optional API

Father.vue

<template>
  <h1>{{name}}</h1>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  import {ref,inject } from 'vue'
  export default {
    name: 'Father',
    data(){
      return{
        name:'zhangan'
      }
    },
    methods:{
      changeName(){
        this.name='lisi'
      }
    },

    // inject:['name','age','hobby','career'],
    setup(){

      return {

      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ref="father"></Father>
    <hr/>
    <button @click="changename">Change name</button>
  </div>
</template>

<script>

import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {

    return {
    }
  },

  methods:{
    changename(){
      this.$refs.father.changeName()
    }
  },
  components:{
    Father,

  }
}
</script>

<style>

</style>

8,refs(vue3)

  • When using composite APIs, reactive, ref and templates are unified
  • Declare ref on setup
  • For the attribute name of ref used on the component, a variable consistent with its name must be defined on the setup
  • This variable is used to receive a null value wrapped by ref (the default requirement)
  • Use this ref in the method (get the dom node through this ref and operate)

Father.vue

<template>
  <h1>{{name}}</h1>
  <!--  there ref Your name should be the same as setup The names inside are the same-->
  <h1 ref="mychild">Zhang San</h1>
  <button @click="changeMyName">Change name</button>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  import {ref,inject } from 'vue'
  export default {
    name: 'Father',
    setup(){
      //By default, ref must have a null value. Note that the child here must be consistent with the name of ref on the component
      const mychild=ref(null)
      const changeMyName=()=>{
        //Get the sub component node through mychild and perform dom operation
        mychild.value.innerText='lisi'
      }
      return {
        mychild,
        changeMyName
      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ref="father"></Father>

  </div>
</template>

<script>

import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {

    return {
    }
  },

  methods:{

  },
  components:{
    Father,

  }
}
</script>

<style>

</style>

Another example
Father.vue

<template>
    <!--  there ref Your name should be the same as setup The names inside are the same-->
  <h1 >{{name}}</h1>
  <button @click="changeMyName">Change name</button>
  <Son></Son>
</template>

<script>
  import Son from './Son.vue'
  import {ref,inject } from 'vue'
  export default {
    name: 'Father',
    setup(){
      const name=ref('zhangsan')
      const changeMyName=()=>{
        name.value='lilaosi'
      }
      return {
        name,
        changeMyName
      }
    },
    components:{
      Son
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <Father ref="father"></Father>
    <button @click="setname">set name</button>

  </div>
</template>

<script>

import {ref,reactive,provide,readonly} from 'vue'
import Father from './components/Father.vue'

export default {
  name: 'App',
  setup (props,context) {
    const father=ref(null)

    const setname=()=>{
      father.value.changeMyName()
    }
    return {
      father,
      setname
    }
  },

  methods:{

  },
  components:{
    Father,

  }
}
</script>

<style>

</style>

Posted by Joeker on Thu, 18 Nov 2021 08:03:55 -0800