Vue3第一次使用:ref与reactive的区别和注意事项

今天使用Vue3写了一个todo的例子

在这里插入图片描述

Vue3对我最大的感觉:

1、template标签下面可以有多个节点了,终于不用先写一个DIV了

2、setup函数可以代替之前的data,methods,computed,watch,Mounted等对象,但是props声明还是在外面。

不过我总是忘记在return里面写声明好的变量或者方法,导致报错没有这个变量或者函数。这一点还需要适应。希望以后能有方便的插件出现。

const todoList = reactive([])
const todoItem = ref('')

3、ref与reactive方法的区别是什么?一个是把值类型添加一层包装,使其变成响应式的引用类型的值。另一个则是引用类型的值变成响应式的值。所以两者的区别只是在于是否需要添加一层引用包装?其目的都是对数据添加响应式效果。

使用ref包装之后,需要使用.value才行进行取值和赋值操作。这就导致一个结果,就是在对象起属性名时,尽可能避开有value的属性名。因为会引起混淆,让人不知道是ref方法加上去的属性,还是原来对象就是这样的结构!

4、响应式对象里面如果有ref包装的值类型。则Vue会实现自动拆箱,即获取值的方式是object.property,而不是object.property.value,注意:只有响应式对象会是这样,响应式数组或者Map都不能这样。这一点在文档里面专门提到了。需要多注意。

在这里插入图片描述
上文说ref自动拆箱只发生在响应式对象内部。而在数组和原生集合如:Map里面访问ref是没有这种行为的。

5、watch监听没有响应式的变量时,需要方法包装,响应式变量可以直接监听。与Vue2的写法不同,要更需要小心和注意了。文档里面有说明

在这里插入图片描述

如果值类型监听,浏览器也会给你直接说明错误原因,很详细。

在这里插入图片描述

上面说:非法的监听源:<值>,源只能是一个getter函数,或者ref包装过的值,或者一个响应式对象,还有数组以上这些类型。

6、想自己下载Vue3来玩一玩的小伙伴,可以使用 npm init vite-app hello-vue3 命令下载一个Vue3的例子。然后用npm run dev启动就可以开始了。官方文档目前还是beta版本,但是已经基本不会大改了。文档地址

下面是源码:
真正的js代码其实还不到20行,比Vue2来说,真得是很大的进步了。节省了很多样板代码,逻辑也更加紧凑了。

<template>
  <h1>{
    
    {
    
     msg }}</h1>
  <p>left {
    
    {
    
     leftNum }} thing(s) have to do</p>
  <input v-model="todoItem" placeholder="write some thing todo" @keyup="e => { if(e.keyCode == 13) add() }">
  <button @click="add">add</button>
  
  <div v-for="(item, index) in todoList" :key="index">
    <input type="checkbox" @input="finish(index)">
    <input v-if="item.editable" v-model="item.value" @keyup="edited($event, index)">
    <span v-else :class="{'item-text':item.finished}" @dblclick="editable(index)">{
    
    {
    
     item.value }}</span>
    <button @click="del(index)">del</button>
  </div>
</template>

<script>
import {
    
     ref, reactive, watch, computed, onMounted } from 'vue'
export default {
    
    
  name: 'HelloWorld',
  props: {
    
    
    msg: String
  },
  setup() {
    
    
    const todoList = reactive([])
    const todoItem = ref('')
    const leftNum = computed(() => todoList.filter(_ => !_.finished).length)
    const add = () => {
    
    
      todoList.push({
    
    value: todoItem.value, finished: false, editable: false})
      todoItem.value = ''
    }
    const finish = (index) => todoList[index].finished = !todoList[index].finished
    const del = (index) => todoList.splice(index, 1)
    // 编辑功能
    const editable = (index) => {
    
    
      if (!todoList[index].finished) todoList[index].editable = true
    }
    const edited = (event, index) => {
    
    
      if (event.keyCode == 13) todoList[index].editable = false
    }

    return {
    
    
      todoItem, todoList, leftNum,
      add, finish, del, editable, edited
    }
  },
}
</script>
<style scoped>
.item-text {
    
    
  text-decoration:line-through
}
</style>

Guess you like

Origin blog.csdn.net/cuipp0509/article/details/108199513