A summary.

The content of the article is a little too much, can not add the style, we will have a look.

With the release of vue3 One Piece last week, it’s time for us to start learning from Utah university.

I compared vue2 to VUe3, listing usage, functionality or deprecated apis. For some vuE2 students to quickly understand and start vuE3. In this article, only some of the differences in use are listed, not the source code.

In addition to installation and some of vue3’s new methods, I will list the APIS in the order listed in the official VUe2 API documentation.

  • The installation
  • Vue3 new content
  • Application Configuration (original global configuration and global API)
  • Global API
  • Options/data
  • Options/DOM
  • Options/lifecycle hooks
  • Options/Resources
  • Options/Combinations
  • Options/Others
  • Instances of the property
  • Instance method/data
  • Instance method/event
  • Instance method/lifecycle
  • instruction
  • Special attribute
  • Built-in components

My skills are limited, and THERE are some APIS here that I may not often use or use, so if there are any mistakes or omissions, please point out in the comments below, AND I will make modifications in time.

Here is my personal understanding and record, now vue3 official documents have been published, you can also go to the official website to view the content of vue2 migration.

2. Install

Project installation is now available in three ways.

  • Introduced via script
<script src="https://unpkg.com/vue@next"></script>
Copy the code
  • Scaffolding vue – cli
Vue3 project creation was supported by cli only in version 4.5.0
npm install -g @vue/cli
vue create hello-vue3
Copy the code
  • Scaffolding vite
npm init vite-app hello-vue3
Copy the code

Vite is Utah’s new open source tool, to borrow a phrase from Utah

A development server based on browser native ES Imports. Parsing the imports in the browser, compiling and returning them on the server side on demand, bypassing the concept of packaging entirely, and making the server available on demand. Not only does it have Vue file support, it also handles hot updates, and the speed of hot updates does not slow down with the increase of modules. For production environments, the same code can be packaged in rollup. Although it is still rough, I think this direction has potential. If done well, it can completely solve the problem of changing a line of code and waiting for hot updates for half a day.

Basically, js was introduced using the browser’s own ES imports method. No packaging is required in development mode, just compiling the modified files. Rollup packaging is used in production environments.

This is a new direction, although it’s still young and compatibility with the ES Imports browser is questionable, but in a few years it could become a mainstream tool as well.

New content of VUE3

1.Composition API

Write data, methods, computed, and lifecycle functions in one place.

1.1 the setup ()

Setup () serves as the entry point for using the Composition API within the component. The execution time is between beforeCreate and created. This cannot be used to retrieve other component variables, and it cannot be asynchronous. Setup returns objects and methods that can be used in templates.

Setup takes two parameters,props,context.

<script lang="js">
import {toRefs} from 'vue'
export default {
    name: 'demo'.props: {name: String,},setup(props, context){
      // Here we need toRefs for the deconstruction
      // The props is the same as vue2, but the name can also be used directly in template
      const { name }=toRefs(props);
      console.log(name.value);
      // Only these three attributes can be obtained, which also cannot be used with ES6 deconstruction
      // Attribute, same as $attrs for vue2
      console.log(context.attrs);
      / / slots
      console.log(context.slots);
      // event, same as $emit for vue2
      console.log(context.emit);
  }
}
</script>
Copy the code

1.2 reactive

Vue3 decouples reactive functionality from VUE code and is called as a single JS library. Vue3’s responsiveness can be introduced and used in any other JS running framework.

<template>
  <div>{{ state.text }}</div>
  <button @click="test">Test it?</button>
</template>
<script>
import { reactive } from 'vue';
export default {
  setup() {
    Declare a reactive object through Reactive
    const state = reactive({ text: "Am I handsome?" });
    // Declare a reactive array by reactive
    const state1 = reactive([ text: "Am I handsome?" ]);
    Declare a change method
    const test = () = > state.text = 'You're ugly';
    // Return state and method
    return{ state,test }; }};</script>
Copy the code

This is a big difference with VUE2, using the above method, to achieve the response of the data. The object can then be assigned at will, without the problem of unresponsive assignment of object values in vue2. Because the bottom layer of VUE is now using proxy to achieve data monitoring.

Note: the elements here can only be objects or arrays, and ref is required for basic data types

1.3 ref

Declare reactive basic data types

import { ref } from 'vue';
export default {
  setup(){
    const a = ref(1);
    const b = ref('1');
    const c = ref(true);
    Declare a change method
    const test = () = > {
      // If the ref is set to.value, the ref is set to.value, and the ref is set to.value.
      Value is not required when ref is used as the value of a reactive object
      Value is required when ref is used as the value of the array reactive
      a.value = 2;
      b.value = '1';
      c.value = false;
    };
    return{ a, b, c, test }; }}Copy the code

Get the DOM element

<template>
  <div id="test" ref="testDom"></div>
</template>

<script>
import { ref, onMounted } from 'vue';
export default {
  setup(){
    const testDom = ref(null);
    // Use the onMounted hook, similar to handling elements in vue2's Mounted lifecycle
    onMounted(() = > {
      // Remember to add.value
      console.log(testDom.value);
    })
    return{ testDom }; }}</script>
Copy the code

1.4 readonly

You can pass in an object or ref and return a read-only object, deep read-only

const state = reactive({ name: 0 })
const readOnlyState = readonly(state)
// It can be modified
state.name = 'handsome';
// Cannot be modified and warned
readOnlyState.name = 'handsome';
Copy the code

2 Reactive API

2.1 isProxy, isReactive, and isReadonly

IsProxy is a proxy that checks whether an object is created by reactive or readonly methods. The latter two are separate tests. Note: isReactive is true if the object being tested isReactive, even if it has been processed by readonly.

2.2 toRaw

To convert a proxied or reactive object to a normal object

const state = {}
const stateReactive = reactive(state)
console.log(toRaw(stateReactive) === state) // true
Copy the code

2.3 markRaw

Disallow this object from being reactive

const state = markRaw({ name: 'handsome' })
console.log(isReactive(reactive(state))) // false
Copy the code

Note that markRaw only works on the root element; if you use child elements to assign, you can still turn it into a reactive proxy

const state = markRaw({
  data: { id: 123}})const newState = reactive({
  data: state.data,
})
console.log(isReactive(newState.data)) // true
Copy the code

2.4 shallowReactive shallowReadonly

Reactive,readonly is the same as reactive, but these two methods are shallow listening. It only responds to the first level, not the deeper data

const state = shallowReactive({ name: '123'.test: { id: 1}})const test = () = > {
  // Deep data changes do not trigger responsiveness
  state.test.id = 2;
};
Copy the code

3 Ref class tool API

3.1 isRef

Checks if a value is a ref object

3.2 toRef

Used as a property of a Reactive object to remain responsive

const state = reactive({
  a: 0
})
// A property of a Reactive object
const aRef = toRef(state, 'a')
// In this case, the.value is used to read Ref
aRef.value++
console.log(state.a) / / 1

state.a++
console.log(aRef.value) / / 2
Copy the code

3.3 toRefs

Convert a reactive object to a normal object (similar to deconstruction), but you can keep the reactive. It can be used for multiple reuse of some reactive variables.

function useFeatureX() {
  const state = reactive({
    foo: 1.bar: 2
  })
  return toRefs(state)
}
export default {
  setup() {
    // It can be reused without losing responsiveness
    const { foo, bar } = useFeatureX()
    return {
      foo,
      bar
    }
  }
}
Copy the code

3.4 unref

Gets the syntax sugar for the ref value

val = isRef(val) ? val.value : val
Copy the code

3.5 customRef

Create a custom ref and manually control its reads and writes. This is an example of anti-shaking in the documentation

<input v-model="text" />
Copy the code
function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) = > {
    return {
      get() {
        // Dependencies are triggered when values are read
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() = > {
          value = newValue
          // When writing a value, perform buffering to trigger dependencies
          trigger()
        }, delay)
      }
    }
  })
}

export default {
  setup() {
    return {
      text: useDebouncedRef('hello')}}}Copy the code

3.6 shallowRef triggerRef

ShallowRef data is non-reactive, but can be triggered manually using triggerRef

const shallow = shallowRef({
  greet: 'Hello, world'
})
shallow.value.greet = 'Hello, universe'
triggerRef(shallow) // Manually triggered response
Copy the code

4. computed and watch

4.1 the computed

  • Pass in a getter function that returns a ref object that cannot be manually modified by default
  • Objects with get and set functions to create writable ref objects
const count = ref(1)
/ / read-only
const plusOne = computed(() = > count.value + 1)
// Modifiable
const plusOne = computed({
  get: () = > count.value + 1.set: (val) = > {
    count.value = val - 1
  },
})

plusOne.value = 1
console.log(count.value) / / 0
Copy the code

4.2 watchEffect

Execute a function passed in immediately, trace its dependencies responsively, and re-run the function when its dependencies change.

const count = ref(0)
watchEffect(() = > console.log(count.value))
// Prints 0, which will be printed when initialized
setTimeout(() = > {
  count.value++
  // -> print 1
}, 100)
Copy the code

Stop watch

It stops automatically when uninstalling components, or you can stop listening manually

const stop = watchEffect(() = > {
  / *... * /
})
// Stop the listener
stop()
Copy the code

Side effects

If a function has a dependency on an external variable or environment, we often call it a side effect. We don’t know what the function is doing if we just sign the function without opening the internal code check. As a separate function we expect explicit inputs and outputs. As programmers, developers should develop as few functions or methods as possible that have side effects, which also make methods less generic and less suitable for extensibility and reuse

Run time

// The initial run reads the DOM
onMounted(() = > {
  watchEffect(() = >{})})// Set the runtime
watchEffect(
  () = > {/ *... * /},
  {flush: 'pre'})// Pre is the default, executed before component updates
// post, execute after component update
// sync
Copy the code

4.3 watch

Same as vue2’s Watch

// Listen for a getter
const state = reactive({ count: 0 })
watch(
  () = > state.count,
  (count, prevCount) = > {
    / *... * /})// Listen directly on a ref
const count = ref(0)
watch(count, (count, prevCount) = > {
  / *... * /
})
Copy the code

Listening to multiple data sources

watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) = > {
  / *... * /
})
Copy the code

Behavior shared with watchEffect

Stop listening, clear side effects, side refresh timing, and listener debugging are the same as watchEffect parameters.

4. Application Configuration (original global configuration and global API)

Note: The globally configured Vue is replaced by the instance now generated by createApp

CreateApp (new)

// vue2 mounts dom methods
new Vue({
  render: (h) = > h(App)
}).$mount("#app");
// vue3
createApp(App).mount('#app')
Copy the code

Note that the global configuration Vue used previously was replaced with the instance now generated by createApp

import { createApp } from 'vue'
const app = createApp({})

// For example, register global components
app.component('my-component', {
  / *... * /
})
// Whether devTools is allowed to check the code
app.config.devtools = true  
Copy the code

GlobalProperties (new)

app.config.globalProperties.foo = 'bar'
app.component('child-component', {
  mounted() {
    console.log(this.foo) // 'bar'}})Copy the code
  • Add global properties that can be accessed in any component instance within the program. Component properties take precedence when there are key conflicts
  • Replaces Vue2. X with vue. prototype property on the prototype

Unmount to (new)

Unload the root component of the application instance on the DOM element

const app = createApp(App)
app.mount('#app')
// After 5 seconds, uninstall the APP component
setTimeout(() = > app.unmount('#app'), 5000)
Copy the code

5. Global API (new)

createApp

Similar to the global Vue variable before, the context is shared across the component tree, and the second parameter is passed as the props value

h

That was createElement before.

JSX is used occasionally, but the underlying one is used relatively infrequently, so I won’t go into details

render() {
  return Vue.h('h1', {}, 'Some title')}Copy the code

DefineComponent (component)

Creating a component

import { defineComponent } from 'vue'
const MyComponent = defineComponent({
  data() {
    return { count: 1}},methods: {
    increment() {
      this.count++
    }
  }
})
Copy the code

DefineAsyncComponent (asynchronous component)

Create an asynchronous component

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() = >
   / * or * /
  import('./components/AsyncComponent.vue')
   / * or * /
  new Promise((resolve, reject) = > {
  / * can reject * /
      resolve({
        template: '
      
I am async!
'
}) }) ) app.component('async-component', AsyncComp) Copy the code

resolveComponent

Only available in Render and Setup, looking for components by name

app.component('MyComponent', {
  / *... * /
})
const MyComponent = resolveComponent('MyComponent')
Copy the code

resolveDynamicComponent

Can only be used in Render and setup, resolving the active component active

resolveDirective

Can only be used in Render and setup, allowing directives to be resolved by name

withDirectives

Can only be used in Render and setup, allowing instructions to be applied to vNodes. Returns a VNode with application instructions

const bar = resolveDirective('bar')

return withDirectives(h('div'), [
  [bar, this.y]
])
Copy the code

createRenderer

It takes two generic parameters: HostNode and HostElement, corresponding to the Node and Element types in the host environment.

This thing is not very clear about the specific use scenario

Options/data

Emits (new)

Validate the parameters before $emit fires the event

const app = Vue.createApp({})

// Object syntax
app.component('reply-form', {
  created() {
    this.$emit('check')},emits: {
    // There is no validation function
    click: null.// with validation functions
    submit: payload= > {
      if (payload.email && payload.password) {
        return true
      } else {
        console.warn(`Invalid submit event payload! `)
        return false}}}})Copy the code

7. Option /DOM(unchanged)

Options/lifecycle hooks

  • beforeDestroy -> beforeUnmount
  • destroyed -> unmounted
  • RenderTracked (new)

Tells you which action tracks the component and the target object and key for that action

renderTracked({ key, target, type }) {
  // Where target is the pre-update value and type is get
  console.log({ key, target, type })
}
Copy the code
  • RenderTriggered (new)

Tells you what action triggered the rerender and the target object and key for that action. Target is the updated value, and type is set

These life cycles can also be used in setup() via the API

  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

Options/resources

Filters (waste)

Filters are still used sometimes

Option/combination

Parent (obsolete)

This property is rarely used in normal development

Setup (see above for details)

Option/others

Delimiters

Functional (obsolete)

A new generation method for asynchronous components is used

Model (obsolete)

The V-model has been modified to no longer require fixed attribute and event names

Comments (deprecated)

Example Property

Vm.$attrs (modified)

Now $listeners can retrieve not only values of props that are not part of the parent scope, but also custom events (including $Listeners).

Vm.$children (deprecated)

Vm.$scopedSlots (obsolete)

Vm.$isServer (deprecated)

$Listeners

13. Instance methods/data

Vue3 uses proxy for data listening, so these two methods are not needed.

Vm.$set (deprecated)

Vm.$delete (discard)

Instance methods/events

Since you can now call the lifecycle API directly from setup and import other JS methods to use, these methods are also not needed.

Vm.$on (obsolete)

Vm.$once (obsolete)

Vm.$off

15. Instance method/lifecycle

Vm.$mount (obsolete)

Use createApp’s mount method for all mounts

Vm.$destroy (destroy)

Unmount createApp

Xvi. Instructions

V-bind (modify)

  • .propGet rid of
  • .syncRemove (now need to manually de-synchronize)
  • Camel converts the kebab-case attribute name to camelCase

V-model (modified)

Multiple property values can be bound to components

<template>
  <! In Vue3.0, the v-model is followed by a modelValue, which is the name of the property to be bidirectionally bound.
  <! Vue3.0 can also be written as' Vue2.0 '.
  <a-input v-model:value="value" placeholder="Basic usage" />
</template>
Copy the code

Customize a component

<template>
  <div class="custom-input">
    <input :value="value" @input="_handleChangeValue" />
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String.default: ""}},name: "CustomInput".setup(props, { emit }) {
    function _handleChangeValue(e) {
      // Vue3.0 updates the V-Model via the EMIT event named Update :modelValue
      emit("update:value", e.target.value);
    }
    return{ _handleChangeValue }; }};</script>
Copy the code

V-on (modified)

.{keyAlias} – The callback is triggered only if the event is triggered from a specific key. No longer triggered by keycode modifiers.

V-is (New)

Similar to the: IS binding in VUe2, components can be rendered in certain HTML tags, such as TABLE, UL.

<! -- Incorrect, will not render any content -->
<tr v-is="blog-post-row"></tr>
<! - right - >
<tr v-is="'blog-post-row'"></tr>
Copy the code

Xvii. Special Attributes

The key (modified)

The key must be set on the template during the loop.

<template v-for="item in list" :key="item.id">
  <div>.</div>
  <span>.</span>
</template>
Copy the code

Ref (modified)

Refs used in V-for will no longer automatically create arrays

Solution:

<div v-for="item in list" :ref="setItemRef"></div>
Copy the code
export default {
  data() {
    return {
      itemRefs: []}},methods: {
    setItemRef(el) {
      this.itemRefs.push(el)
    }
  },
  beforeUpdate() {
    this.itemRefs = []
  },
  updated() {
    console.log(this.itemRefs)
  }
}
Copy the code

18. Built-in components

Transition (modify)

  • Props feature:

Persisted – Boolean true means that this is a transformation that will not actually insert/delete elements, but will instead switch the show/hide state. The transition hook is injected but skipped by the renderer. Instead, custom directives can control the transition by calling injected hooks, such as V-show

enter-class ->enter-from-class

leave-class ->leave-from-class

  • The event

before appear

Teleport (new)

Inserts content into the target element

<teleport to="#popup" :disabled="displayVideoInline">
  <h1>999999</h1>
</teleport>
Copy the code

The to mandatory property must be a valid Query selector or element (if used in a browser environment). Will be placed in the specified target element

Disabled This is an optional feature that can be disabled, meaning that its slot contents are not moved anywhere, but rendered as if there is no teleport component. [Default: false]

Suitable for scenarios, global loading, multiple content merging, etc.

19. Conclusion

In general, while vuE3 is compatible with VUE2 as much as possible, it also introduces a new combinational API programming mode. This new mode is similar to the react idea, which solves the problem that the business code of the previous version is difficult to reuse. Moreover, different functional codes can be better distinguished for a page. There are no previous problems with variables and methods that are jammed together and difficult to maintain later. Plus good TS support, good and powerful.

Vue Router4.0 and vuex4.0 also support vue3. Component libraries, Ant Design Vue and Vant already support VUE3.

However, as suggested in the official documentation, it is not recommended to migrate some important projects to VUe3, because vue3 still has a lot of work to do, and it does not support IE yet, so it will only be compatible with IE11.

Here are some of the best practices in development, which will be summarized later on when you are working on specific projects with VUE3.

Twenty thanks

Thank you for your patience to read, writing the article is not easy, I hope you can give me a thumbs-up, thank you.