vue3详细讲解

一.简介

Vue 3是一种流行的JavaScript框架,用于构建用户界面。它是Vue.js框架的最新版本,于2020年9月正式发布。Vue 3在Vue 2的基础上进行了重大改进和增强,并提供了更好的性能、更好的开发体验和更多的功能。

以下是Vue 3的一些主要特点和改进:

  1. 响应式系统:Vue 3使用Proxy对象替代了Vue 2中基于Object.defineProperty的劫持方式。这样的改变使得Vue 3的响应式系统更强大和灵活。它能够捕获更多类型的变更,提供更好的性能,并且能够处理动态添加的属性和删除属性。

  2. 组件模型:Vue 3引入了组合式API(Composition API),作为选项式API(Options API)的补充。组合式API允许开发人员更好地组织和复用组件逻辑,通过使用函数来组织代码,而不仅仅依靠选项。这种方式提供了更灵活、组合性更强的组件开发方式。

  3. 性能优化:Vue 3采用了虚拟DOM算法的改进,通过静态提升(Static Nodes Hoisting)和基于模块的编译优化,提供了更好的性能。它具有更高的渲染速度、更小的包大小,以及更好的Tree-shaking支持,使您的应用程序更高效。

  4. Teleport组件:Vue 3引入了Teleport组件,它使得在DOM树中的任何位置渲染组件变得更容易。它可以帮助您处理跨组件层级的弹出窗口、对话框和模态框等场景。

  5. TypeScript支持:Vue 3更好地集成了TypeScript,并提供了更准确的类型推断和类型检查。这使得在Vue应用程序中使用TypeScript变得更加流畅和安全。

总体而言,Vue 3在性能、开发体验和功能方面都有明显的改进和增强。它提供了更好的响应式系统、更灵活的组件开发方式和更高的性能,使开发人员能够构建出更高效、易维护和功能丰富的应用程序。
 

二.使用

安装

1、确定node 版本
在这里插入图片描述
2、确定 npm 版本
在这里插入图片描述
3、安装 vue3.0

npm install -g @vue/cli

4、 查看 vue脚手架的版本

vue -V

5、 创建项目

vue create my-project (项目名)

6、 选中安装vue3.0

7、运行项目

npm run serve

声明变量

使用响应式变量

在Vue3中,响应式变量是通过ref()reactive()函数创建的。ref()函数用于创建单一的响应式变量,而reactive()函数则用于创建包含多个属性的响应式对象。

下面是一个例子,演示如何在setup()函数中创建一个响应式变量:

import { ref } from 'vue';
   export default {
      setup() {
        const count = ref(0);
   return {count};}
};

在上面的代码中,我们使用了ref()函数来创建一个名为count的响应式变量,并将其初始化为0。然后,在setup()函数中将这个变量返回给模板。

在模板中使用这个变量时,需要使用.value来访问变量的值:

使用普通变量

除了响应式变量外,你还可以在setup()函数中声明普通变量。这些变量不会被自动监听,也就是说,当它们的值发生改变时,组件不会自动更新。

下面是一个例子,演示如何在setup()函数中声明普通变量:

export default {
     setup() {
        const name = 'John Doe';
     return {name};}
};

在上面的代码中,我们声明了一个名为name的普通变量,并将其初始化为'John Doe'。然后,在setup()函数中将这个变量返回给模板。

在模板中使用这个变量时,可以直接调用它:

如何修改变量值。

在Vue 3中,要修改变量的值,可以使用ref函数来创建一个响应式的变量,并使用.value属性来访问和修改该变量的值。下面是一个最简单的例子:

import { ref } from 'vue'; 

// 创建一个响应式的变量 
const count = ref(0);

 // 访问变量的值 
console.log(count.value); // 输出: 0 

// 修改变量的值 
count.value = 10; // 

再次访问变量的值 
console.log(count.value); // 输出: 10

在上面的例子中,我们使用ref函数创建了一个响应式的变量count,初始值为0。通过count.value可以访问和修改该变量的值。在修改变量的值时,直接对count.value进行赋值即可。

需要注意的是,对于普通的JavaScript对象和数组,Vue 3提供了reactive函数和readonly函数,分别用于创建可变和只读的响应式对象。如果需要对复杂的对象进行修改,可以使用类似的方式来创建并修改响应式对象。


如何定义事件,方法

在Vue 3中,您可以使用methods选项来定义事件和方法。下面是一个最简单的例子:




在上面的例子中,我们定义了一个按钮,并通过@click来监听按钮的点击事件。事件处理函数increment定义在methods选项中。当按钮被点击时,increment方法会被调用,并在控制台上输出文本。

需要注意的是,在Vue 3中,无需再使用this关键字来访问组件的方法。方法直接定义在methods选项下,可以直接在方法内部进行逻辑操作。

当然,您可以在方法中进行更复杂的逻辑操作、数据更新、使用组合式API等。以上示例仅作为最简单的例子,展示了如何定义事件和方法。


同时,您还可以使用箭头函数来定义方法,这样可以避免上下文绑定的问题,如下所示:




在这个例子中,increment方法使用箭头函数来定义,无需担心上下文的绑定问题,仍然可以正常响应点击事件。

这就是Vue 3中定义事件和方法的最简单示例。通过methods选项,您可以定义各种处理函数来响应用户的交互事件,以及执行其他逻辑操作。

生命周期

1、setup() : 开始创建组件之前,在 beforeCreate 和 created 之前执行,创建的是 data 和 methods

2、onBeforeMount() : 组件挂载到节点上之前执行的函数;

3、onMounted() : 组件挂载完成后执行的函数;

4、onBeforeUpdate(): 组件更新之前执行的函数;

5、onUpdated(): 组件更新完成之后执行的函数;

6、onBeforeUnmount(): 组件卸载之前执行的函数;

7、onUnmounted(): 组件卸载完成后执行的函数;

8、onActivated(): 被包含在  中的组件,会多出两个生命周期钩子函数,被激活时执行;

9、onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行;

10、onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数。

Vue2.X和Vue3.X对比

  1. vue2 -------> vue3

  2. beforeCreate --------> setup(()=>{})

  3. created --------> setup(()=>{})

  4. beforeMount --------> onBeforeMount(()=>{})

  5. mounted --------> onMounted(()=>{})

  6. beforeUpdate --------> onBeforeUpdate(()=>{})

  7. updated --------> onUpdated(()=>{})

  8. beforeDestroy --------> onBeforeUnmount(()=>{})

  9. destroyed --------> onUnmounted(()=>{})

  1. activated --------> onActivated(()=>{})

  2. deactivated --------> onDeactivated(()=>{})

  3. errorCaptured --------> onErrorCaptured(()=>{})

总结: Vue2和Vue3钩子变化不大,beforeCreate 、created  两个钩子被setup()钩子来替代。

 

main.js的变化

创建好项目后和Vue2时候一样,首先来看看整个项目的入口文件main.js。

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

我们可以发现,引入的不再是Vue构造函数了,而是一个名为createApp的工厂函数。试着去回想一下以前的写法,并且将生成的这三行代码进行拆分做个对比。

import { createApp } from 'vue'
import App from './App.vue'
 
// Vue 3 
const app = createApp(App)
app.mount('#app')
 
// createApp(App).mount('#app')
 
// Vue 2
const vm = new Vue({
    render: h => h(App)
})
vm.$mount('#app')

定义全局变量

vue2中可以通过Vue.prototype去操作原型,在vue3中只能通过app.config.globalProperties,当时玩的时候还以为自己写错了,修改的这些你会发现改动的东西挺多的变量

举例:定义一个全局的组件

  const app = createApp(App)
    app.component('MyDiv',MyDiv)
    app.use(store).use(router).mount('#app')

举例:定义全局

    main.js中
    app.config.globalProperties.$myVals = 'Hello, world!';
    调用方式:this.$myVals 
    这种方式不适用于setup的Composition API
    
    如果使用setup方法:
    main.js中
    app.provide('$duMy', 'abceffef');
    
    页面中:setup中
    import { inject } from 'vue';
    const kk  = inject('$duMy');
    return {kk}

指令与插槽

插槽的用途就和它的名字一样:有一个缺槽,我们可以插入一些东西。

插槽 slot 通常用于两个父子组件之间,最常见的应用就是我们使用一些 UI 组件库中的弹窗组件时,弹窗组件的内容是可以让我们自定义的,这就是使用了插槽的原理。

我们在项目中新建一个 child.vue 文件,用来当作子组件,它的代码也非常的简单。


然后我们直接在 App.vue 引用该子组件,代码如下:


 
 

响应式原理

实现原理:
通过Proxy(代理): 拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。

通过Reffect(反射): 对源对象的属性进行操作

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

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

被 Proxy 代理虚拟化的对象。它常被作为代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量(保持不变的语义)。

语法:

const p = new Proxy(target, handler)

参数:
target:
要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler:
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

计算属性(computed)

计算属性使用

首先呢,使用 computed 需要引入。

import { computed } from 'vue'

引入这一个步骤是不可或缺的。

计算属性的定义

在Vue中,计算属性是一个函数,它会根据依赖的数据动态计算出一个新的值。计算属性的定义方式是在Vue组件的computed选项中创建一个函数。下面是一个计算属性的示例:




在上述代码中,我们定义了一个计算属性reversedMessage,它通过将message反转后返回一个新的值。

计算属性的特点

与其他数据绑定方式相比,计算属性具有以下几个特点:

  • 缓存性:计算属性会缓存依赖的数据,只有当依赖的数据发生变化时才会重新计算。如果多次访问该计算属性,Vue会直接返回缓存的结果,提高了性能。
  • 响应式:计算属性依赖的数据发生变化时,会自动重新计算,并更新绑定到该计算属性的视图。
  • 可读性:计算属性允许我们编写更清晰、可读性更高的代码,将复杂的逻辑封装在一个函数中,提高了可维护性。

使用

计算属性的读取

在Vue模板中,我们可以直接读取计算属性的值,就像读取普通的属性一样。下面是一个读取计算属性的示例:




计算属性的设置

在特定的情况下,我们可能希望通过计算属性来实现双向绑定。在Vue3中,可以通过添加getset方法来实现计算属性的设置。下面是一个设置计算属性的示例:




 

应用场景 

 数据过滤与排序

计算属性可以用于对数据进行过滤和排序。例如,我们有一个包含用户信息的数组,想要根据某种条件对用户进行筛选。我们可以使用计算属性来动态计算符合条件的用户列表。下面是一个示例:




在上述代码中,我们定义了一个计算属性filteredUsers,它根据ageThreshold筛选出年龄大于等于30的用户列表。在模板中,通过v-for指令遍历该列表并显示用户名称。

表单验证

计算属性可以用于表单验证,根据不同的条件判断表单字段是否有效。例如,我们有一个登录表单,需要验证用户名和密码是否满足一定的要求。我们可以使用计算属性来动态计算验证结果,并将其绑定到表单的错误提示信息上。下面是一个示例:




在上述代码中,我们定义了两个计算属性usernameErrorpasswordError,它们根据表单字段的值和正则表达式来判断是否满足要求,并返回相应的错误提示信息。在模板中,我们通过{{ usernameError }}{{ passwordError }}将错误提示信息显示出来。通过这种方式,我们可以实时根据用户输入更新错误提示,提高表单的交互性和用户体验。

总结

计算属性是Vue3中非常有用的特性之一,它能够根据依赖的数据动态计算出新的值,并具有缓存性、响应式和可读性等特点。本文介绍了计算属性的基本概念、使用方式和常见的应用场景。通过合理地应用计算属性,我们可以简化代码、提高性能和可维护性,从而更高效地开发Vue应用程序。

router(路由)

安装和配置Vue Router

安装Vue Router

安装Vue Router只需要在vue项目中打开终端,输入如下命令即可安装:

npm 方式安装

npm install vue-router@4

yarn方式安装

yarn add vue-router@4

配置Vue Router

为了便于我们后面代码维护和管理,我们一般将路由相关的代码统一放到一个文件夹中。因此,配置Vue Router的步骤如下:

  1. 在src文件夹新建一个router文件夹,在该文件夹下新建index.js文件
  2. 在index.js中引入vue-router中的createRouter 和 createWebHashHistory 方法,引入页面文件
import { createRouter,createWebHashHistory } from "vue-router";
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import List from '../views/List.vue'
import Detail from '../views/Detail.vue'
  1. 在index.js中定义一个routes数组,在里面定义路由规则
const routes = [
  {
    path:'/home',
    name:Home,
    component:Home
  },
  {
    path:'/about',
    component:About
  },
  {
    path:'/list',
    component:List
  },
  {
    path:'/detail',
    component:Detail
  },
  {
    path:'/',
    redirect:'/home'
  }
]
  1. 在index.js中使用createRouter创建路由实例,并配置路由模式和上面定义的路由规则
const router = createRouter({
  history:createWebHashHistory(),
  routes
})
  1. 在index.js的最后,使用export default 将上面创建的路由实例导出
export default router
  1. 注册路由:在main.js中导入上面创建的路由文件,并使用app.use注册路由
import router from './router'
const app = createApp(App)
app.use(router) //注册路由
app.mount('#app')
  1. 在组件中使用路由组件
    在App.vue中使用组件来渲染要显示的组件,在Tabbar组件中使用组件生成链接

App.vue组件中代码




Tabbar组件中代码




至此,我们就完成了路由的配置与搭建,运行程序,刷新浏览器,可以看到页面已经可以正常跳转,实现了路由功能。

虽然上面我们已经实现了一个完整的路由场景搭建,但是我们还是要对Vue Router的基础知识进行深入的了解,方便我们更好的理解和使用Vue Router。下面对Vue Router中的一些基本概念进行介绍。

Vue Router的基本概念

  1. 路由器:Vue Router 提供了一个路由器,用于管理应用程序中的路由。Vue Router 实例化一个 Vue Router 对象,注册路由规则,并以它为中心连接其他组件。

  2. 路由:路由是分发到不同组件的 URL 地址。在 Vue Router 中,路由通常是由 path 规则和相应的组件定义的。当浏览器的 URL 匹配到路由的 path 后,相应的组件将会被加载到页面中。路由的信息可以从 route 对象中获取。

  3. 路由规则:路由规则是由 path、component、name、meta、props 等属性组成的。其中,path 表示 URL 的路径,component 表示要渲染的组件,name 表示路由名称,meta 表示路由的元数据,props 表示路由 props 数据。路由规则可以注册到 Vue Router 中。

  4. 导航守卫:导航守卫是在路由跳转时执行的钩子函数,用于控制路由的访问权限、处理路由跳转前后的逻辑等。在 Vue Router 中,对于选项式 API,常用的导航守卫有 beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave 等;对于使用组合 API 和 setup 函数来编写组件的,可以通过 onBeforeRouteUpdate 和 onBeforeRouteLeave 分别添加 update 和 leave 守卫。

Vue Router 的配置项介绍

我们在使用Vue Router 中的createRouter创建router对象时,其为我们提供了很多配置项,带完整配置项的示例代码如下:
 

const router = createRouter({
  history: createWebHashHistory(),
  routes: [],
  scrollBehavior: () => ({ top: 0, left: 0 }),
  linkActiveClass: 'active',
  linkExactActiveClass: 'exact-active',
  parseQuery: null,
  stringifyQuery: null,
  fallback: true
})

上面代码中各个配置项的含义如下:

  1. history:指定路由的 history 模式,目前支持 createWebHistory()和 createWebHashHistory()模式。

  2. routes:定义路由规则的数组,每一个路由规则都是一个对象,包含 pathnamecomponent 和 meta 等属性。

  3. scrollBehavior:指定路由切换时滚动行为的配置函数。该函数返回一个包含 x 和 y 属性的对象,表示页面跳转后滚动的位置。

  4. linkActiveClass:指定激活状态的链接的 class 名称,默认为 'router-link-active'

  5. linkExactActiveClass:指定精确匹配的激活状态的链接的 class 名称,默认为 'router-link-exact-active'

  6. parseQuery 和 stringifyQuery:用于配置路由的查询参数解析和序列化函数。通常情况下,我们不需要额外配置这两个函数,因为 Vue Router 已经提供了默认的实现。

  7. fallback:用于配置是否开启 HTML5 History 模式的回退机制。默认值为 true,表示当路由不匹配时,将自动回退到历史记录中的上一个路由。

上面的配置项中,我们一般只需要配置history和routes两个选项就可以了,其它选项了解即可

routes中的配置项介绍

在 Vue Router 中,路由规则的配置是通过 routes 属性来实现的。routes 属性中常用的配置如下:

  1. name:路由规则的名字。可以用于编程式导航和组件内部的路由跳转。

  2. path:路由的路径,可以包含动态参数和正则表达式。例如,/user/:id 表示用户页面,:id 是一个动态参数。

  3. redirect:路由的重定向规则。例如,{ path: '/', redirect: '/home' } 表示路由根路径的重定向。

  4. component:路由对应的组件。可以是一个普通的组件类或异步加载的组件。

  5. children:当前路由的子路由。可以是一个路由规则数组,也可以是一个函数,动态生成路由规则。

  6. meta:路由的元信息,用于描述路由的一些额外信息。例如,路由是否需要登录、权限鉴定等。

  7. components:路由对应的多个命名视图组件。

路由跳转

通过Vue Router,我们可以通过router-link组件的to方法和使用router.push函数以编程方式两种方法导航到路由。

使用 router-link组件

使用router-link组件实现路由跳转,我们只需要将菜单按钮使用router-link组件包裹,并在上面使用to方法即可进行跳转,示例代码如下:

Home List About

使用router.push函数

使用router.push函数以编程方式实现路由跳转,我们只需要在普通按钮上绑定click事件,并在事件中调用router.push()方法即可实现跳转,示例代码如下:



使用 router.push 方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。

事实上,当我们点击  时,Vue Router 内部会调用这个方法,所以点击  相当于调用 router.push(...)

hooks模式


提纯代码,可以把逻辑放到单独的文件中,甚至可以复用hooks

一、 什么是hooks

hook是钩子的意思,看到“钩子”是不是就想到了钩子函数?事实上,hooks 还真是函数的一种写法。

vue3 借鉴 react hooks 开发出了 Composition API ,所以也就意味着 Composition API 也能进行自定义封装 hooks

vue3 中的 hooks 就是函数的一种写法,就是将文件的一些单独功能的js代码进行抽离出来,放到单独的js文件中,或者说是一些可以复用的公共方法/功能。其实 hooks 和 vue2 中的 mixin 有点类似,但是相对 mixins 而言, hooks 更清楚复用功能代码的来源, 更清晰易懂。

代码示例:





import {
    reactive,
    computed
} from "vue"

export function useCount() {
    const state = reactive({
        count: 0,
        doubble: computed(() => state.count * 2)
    });

    function handleClick() {
        state.count++;
    }
    return {
        state,
        handleClick
    }
}

Teleport传送门组件

可以给弹框定位到想要的位置,比如说body 或者 某个div

代码示例:



  

  

附:

vue2 和vue3的大致区别

    1.源码组织方式变化:使用 TS 重写
    2.支持 compositionAPI,基于函数的 api,更灵活组织组件逻辑(Vue2 使用 options api) 
    3.响应式系统提升:Vue3 的响应式数据原理改成了 Proxy,可以监听动态新增删除属性,以及数组变化 
    4.编译优化:Vue 通过标记静态根节点来优化 Diff,Vue 则标记和提升所有静态根节点,Diff 的时候只需要去对比动态节点的内容 
    5.打包体积优化:移除了一些不常用的 api(inline-template,filter)
    6.生命周期的变化,使用 setup 替代了 beforeCreate 和 created
    7.template 支持多个根标签
    8.Vuex 状态管理,创建实例的方式,Vue2 使用 new store;Vue3 使用 createStore;
    9.Route 获取页面实例以及路由信息,Vue2 使用 this 的方式获取;而 Vue3 采用 getCurrentInstance/userRoute,userRouter 的方式来获取
    10.对 props 的使用:Vue2 通过 this 的方式使用;Vue3 则直接通过 props 使用;

你可能感兴趣的:(vue.js,前端,javascript)