×

Vue3 ref包装及setup函数等等

2021-03-03 04:51:00 Falcon

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>

本文收录于