One article takes you to master the new features of Vue3, and you are no longer afraid of the interviewer~

Posted by kettle_drum on Fri, 04 Mar 2022 02:41:08 +0100

preface

Take notes and share some common Vue3 new features and which methods have changed.

I only write some commonly used here. For more, please see the Vue3 official website here

Interested parties can pay attention to the official account: front-end entertainment.

Component v-model support parameters

In vue2 When x, if we want to pass values to sub components, we have to pass them in separately. Vue3.x directly passes in the parameter in the form of v-model:xxx, and cooperates with the modifier sync for data synchronization update.

App.vue

<template>
  <div>
  {{title}} 
  <input v-model:title="title">
  </div>
</template>
<script>
import Input from "./components/Input"
export default {
  name: 'App',
  components: {
    Input
  },
  data() {
    return {
      title: "Frogman",
    }
  },
}
</script>

Input.vue

<template>
  <div class="Input">
      <input type="text" @input="first" :value="title">
  </div>
</template>
<script>
export default {
 name: 'Input',
  props: {
    title: {
        default: () => "Frogman"
    }
  },
  methods: {
      first(e) {
          this.$emit("update:title", e.target.value)
      },
  },
}
</script>

effect

The component supports multiple v-model s

In vue3 X supports the creation of multiple v-model bindings on a single component.

App.vue

<template>
  {{title}}
  {{name}}

  <input v-model:title="title" v-model:name="name">
</template>

<script>
import Input from "./components/Input"
export default {
  name: 'App',
  components: {
    Input,
  },
  data() {
    return {
      title: "Frogman",
      name: "www"
    }
  },
}
</script>

Input.vue

<template>
  <div class="Input">
      <input type="text" @input="first" :value="title">
      <input type="text" @input="last" :value="name">
  </div>
</template>
<script>
export default {
 name: 'Input',
  props: {
    title: {
        default: () => "Frogman"
    },
    name: {
        default: () => "Front end entertainment circle"
    }
  },
  methods: {
      first(e) {
          this.$emit("update:title", e.target.value)
      },
      last(e) {
          this.$emit("update:name", e.target.value)
      }
  }
}
</script>

effect

Setup

The setup function is a new component option. As an entry point for using Composition Api within a component. Let's explain it in four aspects

  • Call timing
  • this point
  • Function parameters
  • Return value

Call timing

Create a component instance, then initialize props, and then call the setup function. From a lifecycle perspective, it will be executed before beforeCreate. That is, to create a component, first execute setup, beforeCreate and create.

<template>
  <div>Frogman</div>
</template>
<script>
export default {
  name: 'App',
  setup() {
    console.log("hey Frogman")
  }
}
</script>

this point

In order to avoid using vuundo and vudefine in the function of setup, you cannot use vuundo in the function of this.

<template>
  <div>Frogman</div>
</template>
<script>
export default {
  name: 'App',
  setup() {
    console.log(this); // undefined
  }
}
</script>

Function parameters

  • props
  • context

props

Receive all the data passed by the component, and they are all responsive.

<template>
  <div>Frogman</div>
</template>
<script>
export default {
  name: 'App',
  props: {
      title: {
          type: String
      }
  },
  setup(props) {
    console.log(props.title)
  }
}
</script>

>Note that props data cannot be deconstructed, otherwise the responsive data will be invalid

<template>
  <div>Frogman</div>
</template>
<script>
export default {
  name: 'App',
  props: {
      title: {
          type: String
      }
  },
  setup({ title }) {
    console.log(title) // Here, the responsive data will fail
  }
}
</script>

context

This parameter provides a context object from the original 2 X selectively exposes some properties.

  • attrs
  • slots
  • emit
<template>
  <div>Frogman</div>
</template>
<script>
export default {
  name: 'App',
  props: {
      title: {
          type: String
      }
  },
  setup(props, { attrs, slots, emit } ) {
    console.log(attrs) 
  }
}
</script>

Above, attrs and slots are agents of corresponding items on internal component instances, which can ensure that the updated values are still the latest. So you can use deconstruction syntax here.

Return value

You can render the return value of the setup function to the page. However, the premise is that the return value of setup must be an object, otherwise the rendering will be invalid if other values are returned.

<template>
  <div>Frogman</div>
</template>
<script>
export default {
  name: 'App',
  props: {
      title: {
          type: String
      }
  },
  setup() {
    const name = "Frogman"
    return {
       name
    }
  }
}
</script>

Reactive

This method takes a parameter {} and creates a responsive object. With vue2 Vue of X Observable. If the parameter is not an object, it can also be rendered to the template, but it is not responsive data.

<template>
  <div class="test">
    full name:  {{ name.value }}
    {{ test() }}
  </div>
</template>

<script>
import { reactive } from "vue"
export default {
 name: 'test',
  data() {
    return {

    }
  },
  setup() {
    let name = reactive({value: "Frogman"})
    function test() {
        name.value = "abc"; // This method tests the responsive data. You can see that the view will also change after the method is executed
    }
    return {
        name,
        test
    }
  }
}
</script>

Ref

This method receives a parameter, which can be a single value or an object, and all of them are responsive data. When an object is passed in {}, the internal will call the reactive method to convert it into responsive data. The return value contains Value attribute, which can be omitted when rendering with template value.

<template>
  <div class="test">
    full name:  {{ name }}
    {{ test() }}
  </div>
</template>

<script>
import { ref } from "vue"
export default {
 name: 'test',
  data() {
    return {

    }
  },
  setup() {

    let name = ref("Frogman")
    function test() {
        name.value = "abc"; // Only the rendering template can be omitted value, but it has to be written in logic
    }
    return {
        name,
        test
    }
  }
}
</script>

Computed

This method can pass in a function. By default, this function is getter. No matter whether the return value of getter is a ref responsive data or an ordinary variable, the data is read-only and cannot be changed.

<script>
import { ref, computed } from "vue"
export default {
 name: 'test',
 setup() {
    let name = ref("Frogman")
    let test = computed(() => name.value);
    test.value = "123" // The modification is invalid. It can only be read-only
  }
}
</script>

Pass in an object set and get function method, so you can modify it

<script>
import { ref, computed } from "vue"
export default {
 name: 'test',
 setup() {
    let name = ref("Frogman")
    let test = computed({
        get() {
            return name.value;
        },
        set(val) {
            return name.value = val;
        }
    });
    test.value = "123" 
  }
}
</script>

Readonly

This method receives an incoming object. By default, it is a read-only function. It is a deep object read-only. No matter how many nested layers of attributes are read-only.

<script>
import { readonly } from "vue"
export default {
 name: 'test',
  setup() {
    let obj = {
        name: "Frogman",
        sex: "male",
        prodution: {
            proName: "sound"
        }
    }
    let only = readonly(obj)
    only.name = "Front end entertainment circle" // Invalid modification
    only.prodution.proName = "Welcome to pay attention" // Invalid modification
    console.log(only) 
  }
}
</script>

WatchEffect

This method receives a function and executes it immediately, and re executes the function when the variables in the function change. This method cannot get the original value, only the changed value.

>If you want to monitor which value, you need to write it in this function, otherwise the monitoring is invalid

import { ref, watchEffect } from "vue"
export default {
 name: 'test',
  setup() {
    let name = ref("Frogman");
    let age = ref(23);
    watchEffect(() =&gt; {
        name.value; // Listening name
        age.value;  // Monitor age
        
        console.log(name.value)
        console.log(age.value)
    })
    
    setTimeout(() =&gt; {
        name.value = "Front end entertainment circle"
    }, 5000)

    setTimeout(() =&gt; {
        age.value = 18
    }, 1000)
  }
}

Cancel listening

Sometimes we want to cancel listening after triggering certain conditions. At this time, the return value of watchEffect can be executed.

import { ref, watchEffect } from "vue"
export default {
 name: 'test',
  setup() {
    let name = ref("Frogman");
    let age = ref(23);
    let stop = watchEffect(() =&gt; {
        name.value; // Monitor name
        age.value;  // Monitor age
        
        console.log(name.value)
        console.log(age.value)
    })
    
    setTimeout(() =&gt; {
        name.value = "Front end entertainment circle"
    }, 5000)

    setTimeout(() =&gt; {
        age.value = 18;
        setTimeout(stop, 300)
    }, 1000)
  }
}

Watch

watch is equivalent to vue2 This in X$ watch, which needs to monitor specific data, is lazy by default, that is, the second parameter function is executed only when the data changes.

Compared with WatchEffect, Watch allows us to

  • Lazy execution function
  • More clearly which state changes trigger the listener
  • You can monitor and obtain the values before and after the change

Listen for a single value

<script>
import { ref, watch } from "vue"
export default {
 name: 'test',
  setup() {
    let name = ref("Frogman");

    watch(name, (newVal, oldVal) => {
        console.log(newVal, oldVal) // Front end entertainment circle, Frogman
    })

    setTimeout(() => {
        name.value = "Front end entertainment circle"
    }, 1000)

  }
}
</script>

Listen for multiple values

Listen for multiple values and return an array object.

<script>
import { ref, watch } from "vue"
export default {
 name: 'test',
  setup() {
    let name = ref("Frogman");
    let age = ref(23);

    watch([name, age], (newVal, oldVal) => {
        console.log(newVal, oldVal) // ["front end entertainment circle", 18], ["frogman", 23]
    })
    
    setTimeout(() => {
        name.value = "Front end entertainment circle"
        age.value = 18
    }, 1000)

  }
}
</script>

Life cycle series

In vue3 X can also use the life cycle under the setup function. The writing method of these hook functions is different from that of the previous life cycle.

>Note: these life cycle writing methods can only be used under the setup function, and errors will be reported if they are used elsewhere.

With vue2 Composite Api corresponding to version x life cycle

  • beforeCreate --> setup
  • created --> setup
  • beforeMount --> onBeforeMount
  • mounted --> onMounted
  • beforeUpdate --> onBeforeUpdate
  • updated --> onUpdated
  • beforeDestroy --> onBeforeUnmount
  • destroyed --> onUnmount

Now let's take a look at the writing of these hooks. Hook function is a callback function.

<script>
import { onMounted, onUpdated, onUnmounted } from "vue"
export default {
 name: 'test',
  setup() {
    
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
    
  }
}
</script>

Provide && Inject

This method and vue2 The provide and inject of X are the same. However, Vue3's new features, these two methods can only be used in setup.

  • Provide: receive two parameters, the first key value and the second value value, and pass them
  • Inject: two parameters are received. The first is the key value of provide. The second parameter is optional by default. You can set the default value (set a default value when the key value cannot be found)

App.vue

<script>
import test from "./components/test"
import { provide, ref } from "vue"
export default {
  name: 'App',
  components: {
    test
  },
  setup() {
    let name = ref("Frogman")
    provide("name", name) // Pass in a responsive data
  },
}
</script>

test.vue

<template>
	{{ NAME }}    
</template>
<script>
import { inject } from "vue"
export default {
 name: 'test',
  setup() {
    let NAME = inject("name")
    console.log(NAME) // Frogman
      
    let title = inject("key", 123)
    console.log(title) // The default value will be triggered because the key value cannot be found here
      
    return {
        NAME
    }
  }
}
</script>

Refs

This method is equivalent to vue2 If you want to obtain elements like refs of X, you can use the ref object in setup to obtain them

<template>
  <div class="test">
    <p ref="el">123</p>
  </div>
</template>

<script>
import { ref, onMounted } from "vue"
export default {
 name: 'test',
  setup() {
    let el = ref(null)
    onMounted(() => {
         console.log(el) // p label element
    })
    return {
        el
    }
    
  }
}
</script>

isReadonly

Used to detect whether the data is readable data. Returns a Boolean type.

<script>
import { isReadonly, readonly} from "vue"
export default {
 name: 'test',
  setup() {
    let test = readonly({name: "Frogman"})
    console.log(isReadonly(test)) // true
      
    let test2 = readonly("Frogman")
    console.log(isReadonly(test2)) // false, this is not a read-only data
  }
}
</script>

isRef

Used to detect whether the data is ref responsive data. Returns a Boolean type.

<script>
import { isRef, ref } from "vue"
export default {
 name: 'test',
  setup() {
    let test = ref("Official account: front-end Entertainment")
    console.log(isRef(test)) // true
  }
}
</script>

isReactive

Used to detect whether the data is reactive or not. Boolean returns a type.

<script>
import { isReactive, reactive } from "vue"
export default {
 name: 'test',
  setup() {
    let test = reactive({name: "Frogman"})
    console.log(isReactive(test)) // true
      
    let test2 = reactive("Frogman")
    console.log(isReactive(test2)) // false, this is not a responsive data
  }
}
</script>

Remove filters

In vue3 Remove filter from X, not supported. It is recommended to use computed instead. Post an example of the official website

<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountInUSD }}</p>
</template>

<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    computed: {
      accountInUSD() {
        return '$' + this.accountBalance
      }
    }
  }
</script>

No longer restrict Template to a root node

Vue3. In X, there will be no restriction. There is only one root node in the template. The root component can have as many elements as it wants.

<template>
    <div>home page</div>
    <div>Journalism</div>
</template>

Custom v-model modifier

Vue3.x, a modifier that can be customized is added, such as the built-in method provided by Api trim, we can also customize the new features. Let's demonstrate how to write a modifier to convert string uppercase.

App.vue

<template>
  <input v-model:str.capitalize="modelModifiers">
</template>
<script>
import Input from "./components/Input"
export default {
  name: 'App',
  components: {
    Input
  }
}
</script>

Input.vue

<template>
  <div class="Input">
    <input type="text" @input="send">
  </div>
</template>

<script>
export default {
 name: 'Input',
  props: {
      str: String,
      strModifiers: {
          default: () => ({})
      }
  },
  methods: {
      send(e) {
          let value = e.target.value
          if (this.strModifiers.capitalize) { // capitalize the value here is the modifier
            value = value.toUpperCase()
            console.log(value)
          }
          this.$emit("update:str", value)
      }
  }
}
</script>

For the above method, the props value must be passed in, and the Modifiers must be defined as an empty object.

>A special note: if the value of your v-model parameter is str, all the values received in the component start with str, such as strModifiers and str in props

effect:

Discard on, off, once instance methods

Vue3. The $on, $off and $once instance methods in X have been removed, and the application instance no longer implements the event trigger interface.

<script>
	created() {
        console.log(this.$on, this.$once, this.$off) // undefined undefined undefined
	}
</script>

Custom instruction change

In vue3 The custom specified writing method in X has changed slightly. See the following.

  • Occurs after the bind -- > beforemount instruction is bound to an element. Only once
  • Occurs after the inserted -- > mounted element is inserted into the parent DOM
  • beforeUpdate: Vue3.x is newly added, which is called before the element is updated.
  • componentUpdated --> updated
  • beforeUnmount : Vue3. The newly added x will be called before unloading the element.
  • unbind --> unmounted

main.js

import { createApp } from 'vue'
import App from './App.vue'

let main = createApp(App)
main.directive("custom", {
    beforeMount(el, attr) {
        console.log(el, attr)
    },
    updated() {
        console.log("updated")
    },
    unmounted() {
        console.log("remove")
    }
})
main.mount('#app')

App.vue

<template>
  <p v-custom v-if="show"></p>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      show: true
    }
  },
  created() {
    setTimeout(() => {
      this.show = true;
    }, 5000)
      
    setTimeout(() => {
      this.show = false
    }, 3000)
  }
}
</script>

thank

Thank you for reading this article. I hope it can help you. If you have any questions, you are welcome to correct them.

I'm frog man (✿◡‿◡), if you think it's OK, please praise it ❤.

Interested partners can join [front end entertainment communication group] Welcome to exchange and discuss with us

Writing is not easy, "like" + "watching" + "forwarding". Thank you for your support ❤

Previous good articles

Talk about using Decorator decorator in Vue project

"Share 15 Webpack practical plug-ins!!!"

Teach you to write a Vue component, publish it to npm and use it outside the chain

Sharing loaders commonly used in 12 webpacks

Talk about CommonJs and Es Module and their differences

Do you know the JavaScript tips used in these jobs

[suggestions collection] share some Git commands commonly used in work and how to solve special problem scenarios

reference resources

https://v3.cn.vuejs.org/

Topics: Javascript