preface

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

I’ll just write some of the usual ones here. For more, see Vue3 website here

Component V-Model supports parameters

In vue 2.x, if we want to pass a value to a child component, we have to pass it separately. Ve3. X is passed directly in the form v-model: XXX and is synchronized with the modifier.sync to update the data.

App.vue

<template>
  {{title}} 
  <Input v-model:title="title" />
</template>

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

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>
Copy the code

The effect

The component supports multiple V-Models

The creation of multiple V-Model bindings on a single component is supported in vue3.x.

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>
Copy the code

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."}},methods: {
      first(e) {
          this.$emit("update:title", e.target.value)
      },
      last(e) {
          this.$emit("update:name", e.target.value)
      }
  }
}
</script>
Copy the code

The effect

Setup

The setup function is a new component option. As an entry point for using the Composition Api within a component. Let’s break it down into four areas

  • Call time
  • This points to the
  • Function parameters
  • The return value

Call time

Create the component instance, initialize the props, and then call the setup function. From a lifecycle perspective, it executes before beforeCreate. In other words, setup, beforeCreate, and CREATE are executed for component creation.

<template>
  <div>The upcoming</div>
</template>
<script>
export default {
  name: 'App'.setup() {
    console.log("Hey frogman")}}</script>
Copy the code

This points to the

Since you can’t use data or methods in the setup function, to avoid using Vue error, change this in the setup function to undefined.

<template>
  <div>The upcoming</div>
</template>
<script>
export default {
  name: 'App'.setup() {
    console.log(this); // undefined}}</script>
Copy the code

Function parameters

  • props
  • context

props

Receives all data from the component and responds.

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

Note that the props data cannot be deconstructed, otherwise reactive data will be inoperative

<template>
  <div>The upcoming</div>
</template>
<script>
export default {
  name: 'App'.props: {
      title: {
          type: String}},setup({ title }) {
    console.log(title) // In this case, reactive data will be invalid}}</script>
Copy the code

context

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

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

Above, attrs and slots are proxies for the corresponding entries on the internal component instance to ensure that the latest values remain after updates. So you can use deconstructive syntax here.

The return value

The return value of the setup function can be rendered onto the page. However, the setup return value must be an object, otherwise the render will be invalid.

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

Reactive

This method takes a parameter {} to create a reactive object. Same as Vue2.x’s Vue.Observable. If the parameter is not an object, it can also be rendered to the template, but it is not reactive data.

<template>
  <div class="test">{{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 reactive data, and you can see that the view changes after the method is executed
    }
    return {
        name,
        test
    }
  }
}
</script>
Copy the code

Ref

This method takes a parameter, which can be either a single value or an object, and is all reactive data. When an object {} is passed in, it is internally converted to reactive data by calling the reactive method. The return value has a. Value attribute, which can be omitted when using template rendering.

<template>
  <div class="test">{{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"; // The rendering template can omit the.value, but it has to be written in the logic
    }
    return {
        name,
        test
    }
  }
}
</script>
Copy the code

Computed

This method can pass in a function, which by default is the getter. Whether the getter returns 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 and can only be read
  }
}
</script>
Copy the code

Pass in an object set and get 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) {
            returnname.value = val; }}); test.value ="123" 
  }
}
</script>
Copy the code

Readonly

This method receives an incoming object, which is read-only by default. It is read-only for deep objects, and its properties are read-only regardless of how many layers are nested.

<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." // Invalid modification
    only.prodution.proName = "Welcome to follow." // Invalid modification
    console.log(only) 
  }
}
</script>
Copy the code

WatchEffect

This method receives a function and executes it immediately, then re-executes the function when a variable in the function changes. This method does not get the original value, only the changed value.

If you want to listen for a value, you need to write it in the function, otherwise the listening is invalid

import { ref, watchEffect } from "vue"
export default {
 name: 'test'.setup() {
    let name = ref("Frogman");
    let age = ref(23);
    watchEffect(() = > {
        name.value; / / to monitor the name
        age.value;  / / to monitor the age
        
        console.log(name.value)
        console.log(age.value)
    })
    
    setTimeout(() = > {
        name.value = "Front end entertainment."
    }, 5000)

    setTimeout(() = > {
        age.value = 18
    }, 1000)
  }
}
</script>
Copy the code

Cancel to monitor

Sometimes we want to cancel listening after certain conditions are triggered. The return value of watchEffect can then be executed.

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

    setTimeout(() = > {
        age.value = 18;
        setTimeout(stop, 300)},1000)
  }
}
</script>
Copy the code

Watch

$watch is the same as this.$watch in vue2.x. Watch needs to listen for specific data.

In contrast to WatchEffect, Watch allows us to

  • Lazy execution function
  • Be more explicit about which state changes trigger listeners
  • You can listen to get the value before and after the change

Listening 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, frogman
    })

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

  }
}
</script>
Copy the code

Listening 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 ", 18], [" Frogman ", 23]
    })
    
    setTimeout(() = > {
        name.value = "Front end entertainment."
        age.value = 18
    }, 1000)

  }
}
</script>
Copy the code

Life cycle series

In Vue3.X, you can also use the lifecycle under the setup function. These hook functions are written differently from the previous lifecycle.

Note: These lifecycle scripts can only be used under the setup function; they will report an error if used elsewhere.

A composite Api corresponding to the Vue2. X version lifecycle

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

Let’s see how these hooks are written. Inside the 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>
Copy the code

Provide && Inject

This method is the same as the provide and inject of vue2.x. But the new Vue3 feature is that these two methods can only be used in setup.

  • Provide: Receives two parameters, the firstkeyValue, number twovalueValue is passed
  • Inject: accepts two parameters, the first one isprovidethekeyThe second parameter is optional and can be set to a default value (if the key value cannot be found, set a default value).

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 a responsive data
  },
}
</script>
Copy the code

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 is triggered because the key is not found
      
    return {
        NAME
    }
  }
}
</script>
Copy the code

Refs

This method is equivalent to vue2.x refs for retrieving elements, so use the REF object in the setup

<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 tag element
    })
    return {
        el
    }
    
  }
}
</script>
Copy the code

isReadonly

This is used to test whether the data is readable. 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>
Copy the code

isRef

This is used to check if the data is ref-responsive. Returns a Boolean type.

<script>
import { isRef, ref } from "vue"
export default {
 name: 'test'.setup() {
    let test = ref("Public Account: Front End entertainment")
    console.log(isRef(test)) // true
  }
}
</script>
Copy the code

isReactive

Tests whether the data is reacttive responsive data. Returns a Boolean 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>
Copy the code

Remove filters

Filter removed from Vue3. X, no longer supported. Use computed instead. Post an example from 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>
Copy the code

Template is no longer restricted to a root node

Instead of limiting the template to a single root node in Vue3. X, the root component can have as many elements as it wants.

<template>
    <div>Home page</div>
    <div>news</div>
</template>
Copy the code

Custom V-Model modifier

In Vue3. X, we added custom modifiers such as the built-in methods provided by the Api. Trim, a new feature we can also customize. Let’s show you how to write a modifier that converts a string to uppercase.

App.vue

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

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 is the modifier
            value = value.toUpperCase()
            console.log(value)
          }
          this.$emit("update:str", value)
      }
  }
}
</script>
Copy the code

The above method must be passed in props and the Modifiers must be written as an empty object.

One important thing to note is that if your V-model parameter is STR, then all values that your component receives start with STR, such as strModifiers in props

Effect:

Discard the on, off, once instance methods

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

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

Custom directive changes

The custom specification writing in Vue3. X has changed slightly, as shown below.

  • Bind –> beforeMount occurs after the directive is bound to an element. It only happens once
  • Inserted –> Mounted Occurs after an element is inserted into the parent DOM
  • BeforeUpdate: Newly added by Vue3. X, which is called before the element is updated,
  • componentUpdated –> updated
  • BeforeUnmount: newly added for Vue3. X and is called before uninstalling elements
  • 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')
Copy the code

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>
Copy the code

Thank you

Thank you for reading this article. I hope it helps you. If you have any questions, please correct me.

✿ Theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus theus

Interested partners can join [front end entertainment circle exchange group] welcome everyone to exchange and discuss

Writing is not easy, “like” + “watching” + “retweet” thanks for supporting ❤

Past oliver

How to Use Decorators in Vue Projects

Share 15 useful Webpack plugins!!

How to write a Vue component and publish it to NPM

Sharing 12 Common Webpack Loaders

What are CommonJs and Es Modules and how they differ?

Do you know all these JavaScript Tricks for work?

【 Suggestions 】 Share some Git commands commonly used in work and how to solve special problems

reference

v3.cn.vuejs.org/