• 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的某个属性且要保持响应式连接就很有用
  • 相关阅读:
    (离线算法 LCA) hdu 2874
    (树形DP) hdu 4118
    (树的重心) poj 1655
    (线性基) bzoj 2115
    (线性基) bzoj 2460
    (边双联通+树直径) hdu 4612
    (拓扑图+DP) poj 3249
    (求割点和除去割点后的联通块数目) poj 1523
    (边双联通) poj 3352
    (DP求最长路) hdu 4607
  • 原文地址:https://www.cnblogs.com/bingquan1/p/16338254.html
Copyright © 2020-2023  润新知