preface

The author is currently a senior in college and has an App internship in Beijing. Because my tutor requires me to do a technology sharing, I have decided to share vuE3 I recently learned after much consideration. Besides, there is no limit to the form of sharing, so I plan to publish an article in Nuggets.

The author has been in contact with VUe3 for almost 100 days now. There may be some mistakes in my understanding of VUe3. Please forgive me if there are any mistakes. Since Vue3 prefers typeScript to typeScript, and I prefer typeScript, I’ll use typeScript for the rest of this article, but it shouldn’t bother readers who don’t know typeScript.

Considering the length, this paper is divided into three parts, the first part is mainly about the routine use of VUE3. In the middle part, I mainly talk about some small principles of VUe3. In the last part, I wrote a small project using vue3+deno/node (using denO and Node have written a broken interface, the main author node dish’s foot, deno more dish). It is estimated that about 3000 lines of code, this is the first part.

I hope you can point a small praise, point a collection, and I do not develop the habit of white whoring.

Added github demo address: github.com/1131446340a…

g

Added vuE3 from entry to combat) (middle) juejin.cn/post/687072…

Vue3 life cycle and nextTick usage

In VUe3, most uses are introduced first and then called. It is very cheap to learn. If you have vuE2 development experience, it should be very easy to learn

<script lang="ts">
import { onMounted, onBeforeMount, nextTick} from 'vue'
export default {
    name: 'App',
    setup() {
        nextTick(() => {
            console.log('nextTick');
        })
        onMounted(() => {
            console.log('mounted');
        })
        
        onBeforeMount(() => {
            console.log('beforeMounted');
        })
        console.log('hello vite Vue3')
    }
}
</script>   
Copy the code

Setup () in VUe3 is the entry function, equivalent to the previous Created and Beforecreated life cycles. You can see that the other life cycles are just called in the setup function, and I’m sure there’s nothing to explain here, but the output sequence is pretty straightforward.

Vue responsive system and Methods

So let’s look at the code

<template> <div> <h3>vue3 responsive systems and methods</h3> <div> Age :{{myAge}}</div> <div @ click = "AgeAdd" > age + 1 < / button > < div > name: {{myName}} < / div > < div > interests: <div v-for="(hoppy, Index) in hoppys" :key="index">{{hoppy}}</div> </div> <div> from {{state1.from}}</div> </div> </template> <script lang="ts"> import HelloWorld from './components/HelloWorld.vue' import { ref, toRefs, reactive, watchEffect, watch, computed, onMounted } from 'vue' export default { name: 'App', Setup () {let myAge = ref(23) // let myName = 'reactive' // non-reactive data const state = reactive({// Complex data reactive similar to data based on proxy }) const state1 = reactive({// Can define multiple data sources from: }) watchEffect(() => {// watch console.log(' age :' + myage.value) console.log(' hobby :' + state.hoppys) }) let mylastAge = computed(() => { return myAge.value + 1 }) setTimeout(() => { state.hoppys[1] = 'typeScript' myage. value += 1 myName = 'lihau'}, 1000) watch([state.hoppys, myAge], Console. log('watch:' + newVal)}) const methods = {AgeAdd () {myage.value += 1}} return { myName, myAge, ... ToRefs (state), // Convert reactive to ref state1, mylastAge... methods } } } </script>Copy the code

As you can see, the way the Templeate template is used in Vue3 is basically the same. The only thing to note is that any reactive data used in the template is returned (including methods) in the Setup function.

Now let’s look at the TS code, which is ts, but now all of this data can be inferred using types, and it actually looks like JS.

First, any data returned in the setup function can be used in the template, just not reactive data.

In VUe3, the author has found that there are two ways to transform non-responsive data into responsive data, that is, ref function and Reactive function. Ref should be implemented based on Object.defineProperty. Reactive is implemented based on proxy, so it is recommended to use ref for common data types and proxy for complex data types. But notice that if you use ref, you’re manipulating its value property to change the value, but you don’t need to put value in the template. In fact, I prefer to write this way:

const state = reactive({
	name:"",
    age:0,
    Array:[]
})

Copy the code

In this way, we can define the data source directly, just as we used in VUe2, and methods are the same. If you are careful, you will notice that the setup function deconstructs methods and state so that you can easily write data in the template. You may ask what toRefs is, which is to convert all data in state to ref data.

Computed use in VUe3 is basically the same as before, but expressed in the form of the Component API, so there’s not much talk.

In VUe3, watch has some changes, that is, it can monitor multiple values at the same time. When one of the values changes, watch will be triggered.

WatchEffect watchEffect watchEffect watchEffect watchEffect watchEffect WatchEffct is called once at the beginning and again when the data used in watchEffect changes.

Props and ref bind dom

<template> <div> <h3 props =" h3 ">ref,props </h3> </div> </template> <script> import {ref, onMounted } from 'vue' export default { setup () { let H3 = ref(null) onMounted(() => { H3.value.style.color = 'red' }) Shallow -(Reactive,ref,readonly) rewrites reactive or readonly values (markRow Return {H3}}} </script> </script>Copy the code

In vue3, you only need to pass a null value to ref and then bind it to DON. In Mounted, the value of ref is determined by its value attribute. There are also some small features that you can see in the comments.

Component system

There are several ways to define components in VUe3. The biggest difference is that using JSX/TSX to define components in VUe3 is much easier than using JSX/TSX in VUE2. In addition, components involve children, props, attrs, emit, slot, etc.

<template> <div> <h3> </h3> <Hello name=" updateName" @ "updateName"></Hello> <Age: Age ="33"></Age> <myInput> <template V-slot :desc> <div> This is the input box </div> </template> </myInput> </div> </template> <script lang="ts"> import Hello from  './TSX/Hello' import Age from './components/Age.vue' export default { components:{ Hello,Age }, setup(){ const updateName =()=>{ console.log(1); } return {updateName} } } </script>Copy the code

As you can see, I’ve got hello, age, myInput, three components, actually three components.

Let’s start with the AGE component

<template> <div> <div>{{ props.age }}</div> </div> </template> <script lang="ts"> import { reactive, isReadonly, toRaw, inject, ref, readonly } from 'vue' interface Props { age: number } import vuex from '.. /shared/vuex' export default { props: { age: { type: Number, default: 0 } }, setup (props: {// Props is readonly // Don't try to deconstruct Props, // props. Age = 23 // console.log(isReadonly(props)) props = reactive(toRaw(props)) return {props}}  </script>Copy the code

The setup function has two elements. The first is props. Don’t try to deconstruct the props as it will make them unresponsive. Props is warned if you try to modify it. I guess I did the following for readonly

let proxy = new Proxy(obj, {
    set(target, key, value) {
        target[key] = value
    },
    get(target, key) {
        return target[key]
    }
})

function readonly(proxy) {
    return new Proxy(proxy, {
        get(target, key) {
            return target[key]
        },
        set() {
            throw Error()
        }
    })
}
Copy the code

If you want to modify the props, restore the props to Reactive.

Let’s look at the Hello component, which is written using TSX

export default {
  setup (
    props: object,
    { attrs, emit }: { attrs: { name: string }; emit: Function }
  ) {
    return { attrs, emit }
  },
  render (props: { attrs: { name: string }; emit: Function }) {
    return (
      <div
        onClick={() => {
          props.emit('updateName')
        }}
      >
        hello {props.attrs.name}
      </div>
    )
  }
}

Copy the code

If you prefer to use TSX syntax, you can export a ts object, which is similar to the.vue file, except that the render function is used to write HTML, and vue3 TSX is easier to use than React.

First let’s look at the setup function. This time I gave it a second argument and deconstructed it, attrs and emit. Emit is familiar to everyone, so I will not go into details on emit. Attrs has a name attribute, the name attribute passed by the parent component. Some of you might be saying, isn’t father passing son through props? Yes, we can use props as before, but we need to declare the props object above. Now we can get attrs directly. Note also that attrs is still readable and writable, but not readonly, and an error will be reported if you try to modify attrs. If you want to make changes, you can try copying the data based on your needs.

The first parameter of the render function, also called props, is an object with properties like emit,emit,emit,slots,$attrs, etc. In addition, the setup function is incorporated into the function.

Attrs is exactly the same as our attrs, so in this case, we can use attrs exactly the same as our attrs, so in this case, We can simply use attrs and $emit instead of attrs and emit and remove the setup function.

The emit function can be used by the react parent. Is it more comfortable than the react parent?

Another advantage of using TSX is that if we use the template template, we require the function to pass data of type number, but passing other parameter types to the template is completely undetectable, which you can easily detect using TSX.

The last is the global component myInput

import { reactive, vShow, vModelText, withDirectives, App, isReadonly } from 'vue' interface Props { number: number $slots: { desc: () => any[] } desc: () => {} input: any isShow: boolean } import { toRefs } from 'vue' const install = (app: App) => { app.component('myInput', { props: { number: { type: String } }, setup (props: Props, { slots }) { const state = reactive({ input: 0, isShow: false }) return { ... toRefs(slots), ... toRefs(state) } }, data () { return { number: 0 } }, render (props: Props) {console.log(isReadonly(Props)) return (<div> <div v-show={Props. IsShow}> You can't see me </div> {Props. {props.$slots.desc()[0]} {/* {withDirectives(<input type='text' />, [[vModelText, this.number]])} */} <div>{this.number}</div> {withDirectives(<h1>Count: 2</h1>, [[vShow, true]])} </div> ) } }) } export default { install }Copy the code

Global components and before using the basic similar, introduced to install function, noting that the first parameter is not Vue class, no prototype, use app.com ponent function to register the plugin, use and similar before, the first is the component name, the second is a component. I’m still using TSX syntax here. You can see that the second parameter to the setup function is deconstructed out of slots.

Let’s look at the render function. I tried v-show and it didn’t work. I googled something and realized that to write like this you should use Babel. For slots, the parent component passes a slot of DESC. In VUe3, slots are in the form of function calls. The above two methods of using slots can be, we pay attention to the difference. The withDirectives () function is indeed used in VUe3. After trying this, vShow works, VModel assigns only the initial value and reports an error as soon as it is entered. The usage is not yet known. However, these are still quite tedious to write, hopefully the official native support as templete writing commands.

Directive and CSS property responsiveness

<template> <div> CSS attributes Reactive with instructions <h1 v-highlight=" red "> This is a string of words highlighted in red </h1> </div> </template> <script> export default { The setup () {return {" red ":" red ", "font size:" '40 px,}}} < / script > < style vars =' {red, font size} '> div {color: var (- red); Font: var(-- font size); } </style>Copy the code

I don’t know if you have ever thought about using reactive CSS in VUE, but I did. Now VUE3 supports it.

Add vars ={} in the style and use a comma to separate the variables. Use CSS variables as normal.

Use instructions in VUe3

const app = createApp(Demo)
app.directive('highlight', {
    beforeMount(el, binding, vnode) {
        el.style.color = binding.value;
    },
    pdated(){},
    mounted(){},
    created(){}    
});
Copy the code

Use method we should know a look, do not waste too much tongue.

Global communication mode

I have found three types of global communication in VUe3. The first is provide and Inject

< the template > < div > < h3 > global communication < / h3 > {{myName}} < Age > < / Age > interests: {{hoppy}} </div> </template> <script lang="ts"> import {toRefs, provide,ref, inject} from 'vue' import vuex from './shared/vuex' import Age from './components/Age.vue' export default { components:{  Age }, setup(){ const {myStore, updateName, Provide ('hoppy',ref('javascript')) let hoppy = ref(inject('hoppy') as string) return {... toRefs(myStore),hoppy} } } </script>Copy the code

Provide and Inject are exported from the VUE. If you use provide in a component, its descendants and grandchildren can get the value provided by provide. The first argument is the supplied name, using either a string or symbol. The second is the passed data, but note that to make it reactive you need to wrap it with ref or Reactive. Use Inject as sub-component. In Vuex for VUE3, it is also based on this API.

The second way

Just create a file, take advantage of the ES6 module features, and export an object, which is then imported by both components. Personally, I like this method, which is simple and clear enough, and I haven’t found any bugs in use so far.

import { reactive } from 'vue'; Const myStore = {myName: 'huang Lihao ', myAge: 23}; const updateName = (newName: string) => { myStore.myName = newName; }; const updatedAge = (newAge: number) => { myStore.myAge = newAge; }; export default { myStore, updateName, updatedAge };Copy the code

Another advantage of this approach is that the exported object is changed to a function, and the function returns the object. When used to call the function, these properties are not shared, which is similar to the mixins in VUe2.

The third way is undoubtedly to use VUex, but PERSONALLY I feel that I can completely give up vuex in VUE3. In the next article, I will briefly analyze the principle of vuex, but I will not talk more here.

The first UI component of VUE3

This component is the second version of ANTD Design Vue, released on 9.1. It should be a beta version, you can use it according to the instructions on the official website. When I wrote my vue3 mini-project, there were no third-party UI components, so I simply modified elementUI a little so that he could use a component in Vue3, but there were a few bugs and it wasn’t as fast as rewriting the components himself.

conclusion

Except for vuE-Router and Vuex and filters, we have basically covered the general operation of VUE3. However, there are no filters in VUe3, just function calls, so you should be able to build wheels after learning vuE-Router.

The next article will briefly cover some of the API principles that I know about vUE cripple.