Vue3.0 series - the first issue of "vue3.0 learning manual"

Vue3.0

1, Project construction

vite is a tool developed by Youda to replace webpack. Its implementation principle is to use the import of ES6 to send a request to load a file. Intercept these requests and do some compilation to save the lengthy packaging time of webpack. It is bundled with Rollup for production. There are no bundles in the development process. The ES Import syntax in the source code is directly provided to the browser. The browser supports parsing it through the native < script module >, so as to issue HTTP requests for each import. The development server intercepts requests and performs transcoding if necessary. For example, importing *. vue files will compile immediately before sending them back to the browser.

1. Global installation of vite scaffold

npm install -g create-vite-app

2. Create a project using scaffolding

create-vite-app projectName

3. Enter project folder

cd projectName

4. Installation dependency

npm install

5. Start vue3.0 project

npm run dev

2, Problems with vue2.x

One problem in 2.x is that when the business is increasing, the data and logic are scattered, which will be difficult to maintain.

<template>
  <div>
    <div>
      <input type="text" v-model="obj.id">
      <input type="text" v-model="obj.con">
      <button @click="submit">Submit</button>
    </div>
    <ul>
      <li v-for="(item,index) in list" :key="item.id" @click="cli(index)">
        {{item.id}}-{{item.con}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name:"filterBox",
  data(){
    return {
      list:[
        {
          id:1,
          con:"a"
        },
        {
          id:2,
          con:"b"
        }
      ],
      obj:{
        id:"",
        con:""
      }
      // Code data 1
      // Code data 2
      // ...
    }
  },
  methods:{
    cli(index){
      this.list = this.list.filter((item,idx)=>idx!==index);
      console.log(this.list);
    },
    submit(){
      // const obj = Object.assign({},this.obj);
      this.list.push(this.obj);
      this.obj.id = "";
      this.obj.con = "";
    },
    // Execute code logic 3
    // ...
  },
  computed:{
   // Execute code logic 1
  },
  watch:{
   // Execute code logic 2
  }
}
</script>

<style>

</style>

3, Composite API

ref

<template>
  <div>
    <p>{{count}}</p>
    <button @click="add">add</button>
  </div>
</template>

<script>
import {ref} from "vue"
export default {
  name: 'App',
  setup(){
    // Define a variable named count. The initial value of this variable is 0
    // After this variable is changed, vue will automatically update the page.
    const count  = ref(0);
 // In the composite API, if you want to define methods, you don't need to define them in methods, you can define them directly in the setup function.
    const add = () => {
      count.value+=1;
    }
 // The variables / methods defined in the composition API must be return ed if they want to be used outside.
    return {
      count,
      add
    }
  }
}
</script>

Ref can only listen for changes of simple types, not complex types (objects / arrays). Its essence is reactive. When we pass a value to the ref function, the ref function will automatically convert ref into reactive.

ref(0) -->  reactive({
value:0
})

In addition, it should be noted that if the data is created through ref, it does not need to be obtained through. value when used in template. Because Vue will automatically add. value to us .

So how does vue decide whether to add. value automatically. vue will automatically judge whether the data is ref type before parsing the data. If yes, it will automatically add. value. If not, it will not automatically add. value.

How does vue determine whether the current data is ref type? Through current data__ v_ref. if there is this private attribute and the value is true, it means that it is a ref type data.

Then we developers also have their own api to judge. Isref (data), return true or false.

import {isRef} from 'vue'

reactive

reactive can listen for changes in complex types, such as objects or arrays.

let state = reactive({
 name:"maomin"
});
// or
let arr = reactive([1,2,3]);
<template>
  <div>
    <ul>
      <li v-for="(item,index) in state.list" :key="item.id" @click="removeItem(index)">{{item.id}}--{{item.con}}</li>
    </ul>
  </div>
</template>

<script>
import {reactive} from "vue"
export default {
  name: 'App',
  setup(){
    const state  = reactive({
      list:[
        {
          id:1,
          con:"A"
        },
        {
          id:2,
          con:"B"
        },
        {
          id:3,
          con:"C"
        }
      ]
    });

    const removeItem = (index) => {
      state.list = state.list.filter((item,i)=>i!==index)
    }

    return {
      state,
      removeItem
    }
  }
}
</script>

We can change and put the data and logic together, which solves the problem of data and logic dispersion in vue2.x.

<template>
  <div>
    <ul>
      <li
        v-for="(item, index) in state.list"
        :key="item.id"
        @click="removeItem(index)"
      >
        {{ item.id }}--{{ item.con }}
      </li>
    </ul>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    let {state,removeItem} = userReturn();
    return {
      state,
      removeItem,
    };
  },
};

function userReturn(params) {
  const state = reactive({
    list: [
      {
        id: 1,
        con: "A",
      },
      {
        id: 2,
        con: "B",
      },
      {
        id: 3,
        con: "C",
      },
    ],
  });

  const removeItem = (index) => {
    state.list = state.list.filter((item, i) => i !== index);
  };

  return {state,removeItem}
}
</script>

We have implemented the above deletion function, so we are implementing an added function.

<template>
  <div>
    <input type="text" v-model="state2.items.id">
    <input type="text" v-model="state2.items.con">
    <button @click="addItem">add to</button>
    <ul>
      <li
        v-for="(item, index) in state.list"
        :key="item.id"
        @click="removeItem(index)"
      >
        {{ item.id }}--{{ item.con }}
      </li>
    </ul>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    let {state,removeItem} = userRemove();
    let {state2,addItem} = userAdd(state);
    return {
      state,
      removeItem,
      state2,
      addItem
    };
  },
};
// add to
function userAdd(state) {
   const state2 = reactive({
    items:{
      id:"",
      con:""
    }
  });

  const addItem = () => {
    const items = Object.assign({},state2.items);
    state.list.push(items);
    state2.items.id = "";
    state2.items.con = "";
  };

  return {state,state2,addItem}
}
// delete
function userRemove(params) {
  const state = reactive({
    list: [
      {
        id: 1,
        con: "A",
      },
      {
        id: 2,
        con: "B",
      },
      {
        id: 3,
        con: "C",
      },
    ],
  });

  const removeItem = (index) => {
    state.list = state.list.filter((item, i) => i !== index);
  };

  return {state,removeItem}
}
</script>

If it is another object, the interface will not be updated if the object is modified by default.

<template>
  <div>
    <p>{{state.time}}</p>
    <button @click="add">Plus one day</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  name:"Demo4",
  setup(){
    const state = reactive(
      {
        time:new Date()
      }
    );
    function add () {
      state.time.setDate(state.time.getDate()+1);
      console.log(state);
    }
    return {
      state,
      add
    }
  }
}
</script>

<style>

</style>

If you want to update, you can use the method of re assignment.

<template>
  <div>
    <p>{{ state.time }}</p>
    <button @click="add">Plus one day</button>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "Demo4",
  setup() {
    const state = reactive({
      time: new Date(),
    });
    function add() {
      const newTime = new Date(state.time.getTime());
      newTime.setDate(state.time.getDate() + 1);
      state.time = newTime;
      console.log(state);
    }
    return {
      state,
      add,
    };
  },
};
</script>

<style>
</style>

Similarly, if we developers detect whether a data is reactive. You can use isreactive (data) to return true or false.

import {isReactive} from 'vue'

4, Composite API essence

The composition API and the option API can be mixed. Its essence is injection.

<template>
  <div>
    <p>Vue2.x</p>
    <button @click="cli1">click</button>
    <p>Vue3.0</p>
    <button @click="cli2">click</button>
  </div>
</template>

<script>
import {ref} from "vue"
export default {
  name:"Demo2",
  data(){
    return {
      msg:"Vue2.x"
    }
  },
  methods:{
    cli1(){
      alert(this.msg);
    }
  },
  setup(){
    let txt = ref("Vue3.0"); // Inject into the data function
    function cli2() { // Inject into the methods property
      alert(txt.value); 
    }
    return {
      txt,
      cli2
    }
  }
}
</script>

<style>

</style>

5, setup execution timing and precautions

The setup function is completed before the beforecreate hook. Therefore, data and methods cannot be used. Also note that setup is synchronous, not asynchronous.

<template>
  <div>
    <button @click="name">open</button>
  </div>
</template>

<script>
export default {
  name:"Demo3",
  data(){
    return {
      msg:"hello"
    }
  },
  setup(){
    function name() {
      console.log(this.msg); // undefined
    }
    return {
      name
    }
  }
}
</script>

<style>

</style>

Continue in the next issue

Posted by mehaj on Tue, 30 Nov 2021 22:00:20 -0800