Vue3快速入门

Vue3快速入门

Vue3.0 简介

  1. 2020年9月18日,Vue.js 发布3.0版本,代号:One Piece(海贼王)

Vue3 带来了什么

  • 性能的提升,源码的升级,拥抱TypeScript,新的特性 Composition API。

新的特性

Composition API(组合API)

  1. setup 设置
  2. ref 与 reactive
  3. watch 与 watchEffect
  4. provide 与 inject

新的内置组件

  1. Fragment
  2. Teleport
  3. Suspense

其他改变

  1. 新的生命周期钩子

  2. data选项应始终生命为一个函数

  3. 移除keyCode支持为v-on的修饰符

  4. DOM节点的挂载方式

    1. DOM节点挂在的方式从Vue2.0中 new Vue() 实例的方式变成了Vue3中createApp()方法。

    2. //Vue2
      new Vue({
      	el: '#app',
      	router,
      	store,
      	render: h => h(App)
      })
      //Vue3
      createApp(App).$mount("#app");
      

Composition API(组合API)

官方文档:介绍 | Vue.js

  • 使用Vue2的Option API写组件,随着业务复杂度越来越高,代码量会不断的加大;
  • 由于相关业务的代码要遵循option的配置写到特定的区域,导致后续维护非常的复杂,同时可复用性不高,而Composition API就是为了解决这个问题而生的。

拉开序幕的 setup

  1. 理解:Vue3.0中一个新的配置项,值为一个函数。

  2. setup 是所有 Composition API(组合API)"表演的舞台",(入口函数)。

  3. 组件中所用到的:数据,方法等等,均要配置在setup中。

  4. setup 函数的两种返回值:

    1. 若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用。
    2. 若返回一个渲染函数:则可以自定义渲染内容。(了解)
  5. 尽量不要与 Vue2.x 配置混用

    1. Vue2.x配置(data,methods,computed。。。)中可以访问到setup中的属性,和方法。

      但在 setup中不能访问到Vue2.x配置(data,methods,computed。。。),因为setup执行时期的问题:setup会在 beforeCreate执行,所以this是undefined,无法获取 Vue2中配置的数据与方法。。。。反而言之,setup函数执行完毕会返回一个对象对象 对象中的属性和方法都会挂载到vue实例上,所以在Vue2.0中可以访问到setup中的数据。如果有重名,setup优先

  6. setup的执行时机

    1. setup在组件实例创建之前便开始执行,因此在setup选项中没有this。这也意味着,除了props,你将无法访问到组件任何的状态或者方法。 以前data里面的数据我们是直接可以绑定到template上面的,而在vue3.0 Composition API中需要在setup里面return出去,那么数据便会被合并到渲染的上下文中去,从而在template中使用。(在beforeCreate之前执行,this是undefined)
  7. setup 的参数

    1. setup(props,context)/setup(props,{attrs,slots,emit})

      1. props:值为对象,包含组件外部传递过来,且组件内部声明接受了的属性。
      2. context:上下文对象
        1. attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于 this.$attrs
        2. slots:收到的插槽内容,相当于 this.$slots
        3. emit:分发自定义事件的函数,相当于 this.$emitu1kh
    2. 参数 含义
      props 包含props配置声明且传入了的所有属性的对象(props对象是响应式的,不要去解构,解构会失去响式性)
      attrs 包含没有在props配置中声明的属性的对象,相当于this.$attrs
      slots 包含所有传入的插槽内容的对象,相当于this.$slots
      emit 用来分发自定义事件的函数,相当于this.$emit

ref 函数

  1. 作用:定义一个响应式的数据。
  2. 语法:const xxx = ref(initValue);
    1. 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)
    2. js中操作数据:xxx.value
    3. 模板中读取数据,不需要.value 直接使用数据
  3. 备注
    1. 接受的数据可以是:基本类型,也可以是对象类型。
    2. 基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成。
    3. 对象类型的数据:内部“求助“了Vue3.0中的一个函数 ------- reactive 函数 底层是用Proxy来进行拦截。

reactive 函数

  1. 作用:定义一个对象类型的响应式数据(基本类型不要用他,要用ref)
  2. 语法:const 代理对象 = reactive(目标对象),返回一个代理对象(Proxy的实例对象,简称proxy对象)
    1. reactive 定义的响应式数据是 ”深层次的“
    2. 内部基于 ES6 的 Proxy实现,通过代理对象操作源对象内部数据进行操作。

Vue3.0 与 2.x 的响应式原理

  1. Vue2.x的响应式

    1. 实现原理

      1. 对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)

      2. 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)

      3. Object.defineProperty(data, 'xxx', {
            get() {
                return data[xxx];
            }
            set() {
            	set(value) {
                    data[xxx] = value;
                }
        	}
        })
        
    2. 存在的问题

      1. 新增属性,删除属性,界面不会更新。
        1. 解决方案:
          1. 新增:Vue.set(object, key, value) 或 vm.$set(object, key, value)
          2. 删除:Vue.delete(object, key, value) 或 vm.$delete(this.person, 'name')
      2. 直接通过下标修改数组,界面不会自动更新。
        1. 解决方案:this.$set('要修改的数组', '数组索引', '修改的值') 或 Vue.set('要修改的数组', '数组索引', '修改的值') 或 调用数组本身的方法进行响应式修改 this.arr.splice(0, 1, '修改的数据')
  2. Vue3.0 响应式

    1. 实现原理

      1. 通过 Proxy(代理):拦截对象中任意属性变化,包括属性的读写,属性的添加,属性的删除等。

      2. 通过Reflect(反射):对目标对象的属性进行操作。

        1. let proxy = new Proxy(data, {
              // 拦截读取属性值
              get(target, prop) {
                  return Reflect.get(target, prop);
              },
              // 拦截设置属性值或添加新的属性
              set(target, prop, value) {
                  return Reflect.set(target, prop, value);
              },
              // 拦截删除属性
              deleteProperty(target, prop) {
                  return Reflect.deleteProperty(target, prop)
              }
          });
          proxy.name = '权';
          

reactive 对比 ref

  1. 从定义角度对比

    1. ref用来定义:基本数据类型。

    2. reactive用来定义:对象(或数组)类型。

    3. 备注:ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象。

      1. import { ref } from 'vue'
        let person = ref({name: 'zs', age: 20});
        自动转换 ===> reactive({value: {name: 'zs', age: 20}})
        
  2. 从原理角度对比

    1. ref 通过 Object.definePrototype() 的 get 与 set 来实现数据响应(数据劫持)。
    2. reactive 通过使用 Proxy 来实现数据响应式(数据劫持),并通过Reflect操作目标对象内的数据。
  3. 从使用角度对比

    1. ref 定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
    2. reactive定义的数据:操作数据与读取数据:均不需要 .value

计算属性与监视

computed函数

  • 与Vue2.x中computed配置功能一致。

  • import { computed } from 'vue'
    setup() {
    	//....
        // 计算属性-简写
        let fullName = computed(()=> {
            return `${person.firstName}-${person.lastName}`;
        })
        // 计算属性-完整
        let fullName = computed({
            get() {
                return `${person.firstName}-${person.lastName}`;
            },
            set(value) {
                person.firstName = value.split('-')[0];
                person.lastName = value.split('-')[1];
            }
        })
    }
    

watch 函数

  • 与Vue2.x中的 watch 配置功能一致
  • 两个小坑
    • 监视reactive定义的响应式数据时:oldValue无法获取,强制开启了深度监视(deep配置失效)
    • 监视reactive定义的响应式数据某个属性时:deep配置有效

新特性

  • Composition API(组合 API)

  • Dom 节点的挂载方式

    
    
  • setup

    • composition api其实是配合着 options选项一起使用的,因为还有name、props、components、setup这些选项。只不过是现在所有的功能都成为了一个一个的hook函数,在使用时需要手动引入,并且需要写在setup选项里面。而setup的存在就是为了让我们能够使用composition api。、

  • reactive

    • reactive是Vue3中提供的实现响应式数据的方法。

    • reactive接受一个普通对象然后返回该普通对象的响应式代理

      • setup() {
            const user = reactive({
                name: '码农权',
                age: 20
            })
        }
        
      • 普通对象 ==> 返回一个proxy对象

      • 用user.name = "xxx" 来修改值

      • 内部基于proxy实现

      • 获取数据值的时候直接获取,不需要加.value

      • 参数只能传入对象类型(json/arr)

        • 如果给reactive传递了其他对象
          • 默认情况下修改对象,界面不会自动更新
          • 如果想更新,那就通过重新赋值的方式
  • ref 接受一个内部值柄返回一个响应可以变的ref对象

    • import { ref } from "vue"
      // 为基本数据类型添加响应状态
      const name = ref('权');
      
      // 为复杂数据类型添加响应状态
      const state = ref({
          count: 0
      })
      // 打印name的值
      console.log(name.value);
      // 打印count的值
      console.log(state.value.count)
      
      
    • 任意类型 ==> 返回一个ref对象

    • 用 name.value = "" 来修改值

    • 获取数据值的时候需要添加.value。可以理解为ref是通过reactive包装了一层具有value属性的对象来实现的

    • 参数可以传递任意类型数据,传递对象类型时也能保持深度响应式,所以适用性更广,setup中定义数据时推荐优先使用ref,方便逻辑拆分和业务解耦。

    • template中使用ref值不用通过value获取(导出后已经默认做了一个结构),js中使用ref必须通过.value获取

    • ref获取元素

      • import { ref, onMounted } from 'vue'
        export default {
          name: "Demo",
          setup() {
            const userIpt = ref(null);
            onMounted(()=> {
              userIpt.value.focus();
            });
            return {
              userIpt
            }
          }
        }
        
  • toRef

    • toRef 用于为源响应式对象上的属性新建一个ref,从而保持对其源对象属性的响应式连接。
    • 接受两个参数:源响应对象和属性名,返回一个ref数据。
    • 例如:使用父组件传递的props数据时,要引用props的某个属性且要保持响应式连接就很有用
posted @ 2022-06-02 16:39  HuangBingQuan  阅读(303)  评论(0编辑  收藏  举报