Vue3 学习笔记

1. Vue3 初识

1.1 Vue3 简介

  • 发布时间:2020年9月
  • 开发团队:尤雨溪团队
  • 开发时长:2年多

1.2 Vue3 特点

  • 性能提升
    • 打包大小减少41%
    • 初次渲染快51%,更新渲染快133%
    • 内存占用减少54%
  • 源码升级
    • 使用 Proxy 代替 Object.defineProperty 实现双向数据绑定
    • 重写虚拟DOM的实现和 Tree-Shaking
  • 更好的 TypeScript 支持
  • 新特性
    • Composition API(组合式API)
    • setup 配置
    • ref 和 reactive
    • watch 和 watchEffect
    • provide 和 inject
    • 新的内置组件:FragmentTeleportSuspense
    • 新的生命周期钩子
    • 移除 keyCode 作为 v-on 的修饰符

1.3 创建 Vue3 工程项目

# 1. 确保 vue-cli 版本在 4.5.0 以上
vue -V 或 vue --version

# 2. 如果版本低,重新安装 vue-cli
npm install -g @vue/cli

# 3. 创建项目
vue create vue3-project

# 4. 进入项目目录
cd vue3-project

# 5. 启动项目
npm run serve

1.4 Vue3 目录结构分析

  • Vue3 入口文件 main.js
    import { createApp } from 'vue'
    import App from './App.vue'
    const app = createApp(App).mount('#app')

 Vue2 入口文件 main.js

  • Vue2 入口文件 main.js
    import Vue from 'vue'
    import App from './App.vue'
    const vm = new Vue({
      render: h => h(App),
    }).$mount('#app')

2. Composition API

2.1 setup 函数

  • 作用:Vue3 新增的配置项,值为一个函数,所有的组合式 API 方法都写在 setup 函数中。
  • 返回值:返回一个对象,对象中的属性和方法可以在模板中直接使用。
  • 示例
    export default {
      setup() {
        let name = "张三";
        let age = 20;
        function sayHello(m) {
          alert(`${name}--${age}--${m}`);
        }
        return {
          name,
          age,
          sayHello,
        };
      },
    };

2.2 setup 执行时间

  • 执行时间:在 beforeCreate 之前执行,且 setup 中获取不到 thisthis 为 undefined

2.3 ref 响应式函数

  • 作用:将基本类型数据处理成响应式数据。
  • 语法const xxx = ref(数据变量)
  • 示例
    import { ref } from "vue";
    export default {
      setup() {
        let name = ref("张三");
        let age = ref(20);
        function change() {
          name.value = "李四";
          age.value = 30;
        }
        return {
          name,
          age,
          change,
        };
      },
    };

2.4 reactive 函数

  • 作用:定义一个对象类型的响应式数据,返回一个 Proxy 实例对象。
  • 语法const 代理对象 = reactive(源对象)
  • 示例
    import { reactive } from "vue";
    export default {
      setup() {
        let job = reactive({
          type: "前端工程师",
          salary: "20k",
        });
        function changeFn() {
          job.type = "后端开发工程师";
          job.salary = "30k";
        }
        return {
          job,
          changeFn,
        };
      },
    };

3. Vue3 响应式原理

3.1 Vue2.x 的响应式原理

  • 实现原理:通过 Object.defineProperty() 对属性的读取、修改进行拦截。
  • 问题
    • 无法添加和删除属性
    • 无法捕获到修改数组下标改变对应数组

3.2 Vue3 响应式原理

  • 实现原理:通过 Proxy 代理,拦截对象中任意属性的变化,包括属性的读取、修改、设置、删除。
  • 示例
    let data = {
      name: "张三",
      age: 30,
    };
    let p = new Proxy(data, {
      get(target, propName) {
        console.log(`读取p上的${propName}属性`);
        return Reflect.get(target, propName);
      },
      set(target, propName, value) {
        console.log(`修改p的${propName}属性`);
        return Reflect.set(target, propName, value);
      },
      deleteProperty(target, propName) {
        console.log(`删除p上的${propName}属性`);
        return Reflect.deleteProperty(target, propName);
      },
    });

4. Vue3 中的组件传参

4.1 父传子

  • 父组件
    <template>
      <Testvue3 :tit="schoolName"></Testvue3>
    </template>
    <script>
    import Testvue3 from "@/components/Testvue3";
    export default {
      setup() {
        let schoolName = "青山";
        return { schoolName };
      },
    };
    </script>

  • 子组件
    <template>
      <p>{{ tit }}</p>
    </template>
    <script>
    export default {
      props: ["tit"],
      setup(props) {
        console.log(props);
      },
    };
    </script>

4.2 子传父

  • 子组件
    
    
    <template>
      <button @click="emit">点击事件,子传父</button>
    </template>
    <script>
    export default {
      emits: ["transfer"],
      setup(props, context) {
        function emit() {
          context.emit("transfer", 666);
        }
        return { emit };
      },
    };
    </script>

  • 父组件
    <template>
      <Testvue3 @transfer="showdata"></Testvue3>
    </template>
    <script>
    import Testvue3 from "@/components/Testvue3";
    export default {
      setup() {
        function showdata(value) {
          console.log(value);
        }
        return { showdata };
      },
    };
    </script>

5. Vue3 中的计算属性

  • 引入import { computed } from "vue"
  • 示例
    
    
    <template>
      <Testvue3 @transfer="showdata"></Testvue3>
    </template>
    <script>
    import Testvue3 from "@/components/Testvue3";
    export default {
      setup() {
        function showdata(value) {
          console.log(value);
        }
        return { showdata };
      },
    };
    </script>

6. Vue3 中的 watch 监听器

  • 引入import { watch } from "vue"
  • 示例
    import { ref, watch } from "vue";
    export default {
      setup() {
        let sum = ref(0);
        watch(sum, (newvalue, oldvalue) => {
          console.log(newvalue, oldvalue);
        });
        return { sum };
      },
    };

7. Vue3 生命周期

  • 变化
    • beforeDestroy => beforeUnmount
    • destroyed => unmounted
  • 示例
    
    
    import { onMounted, onUnmounted } from "vue";
    export default {
      setup() {
        onMounted(() => {
          console.log("mounted");
        });
        onUnmounted(() => {
          console.log("unmounted");
        });
      },
    };

8. Vue3 中的自定义 hook 函数

  • 定义:本质是一个函数,将 setup 中的公共逻辑抽离出来放在一个单独的 js 文件。
  • 示例
    
    
    // usePoint.js
    import { reactive, onMounted, onBeforeUnmount } from "vue";
    export function usePoint() {
      let point = reactive({ x: 0, y: 0 });
      onMounted(() => {
        document.onclick = function (event) {
          point.x = event.pageX;
          point.y = event.pageY;
        };
      });
      onBeforeUnmount(() => {
        document.onclick = null;
      });
      return point;
    }

9. toRef 与 toRefs

  • toRef:将响应对象中的某个属性单独拿出来变成响应属性。
  • toRefs:将对象中的多个属性转换成响应数据。
  • 示例
    
    
    import { reactive, toRefs } from "vue";
    export default {
      setup() {
        let person = reactive({
          name: "张三",
          age: 20,
        });
        return { ...toRefs(person) };
      },
    };

10. Vue3 中的路由

  • 安装npm install vue-router@4
  • 配置
    
    
    import { createRouter, createWebHashHistory } from "vue-router";
    const routes = [
      { path: '/home', component: () => import('@/views/Home') },
      { path: '/category', component: () => import('@/views/Category') },
    ];
    const router = createRouter({
      history: createWebHashHistory(),
      routes,
    });
    export default router;

11. Vue3 中的 Vuex

  • 安装npm install vuex@next --save
  • 配置
    
    
    import { createStore } from 'vuex';
    export default createStore({
      state: { count: 100 },
      getters: { getCount: (state) => state.count * 2 },
      mutations: { setTestA: (state, value) => state.count = value },
    });

12. Pinia 状态管理

  • 简介:Pinia 是 Vuex 的替代品,可以看作是 Vuex 5。
  • 示例
    // counter.ts
    import { ref, computed } from 'vue';
    import { defineStore } from 'pinia';
    export const useCounterStore = defineStore('counter', () => {
      const count = ref(0);
      const doubleCount = computed(() => count.value * 2);
      function increment() { count.value++; }
      return { count, doubleCount, increment };
    });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值