• 技术文章 >web前端 >Vue.js

    聊聊Vue2开发者如何快速上手Vue3

    青灯夜游青灯夜游2022-07-26 19:57:09转载230
    如何快速上手Vue3?下面本篇文章给大家对比一下Vue2和Vue3,并介绍一下Vue2开发者如何快速上手Vue3,希望对大家有所帮助!

    笔者之前是Vue2+React开发者,因项目需要直接上手Vue3,所以快速学习一下,中间会对比一些和React相关的区别。阅读前提:已经上手了Vue2的开发,本文主要聊的问题:

    (学习视频分享:vue视频教程

    Vue2 vs Vue3


    1、简单点说

    2、源码

    了解的不多,后续再补充

    diff算法的优化

    源码管理

    1.png

    全新的API


    什么是组合式 API?- Vue官方

    1、setup

    <script setup>
    const result = await Http.get('/getUserInfo')
    </script>
    // or 
    export default {
      setup(props, context) {
        // Attribute (非响应式对象,等同于 $attrs)
        console.log(context.attrs)
        // 插槽 (非响应式对象,等同于 $slots)
        console.log(context.slots)
        // 触发事件 (方法,等同于 $emit)
        console.log(context.emit)
        // 暴露公共 property (函数)
        console.log(context.expose)
      }
    }

    2、ref

    有一定的心智负担,尤大也明确说了不会支持script中直接访问。究其原因,还是基础类型无法拦截它的变化,当然也有大哥提出用new String('foo')类似的语法对基础类型进行包装。个人感觉直接拿已支持的reactive来搞也不错

    相关api

    3、reactive

    相关api

    import { reactive, toRefs } from 'vue'
    
    const book = reactive({
      author: 'Vue Team',
      year: '2020',
      title: 'Vue 3 Guide',
      description: 'You are reading this book right now ;)',
      price: 'free'
    })
    
    let { author, title } = toRefs(book)
    
    title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref
    console.log(book.title) // 'Vue 3 Detailed Guide'

    4、生命周期

    区别不大,把setup当created用,其它就当改了个名

    <script setup>
    import { onMounted } from 'vue';
    
    const getUserInfo = () => {
      console.log('获取用户信息');
    };
    onMounted(getUserInfo);
    </script>

    2.png

    5、watch & watchEffect

    watch

    import { ref, reactive, watch } from 'vue'
    
    const counter1 = ref(0)
    const counter2 = ref(0)
    // 监听多个
    watch([counter1, counter2], (newValue, oldValue) => {
      console.log('The new counter1 value is: ' + counter1.value)
      console.log('The new counter2 value is: ' + counter2.value)
    })
    
    const obj = reactive({
      name: 'JJ',
      age: 18
    })
    // 深度监听对象
    watch(obj, (newValue, oldValue) => {
      console.log('The new obj value is: ' + obj.value)
    }, {
       deep: true,
       immediate: true
    })
    // watch监听单个属性
    watch(() => obj.name, (newValue, oldValue) => {
      console.log('The new obj value is: ' + obj.value)
    }, {
       deep: true,
       immediate: true
    })

    watchEffect

    const stopWatch = watchEffect(
      (oninvalidate): void => {
        oninvalidate(() => {
          console.log("前置校验函数");
        });
        // 引用了响应式的属性 count
        console.log("watchEffect count变化", count.value);
      },
      {
        // 副作用刷新时机 flush 一般使用post
        // 可选:pre(组件更新前执行)/sync(强制效果始终同步触发)/post(组件更新后执行)
        flush: "post",
        // 开发调试
        onTrigger() {
          console.log("开发调试");
        },
      }
    );

    6、computed

    import { ref, computed } from 'vue'
    
    const counter = ref(0)
    const twiceTheCounter = computed(() => counter.value * 2)
    // get set写法
    const plusOne = computed({
      get: () => counter.value + 1,
      set: (val) => {
        counter.value = val - 1
      },
    })
    
    plusOne.value = 1
    console.log(counter.value) // 0
    
    counter.value++
    console.log(counter.value) // 1
    console.log(twiceTheCounter.value) // 2

    组件


    1、异步组件

    // template
    <Suspense>
      <template #default>
        <AsyncComponent></AsyncComponent>
      </template>
    
      <template #fallback>
        <div>loading...</div>
      </template>
    </Suspense>
    
    // script
    const AsyncComponent = defineAsyncComponent(() => import('./asyncComponent.vue'))

    2、Teleport传送组件

    Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;类似于 React 的 Portal。之前写react是不怎么用这个属性,vue3这个估计也没多大用。

    主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响

    to 属性 插入指定元素位置,body,html,自定义className等等

    <Teleport to="body">
        <Loading></Loading>
    </Teleport>

    3、keep-alive缓存组件

    4、组件通信

    defineXxxx

    defineXxxx 无需import即可直接使用

    provide/inject

    和vue2一致

    vuex & pina

    两者用法,除了pina没有Mutations,差别不大。但是官方推荐的东西,自然有它的各种优点

    TS支持


    import { ref } from 'vue'
    let v = ref<string>('')
    const renderDom = () => {
        return (
            <>
               <input v-model={v.value} type="text" />
               <div>
                   {v.value}
               </div>
            </>
        )
    }
    export default renderDom

    插件


    1、开源插件

    unplugin-auto-import/vite

    无需导入xxx,import { reactive,ref } from "vue";,只需要用即可

    unplugin-vue-define-options

    自定义组件名称,需要引入插件unplugin-vue-define-options,并在vite中配置

    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    import DefineOptions from 'unplugin-vue-define-options/vite';
    
    export default defineConfig({
      plugins: [vue(), DefineOptions()],
    });

    不使用插件,也可以通过多写一个script标签来单独写options

    <script>
        export default {
            name: "TButton",
        };
    </script>
    <script setup>
      defineOptions({
        name: 'TButton',
      });
    </script>

    2、vscode插件

    volar vscode

    3.png

    指令


    1、v-model

    2、自定义指令

    生命周期(和vue3一致)

    自定义拖拽指令v-move

    import { Directive } from "vue";
    const vMove: Directive = {
      mounted(el: HTMLElement) {
        let moveEl = el.firstElementChild as HTMLElement;
        const mouseDown = (e: MouseEvent) => {
          //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
          console.log(e.clientX, e.clientY, "-----起始", el.offsetLeft);
          let X = e.clientX - el.offsetLeft;
          let Y = e.clientY - el.offsetTop;
          const move = (e: MouseEvent) => {
            el.style.left = e.clientX - X + "px";
            el.style.top = e.clientY - Y + "px";
            console.log(e.clientX, e.clientY, "---改变");
          };
          document.addEventListener("mousemove", move);
          document.addEventListener("mouseup", () => {
            document.removeEventListener("mousemove", move);
          });
        };
        moveEl.addEventListener("mousedown", mouseDown);
      },
    };

    Hook


    用了react hook的人都知道很香,vue3支持这个相当不错,能解决很多业务场景的封装

    1、自定义Hook

    可以当做mixins写

    // useWindowResize
    import { onMounted, onUnmounted, ref } from "vue";
    
    function useWindowResize() {
      const width = ref(0);
      const height = ref(0);
      function onResize() {
        width.value = window.innerWidth;
        height.value = window.innerHeight;
      }
      onMounted(() => {
        window.addEventListener("resize", onResize);
        onResize();
      });
      onUnmounted(() => {
        window.removeEventListener("resize", onResize);
      });
      
      return {
        width,
        height
      };
    }
    
    export default useWindowResize;

    2、hook库

    3、react vs vue3

    4.png

    结语


    笔者vue3也刚用不久,如有错误,还请兄弟们指出

    本文所有demo都在该仓库中JJ-UI 一款Vue3组件库,参考大佬文章刚刚搭建好,后续会基于这个架子开发自己的vue3组件库

    5.png

    【相关视频教程推荐:vuejs入门教程web前端入门

    以上就是聊聊Vue2开发者如何快速上手Vue3的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:Vue vue3
    上一篇:Laravel8+Vuejs怎么实现单页面应用(SPA) 下一篇:Vue3中如何自定义指令?代码讲解
    VIP课程(WEB全栈开发)

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• 前端怎么埋点?浅析vue自定义指令进行前端埋点的方法• 聊聊Vue3中的一个好用的功能:Teleport• 分享 6 个实用的 Vue 依赖库(值得收藏)• vue中v-if和v-for哪个优先级高• 总结分享几个 VueUse 最佳组合,快来收藏使用吧!• 【整理分享】Vue开发必备的操作技巧,快来收藏吧!
    1/1

    PHP中文网