Vue脚手架

1.Vue脚手架

1.1 脚手架简介

Vue 脚手架是一个命令行工具,用于自动化生成和配置新的 Vue.js 项目的基础结构。Vue CLI(Command Line Interface)是 Vue 脚手架的官方工具,它提供了一套完整的工具来快速启动一个带有合理默认配置的 Vue.js 项目,包括构建系统(基于 webpack)、路由器、状态管理等。

创建一个 Vue 脚手架项目的步骤:

  1. 安装 Node.js

  2. 安装 Vue CLI

    • 打开命令行工具(在 Windows 上是 CMD 或 PowerShell,在 macOS 或 Linux 上是终端),然后运行以下命令来全局安装 Vue CLI:
      npm install -g @vue/cli
      
      或者,如果您使用的是 Yarn,则运行:
      yarn global add @vue/cli
      
  3. 创建新项目

    • 使用 Vue CLI 创建新项目,运行以下命令:
      vue create my-project-name
      
      其中 my-project-name 是您希望为新项目指定的名称。这个命令会启动一个交互式的界面,让您选择一些预设(如默认预设、手动选择特性等)。
  4. 进入项目目录

    • 创建项目后,进入新创建的项目目录:
      cd my-project-name
      
  5. 启动开发服务器

    • 在项目目录中,启动开发服务器:
      npm run serve
      
      或者,如果您使用 Yarn,则运行:
      yarn serve
      
      这将启动一个热重载的本地开发服务器。
  6. 访问应用

    • 打开浏览器并访问 http://localhost:8080(或者命令行提示的其他地址),您应该能看到 Vue 应用正在运行。

通过以上步骤,您就可以创建并开始开发一个新的 Vue.js 项目了。Vue CLI 还提供了许多其他的功能和配置选项,您可以通过 Vue CLI 的官方文档来了解更多高级用法。

1.2 src文件夹

在 Vue.js 的项目结构中,src 文件夹扮演着非常重要的角色。它是“source”的缩写,意味着“源代码”。这个文件夹通常包含了 Vue 应用程序的所有源代码文件,包括组件、视图、路由、服务、图片、样式等。以下是 src 文件夹中可能包含的一些子文件夹和文件的标准结构和它们的作用:

  1. assets

    • 这个文件夹通常用于存放静态资源,如样式表(CSS 或 SCSS 文件)、图片、字体等。
  2. components

    • 这里包含了 Vue 应用中的所有组件文件。每个组件通常都有一个 .vue 扩展名的单文件组件(SFC),这个文件定义了组件的模板、脚本和样式。
  3. viewspages

    • 这个文件夹包含应用程序的页面级组件。在使用 Vue Router 时,路由通常会映射到这些页面组件。
  4. router

    • 如果项目使用 Vue Router 进行页面路由,这里通常会有一个 index.js 或类似的文件,定义了所有的路由规则。
  5. store

    • 对于使用 Vuex 进行状态管理的项目,这个文件夹包含了状态管理相关的文件,如 store.js 或分模块的状态管理文件。
  6. App.vue

    • 这是根组件文件,Vue 应用的主组件,其他所有的组件都是这个组件的子组件。
  7. main.jsmain.ts

    • 这是应用程序的入口文件。它创建了 Vue 实例,并且通常用于挂载根组件、引入插件、配置全局组件等。

这个结构不是强制性的,但它是 Vue 社区中广泛采用的一种约定俗成的组织方式。开发者可以根据项目的需要对这个结构进行调整。例如,大型项目可能会有更复杂的目录结构,可能会包含更多的子目录来组织复杂的组件系统和业务逻辑。

在这里插入图片描述

2.基本使用

2.1 main.js

这是应用程序的入口文件。它创建了 Vue 实例,并且通常用于挂载根组件、引入插件、配置全局组件等。

/* 引入createApp方法 */
/* createApp:是一个工厂函数,用于创建应用的实例对象*/
import { createApp } from 'vue'
/* 引入根组件对象 */
import App from './App.vue'
/*
以根组件App对象创建一个vue实例并挂载到容器上
*/
createApp(App).mount('#app')

2.2 数据的引入与暴露

在vue脚手架中一个文件想使用另一个文件中的变量或方法,必须通过export暴露数据import引入数据才能使用其他文件中的数据!

暴露数据使用: export {变量a,变量b} 使用export {}可以一次性暴露多个数据给其他文件使用
引用数据就需要使用: import {变量a,变量b} from ‘变量所在文件的相对路径’

暴露数据使用:export default 变量a;
引用数据就需要使用:import 变量a from ‘变量文件所在的路径’
注意:
export default在一个文件中只能出现一次

总结:
  暴露引入数据的两种形式
  第一种:
    export {a,b,c}
    import {a,b,c}
  第二种形式:
    export default a
    import a 

在脚手架中使用Vue提供的函数需要通过import引入使用(如ref,reactive等)
如: import {reactive,ref} from ‘vue’

2.3 setup

setup 是 Vue.js 3 中的一个新功能,它是 Composition API 的一部分。setup 函数用于设置组件的响应式属性和逻辑。它提供了一种更灵活、可组合的方式来组织和重用组件逻辑,相比于之前的 Options API,它更容易在大型项目中进行维护和管理。

import {ref} from 'vue'
export default {
  setup(){
    var num = ref(1);
    function add(){
      num.value++;
    }
    return{
      num,
      add
    }
  }
}

在以上代码示例中,setup 函数的用途如下:

  1. 定义响应式属性:num 是一个响应式引用,其初始值为 1。ref() 函数是 Vue 提供的一个用于创建响应式引用的函数。当 num 的值发生变化时,Vue 会自动更新与其相关的 DOM 元素。

  2. 定义组件逻辑:add 函数是一个简单的方法,用于增加 num 的值。每次调用 add 函数时,num 的值都会递增。

  3. 返回对象:setup 函数返回一个包含 numadd 的对象。这使得我们可以在组件的模板中访问和使用这些响应式属性和方法。

总之,setup 函数在这个示例中的用途是定义响应式属性和组件逻辑,并将它们暴露给组件的模板。这使得我们可以轻松地在组件模板中使用和绑定这些属性和方法,从而实现响应式的用户界面。

通过 setup 定义的变量或方法默认情况下只能在当前组件的模板和逻辑中使用。但是,如果你想在其他组件中使用这些变量或方法,你可以通过以下两种方式实现:

  1. Props 和 Events: 当你想在父子组件之间共享数据或方法时,你可以使用 props 和 events。父组件可以通过 props 向子组件传递数据,而子组件可以通过触发事件(例如 $emit)将数据或方法传递回父组件。

  2. 使用 Vue.js 的 provide / inject 机制: 如果你想在组件的某个子树中共享数据或方法,可以使用 Vue.js 的 provide / inject 机制。在一个祖先组件中,你可以使用 provide 函数将变量或方法提供给其所有子孙组件。然后,在任何需要使用这些变量或方法的子孙组件中,你可以使用 inject 函数将它们注入到组件中。

以下是一个简单的 provide / inject 示例:

// 祖先组件
export default {
  setup() {
    const sharedData = ref("Hello, I'm shared data!");

    provide("sharedData", sharedData);

    return {};
  },
};
// 子孙组件
export default {
  setup() {
    const sharedData = inject("sharedData");

    return {
      sharedData,
    };
  },
};

在这个示例中,祖先组件通过 provide 函数提供了一个名为 sharedData 的响应式引用。在子孙组件中,我们使用 inject 函数将 sharedData 注入到组件中,以便在模板和逻辑中使用它。

需要注意的是,provideinject 主要用于在组件之间共享状态和逻辑,而不是用于简单的父子组件通信。在大多数情况下,使用 props 和 events 会更加简单和直观。

3.reactive响应式数组

3.1 问题引入

<template>
  <div v-for="item in data.list">
    {{item}}
  </div>
  <button @click="add">添加元素</button>
</template>
<script>
import {reactive} from 'vue'
export default {
  setup(){
    var data = reactive({
      list:[1,2,3,4]
    });
    function add(){
      data.list = [1,2,3,4,5];
    }
    return{
      data,
      add
    }
  }
}
</script>

在以上代码中定义了一个响应式数组,我们希望当按下添加元素的按钮时,页面上的list显示的数据会增加一个5,但发现按下按钮后,页面不发生变化,这就导致了数据失去响应式的问题.

3.1 原因及解决方法

原因: 用reactive定义的数据是响应式的,此时list是响应式的,在add方法中list=[1,2,3,4,5],将list指向普通数组,list失去了响应式, 因此list中数据变化,页面不会变化.

**解决方法:**修改数组的时候使用数组提供的方法去修改,不要直接修改数组变量的地址!

   function add(){
      //修改数组的时候使用数组提供的方法去修改
      //不要直接修改数组变量的地址!!
      list.push(5);
    }

4.组件的使用

4.1 组件简介

组件的作用:

​ 组件可以理解成页面的某一个片段,使用组件可以将html,css,js封装到一起变为一个页面片段,我们需要使用这个页面片段的时候,可以通过组件名直接调用,使用组件的好处是可以封装页面,可以提高页面的复用性,可以精简代码!

如:先定义了一个mynav.vue组件,我们将在App.vue中调用它

<template>
  <div class="bg">
    <img src="../assets/back.png" />
    <div class="nav">
      <div>首页</div>
    </div>
  </div>
</template>
<script>
export default {
  
}
</script>

我们将在App.vue中调用它

<template>
  <div>
    <mynav></mynav>//引入了mynav组件
  </div>
</template>

<script>
/* 引入mynav组件 */
import mynav from "./components/mynav.vue";
export default {
  /*
  使用组件都需要在components对象里面注册,
  注册过的组件才能在template模板页面里面使用 
  */
  components: {
    mynav,
  },
};
</script>

4.2 父组件传值给子组件

父传子步骤

1. 在子组件的props中定义父组件要传给子组件的属性
2. 在子组件的开始标签上使用props定义的属性,将父组件的值传给子组件

案例演示:

先定义一个子组件mc

<template>
  <div class="mc">
    mc组件
    <div>
      count:{{count}}
    </div>
  </div>
</template>

<script>
export default {
  /*
  properties:
    property属性的意思 
    props是properties的简写,props主要用来定义
    父组件要传给子组件的属性!
  */
  props:{
    /* 
    count是父组件给子组件传递的属性名
    */
    count:{
      //数据类型
      type:Number,
      /*
      默认值:
        当父组件没有使用这个属性传值给子组件,
        那么这个属性就会取默认值!!! 
      */
      default:0
    }
  },
  setup(){
    return{
      
    }
  }
}
</script>

在父组件中对子组件进行传值

<template>
  <div>
    <!-- 
      在子组件的标签上通过props中定义的属性,
      将父组件中的数据传给子组件使用!!!
    -->
    <mc count="55"></mc>
    <mc :count="data.num"></mc>
  </div>
</template>

<script>
import {reactive} from 'vue'
import mc from './components/mc'
export default {
  components:{
    mc
  },
  setup(){
    let data = reactive({
      num:99
    });
    return{
      data
    }
  }
}
</script>

4.3 子组件传值给父组件

子传父步骤

  1. 在子组件的标签上使用v-on监听一个自定义的事件,并绑定

    一个回调函数,当这个自定义的事件被子组件中的emit方法

    触发时,回调函数就会执行,回调函数的参数就是emit传递

    过来的数据

  2. 在子组件中通过context.emit(‘自定义事件名’,数据)触发

    自定义事件并传数据

先定义一个子组件,我们希望当按下子传父按钮时,会将子组件里的数据传到父组件中

<template>
  <div class="mc">
    mc组件
    <button @click="foo">子传父</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  setup(props,context){
    function foo(){
      /*
      emit方法可以用来触发自定义的事件,他有两个参数:
        第一个参数:自定义的事件名
        第二个参数:子组件要传给父组件的数据 
      */
      context.emit('send',888);
    }
    return{
      foo
    }
  }
}
</script>

在父组件中接收到数据:

<template>
  <div>
    <mc @send="callback" ></mc>
  </div>
</template>

<script>
import {reactive} from 'vue'
import mc from './components/mc'
export default {
  components:{
    mc
  },
  setup(){
    function callback(params){
      console.log('父组件拿到了子组件传递过来的参数:',params);
      console.log('callback执行了');
    }
    return{
      callback
    }
  }
}
</script>

4.4 祖孙传值

祖先组件给后代组件传值步骤:

1. 先在祖先组件中通过provide('数据名',数据)暴露数据给后代
2. 在后代组件中通过inject('数据名')获取祖先组件传递过来的数据使用

案例演示:

先定义一个父组件,使用provide方法暴露数据给后代使用, 所有的后代都能通过inject方法拿到数据

<template>
  <div class="app">
   <h3>祖先组件</h3>
   <button @click="modi">修改水果</button>
   <div>food:{{data.food}}</div>
   <son></son>
  </div>
</template>

<script>
import son from './components/son'
/*
注意:
  在vue3中几乎所有vue给我们提供的方法都需要去
  vue中import引入使用 
*/
import {reactive,provide} from 'vue'
export default {
  components:{
     son
  },
  setup(){
    let data = reactive({
      food:'苹果'
    });
    /*
    使用provide方法暴露数据给后代使用,
    所有的后代都能通过inject方法拿到数据 
    */
    provide('data',data);
    function modi(){
      data.food = '火龙果';
    }
    return {
      data,
      modi
    }
  }
}
</script>

<style scoped>
/*
scoped属性是css作用域,他的作用是让style标签里面的
样式只对当前组件生效
*/
.app{
  border: 1px solid skyblue;
  padding: 10px;
  margin: 10px;
}
</style>

定义一个儿子组件,并且将在其中引用孙子组件grandson

<template>
  <div class="son">
    <h3>儿子组件</h3>
    <button @click="modi">修改水果</button>
    <div>
      food:{{data.food}}
    </div>
    <grandson></grandson>
  </div>
</template>

<script>
import {inject} from 'vue'
import grandson from './grandson'
export default {
  components:{
    grandson
  },

  setup(){
    /*
    注意:
      inject的参数是一个字符串,它表示要引入的
      祖先组件中provide暴露的数据的名字 
    */
    let data = inject('data');
    function modi(){
      data.food='猕猴桃';
    }
    return {
      data,
      modi
    }
  }
}
</script>

定义一个孙子组件

<template>
  <div class="grandson">
    <h3>孙子组件</h3>
    <div>
      food:{{data.food}}
    </div>
  </div>
</template>
<script>
import {inject} from 'vue'
export default {
  setup(){
    let data = inject('data');
    return{
      data
    }
  }
}
</script>

5 .创建全局共享数据文件

任意组件之间的数据共享实现步骤

  1. 创建一个js文件,在js中文件中使用reactive创建一个全局共享的数据对象
  2. 其他任何组件之间需要共享数据时都可以引入第一步中js文件里面定义的reactive数据对象

案例演示:

定义一个名为globaldata的js文件

import {reactive} from 'vue'
/* 定义全局共享的数据data */
var data = reactive({
  score:60
});
/* 暴露数据 */
export {
  data
}

定义学生student组件和老师teacher组件,在里面调用全局变量,并在老师组件中修改该变量值,修改后的变量值也会在学生组件中更新.

老师组件:

<template>
  <div class="box">
    <h3>老师组件</h3>
    <button @click='modi'>修改学生分数</button>
    <div>分数:{{data.score}}</div>
  </div>
</template>
<script>
import {data} from '../utils/globaldata.js'
export default {
  setup(){
    function modi(){
      data.score++;
    }
    return{
      data,
      modi
    }
  }
}
</script>

学生组件:

<template>
  <div class="box">
    <h3>学生组件</h3>
    <div>
      分数:{{data.score}}
    </div>
  </div>
</template>
<script>
import {data} from '../utils/globaldata.js'
export default {
  setup(){
    return{
      data
    }
  }
}
</script>

最后将student和teacher组件都引入到App.vue文件中

<template>
  <div>
    <teacher></teacher>
    <student></student>
  </div>
</template>

<script>
import teacher from './components/teacher'
import student from './components/student'
export default {
  components:{
    student,
    teacher
  }
}
</script>

6.生命周期钩子函数

6.1 vue 2

在 Vue.js 中,生命周期钩子函数是一系列在组件各个阶段自动被调用的函数。它们为开发者提供了在不同阶段管理组件的机会,如创建前后、插入 DOM 前后、更新前后、以及销毁前后等。

下面是一些 Vue 实例的生命周期钩子:(Vue 2)

  1. beforeCreate: 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

  2. created: 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前尚不可用。

  3. beforeMount: 在挂载开始之前被调用:相关的 render 函数首次被调用。

  4. mounted: el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果根实例挂载了一个文档内元素,当 mounted 被调用时,组件已经在文档内。

  5. beforeUpdate: 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。可以在这个钩子中进一步地更改状态,这不会触发额外的重渲染过程。

  6. updated: 由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后会调用这个钩子。当这个钩子被调用时,组件 DOM 已经更新,所以现在可以执行依赖于 DOM 的操作。

  7. beforeDestroy: 实例销毁之前调用。在这一步,实例仍然完全可用。

  8. destroyed: Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

这些钩子给予了开发者控制组件行为的能力,尤其是执行非响应性的操作,或是与外部资源进行交互。例如,你可能会在 created 钩子中进行 AJAX 请求获取数据,在 mounted 钩子中访问操作 DOM,在 beforeDestroy 钩子中执行清理操作,如清除定时器或解除事件监听器。

6.2 vue 3

Vue 3 中,生命周期钩子函数与 Vue 2 中的概念相同,但是它们是作为函数导入并在 setup 函数中使用。这是 Composition API 的一部分,它允许开发者在一个地方组合和重用逻辑。

这里是 Vue 3 的主要生命周期钩子函数:

  1. onBeforeMount: 在挂载(mounting)过程开始之前调用。

  2. onMounted: 在组件挂载到 DOM 上后调用。

  3. onBeforeUpdate: 在响应式依赖项发生变化,且组件重新渲染之前调用。

  4. onUpdated: 在组件重新渲染并且 DOM 更新后调用。

  5. onBeforeUnmount: 在卸载(unmounting)过程开始之前调用。

  6. onUnmounted: 在组件卸载后调用。

在使用 Composition API 时,我们通常在 setup 函数中按需导入和使用这些钩子。例如:

import { onMounted, onBeforeUnmount } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('组件已挂载');
    });

    onBeforeUnmount(() => {
      console.log('组件将要卸载');
    });

    // ... setup 中的其他逻辑
  }
}

在这种模式下,setup 函数是一个新的组件选项。它在组件创建之前执行,一次性地执行所有响应性的定义,事件处理函数的设置等等。你可以认为它是组件的“启动”函数,取代了 datacomputedmethodswatch 等传统的 API。

此外,Vue 3 还提供了其他几个生命周期钩子函数,用于服务器端渲染(SSR)和调试:

  • onRenderTracked: 当一个响应式依赖被追踪时调用。
  • onRenderTriggered: 当一个响应式依赖被触发(即:它的值被改变了)时调用。
  • onActivated: 用于 <keep-alive> 包裹的组件,当组件被激活时调用。
  • onDeactivated: 用于 <keep-alive> 包裹的组件,当组件被停用时调用。

这些额外的钩子函数使得开发者能够更细粒度地控制组件的行为,并在调试时获得更多信息。

7.toRefs 将对象属性变为响应式

7.1toRefs的作用:

​ toRefs方法会将传入的对象上的所有属性变为响应式的属性! 使用toRefs结合扩展运算符…暴露数据给模板template使用,可以简化代码,不需要再通过对象.属性名 在模板中显示数据了,直接通过属性名就可以在模板中使用显示了!

案例如下:

<template>
  <div>
    name:{{name}}
  </div>
  <div>
    age:{{age}}
  </div>
  <button @click="modi">修改年龄</button>
</template>

<script>
import { reactive,toRefs } from "vue";
export default {
  setup() {
    let person = reactive({
      name: "刘备",
      age: 18,
    });
    function modi(){
      person.age++;
    }
    return {
      ...toRefs(person),//toRefs结合扩展运算符,将person对象上的属性都变成了响应式
      modi
    };
  },
};
</script>

7.2 toRefs和toRef的区别:

在 Vue 3 的 Composition API 中,toRefstoRef 都是用来处理响应式数据的函数,但它们用于不同的场景。

toRefs

当你想要将一个响应式对象的所有属性转换为响应式引用(refs)时,你会使用 toRefs。这在你需要将这些属性作为独立的响应式值传递给其他地方时非常有用,同时保持它们与原始响应式对象的连接。使用 toRefs,你可以保证即使属性被解构和传递到组件或函数外部,它们仍然是响应式的。

import { reactive, toRefs } from 'vue';

const state = reactive({
  count: 0,
  title: 'Hello'
});

const stateRefs = toRefs(state);
// stateRefs.count 和 stateRefs.title 现在都是响应式的 refs

toRef

toRef 用于为响应式对象的某个属性创建一个 ref。这在你只需要从响应式对象中提取一个属性并保持其响应性时非常有用。与 toRefs 不同,toRef 不会处理整个对象,而是专注于单个属性。

import { reactive, toRef } from 'vue';

const state = reactive({
  count: 0,
  title: 'Hello'
});

const countRef = toRef(state, 'count');
// countRef 是一个响应式的 ref,它与 state.count 保持同步

使用 toRef,你可以将响应式对象的某个属性作为一个响应式引用传递到其他地方,而不需要传递整个对象。

关键区别

  • 使用 toRefs 时,你可以将一个响应式对象转换为一个包含多个属性的普通对象,这些属性都是独立的响应式 refs。
  • 使用 toRef 时,你只处理响应式对象的一个属性,将其转换为单个的响应式 ref。

在实际应用中,选择 toRefs 还是 toRef 取决于你的具体需求:是否需要处理整个对象的所有属性,还是只关注单个属性。

8.使用ref获取dom对象

在vue中可以使用ref方法获取dom对象,方法如下:

使用ref方法定义一个变量,将这个定义的变量和标签的ref属性进行绑定,我们通过 变量名.value 就可以获取到绑定的标签对象了!

<template>
  <!-- 使用ref属性绑定一个变量 -->
  <div ref="myref" id="box">hello</div>
  <button @click="foo">获取dom</button>
</template>

<script>
import {onMounted,ref} from 'vue'
export default {
  setup() {
    var myref = ref();
    function foo() {
      //获取真实的dom元素
      console.log('myref',myref.value)
    }
    onMounted(()=>{
      //在onMounted里面才能获取到dom标签对象
      var dom = document.getElementById("box");
      console.log("dom", dom);
    });
    return {
      foo,
      myref
    };
  },
};
</script>

9.路由的使用

9.1 基本概念

在 Vue.js 中,路由(Routing)和路由器(Router)是用于构建单页面应用(SPA)的关键概念。

  1. 路由(Routing):路由是一种映射关系,将 URL 与应用中的特定组件关联起来。当用户在浏览器中访问不同的 URL 时,路由会根据 URL 的变化动态地加载和渲染相应的组件,而不需要重新加载整个页面。这种方式可以提高应用程序的性能,同时提供更好的用户体验。

  2. 路由器(Router):路由器是一个负责管理路由的对象。在 Vue.js 中,Vue Router 是官方的路由管理器。它允许你定义路由规则、导航守卫、嵌套路由等高级功能,以便在 Vue 应用程序中实现复杂的导航逻辑。Vue Router 使用一个名为 router 的实例来管理这些功能。

9.2 路由使用步骤

  1. 引入路由 npm i vue-router@4 注意:vue3使用的是4.x版本的路由,所以引入时要加入版本号@4,如果不加版本号引入的是3.x版本的路由,会导致vue3使用不了报错!

  2. 创建router.js文件,创建路由配置:定义一个包含路由规则的数组。每个路由规则都是一个对象,包含 path(URL 路径)、name(路由名称,可选)和 component(与该路径关联的 Vue 组件)属性。

    import {createRouter,createWebHashHistory} from 'vue-router'
    import login from './components/login.vue'
    export default createRouter({
        /* 
        createWebHashHistory:hash模式,
        createWebHistory:history模式
        */
        history:createWebHashHistory(),
        routes:[
            {
                path:'/',
                name:'main',
                component:()=>import('./components/main.vue'),
            },
            {
                path:'/login',
                name:'login',
                //组件也可以在最上面用import引入
                component:login
            },
            {
                path:'/register',
                name:'register',
                component:()=>import('./components/register.vue'),
            }
        ]
    })
    
    1. 在main.js中注册路由,将路由器实例挂载到 Vue 应用程序中.
       import {createApp} from 'vue'
       import App from './App.vue'
       import router from './router'
       const app = createApp(App)
       //注册路由到app上
       //注意: 这里需要把use放到mount前面否则会失败,因为插件要先使用才会生效
       app.use(router);
       app.mount("#app");
    
    1. 在App.vue中放置好路由占位组件<router-view></router-view>在应用程序的模板中显示当前路由对应的组件.

9.3 路由重定向

路由重定向是一种在 Vue.js 应用程序中自动将用户从一个路由导航到另一个路由的技术。当用户访问某个特定的 URL 时,路由重定向可以将用户引导到一个不同的 URL。这在以下场景中非常有用:

  1. 当用户访问一个已经被废弃的 URL 时,将用户重定向到新的 URL。
  2. 当用户访问一个需要权限才能访问的 URL 时,如果用户未登录或没有权限,将用户重定向到登录页面或者错误页面。
  3. 当用户访问一个不存在的 URL 时,将用户重定向到一个 404 错误页面。

在 Vue Router 中,可以通过在路由配置中使用 redirect 属性来实现重定向。

例如,假设你想要将用户从 /old-path 重定向到 /new-path,你可以在路由配置中添加以下规则:

const routes = [
  {
    path: '/old-path',
    redirect: '/new-path'
  },
  // ...其他路由规则
]

当用户访问 /old-path 时,浏览器的 URL 会自动更新为 /new-path,并加载与 /new-path 对应的组件。

你还可以使用一个函数作为 redirect 的值,以便在重定向时执行更复杂的逻辑。这个函数接收一个包含路由信息的对象作为参数,返回一个字符串(新的 URL)或一个包含新路由信息的对象。

例如,根据用户访问的 URL 中的参数来决定重定向的目标:

const routes = [
  {
    path: '/redirect/:type',
    redirect: (to) => {
      const { type } = to.params;
      if (type === 'admin') {
        return '/admin-dashboard';
      } else {
        return '/user-dashboard';
      }
    }
  },
  // ...其他路由规则
]

在这个例子中,当用户访问 /redirect/admin 时,将重定向到 /admin-dashboard;当用户访问 /redirect/user 时,将重定向到 /user-dashboard

9.4 页面跳转与传参

9.4.1 Vue Router常用方法

Vue Router 提供了一系列方法来实现导航和路由管理。以下是 Vue Router 中一些常用的方法:

  1. push(location, onComplete?, onAbort?):导航到一个新的 URL。location 参数可以是一个字符串或一个描述目标路由的对象。当导航完成时,可选的 onComplete 回调函数会被调用;当导航被取消时,可选的 onAbort 回调函数会被调用。例如:
// 使用字符串
router.push('/about')

// 使用对象
router.push({ path: '/about' })

// 使用命名路由和参数
router.push({ name: 'about', params: { userId: 123 } })

// 使用查询参数
router.push({ path: '/about', query: { page: 2 } })
  1. replace(location, onComplete?, onAbort?):与 push() 类似,但不会向历史记录中添加新的记录。相反,它会替换当前的历史记录。这在某些情况下很有用,例如在登录页面跳转到主页时,你可能不希望用户能通过后退按钮回到登录页面。
router.replace('/home')
  1. go(n):在浏览器历史记录中前进或后退指定的步数。n 是一个整数,正数表示前进,负数表示后退。
// 后退一步
router.go(-1)

// 前进一步
router.go(1)

// 前进两步
router.go(2)
  1. back():后退一步,相当于 router.go(-1)
router.back()
  1. forward():前进一步,相当于 router.go(1)
router.forward()
  1. resolve(location, current?, append?):解析目标位置,返回一个包含完整 URL 信息的对象。这个方法不会触发导航,但可以用来预先计算导航的结果。
const resolvedLocation = router.resolve({ path: '/about' })
console.log(resolvedLocation)

除了这些方法,Vue Router 还提供了一些其他高级功能,例如导航守卫、路由元信息、嵌套路由等。你可以查阅 Vue Router 文档 以了解更多关于 Vue Router 的信息。

9.4.2 useRouter

在 Vue 3 中,useRouter 是一个 Composition API 函数,它允许你在组件中访问当前的路由器实例。使用 useRouter,你可以在组件内执行页面跳转或访问其他路由相关的功能。

要使用 useRouter,请按照以下步骤操作:

  1. 在组件的 setup() 函数中导入 useRouter
  2. 调用 useRouter() 以获取当前的路由器实例。
  3. 使用路由器实例的 push() 方法进行页面跳转。

以下是一个简单的示例,展示了如何在 Vue 3 中使用 useRouter 进行页面跳转:

<template>
  <button @click="navigateToAbout">Go to About</button>
</template>

<script>
import { useRouter } from 'vue-router'

export default {
  setup() {
    const router = useRouter()

    const navigateToAbout = () => {
      router.push('/about')
    }

    return {
      navigateToAbout
    }
  }
}
</script>

在这个例子中,当用户点击 “Go to About” 按钮时,navigateToAbout 函数会被调用。这个函数使用 router.push() 方法将用户导航到 /about 路径对应的页面。

9.4.3 useRoute

useRoute 是 Vue Router 4(适用于 Vue 3)中的一个 Composition API 函数,它允许你在组件内访问当前激活的路由信息。使用 useRoute,你可以获取当前路由的参数、查询参数、元信息等。

要使用 useRoute,请按照以下步骤操作:

  1. 在组件的 setup() 函数中导入 useRoute
  2. 调用 useRoute() 以获取当前激活的路由对象。

以下是一个简单的示例,展示了如何在 Vue 3 中使用 useRoute 获取当前路由的参数和查询参数:

<template>
  <div>
    <p>User ID: {{ userId }}</p>
    <p>Page: {{ page }}</p>
  </div>
</template>

<script>
import { useRoute } from 'vue-router'

export default {
  setup() {
    const route = useRoute()

    // 获取路由参数和查询参数
    const userId = route.params.userId
    const page = route.query.page

    return {
      userId,
      page,
    }
  },
}
</script>

在这个例子中,userIdpage 分别从当前路由的参数和查询参数中获取。当路由发生变化时,这些值会自动更新。

9.4.4 useRouter与useRoute的区别

useRouteruseRoute 都是 Vue Router 4(适用于 Vue 3)中的 Composition API 函数,它们在组件中分别提供对路由器实例和当前激活的路由对象的访问。

  1. useRouter:它返回当前的路由器实例,允许你在组件内执行导航操作(如页面跳转)和访问其他路由器相关的方法和属性。使用 useRouter,你可以调用 pushreplacego 等方法来控制应用程序的导航。
import { useRouter } from 'vue-router'
export default {
  setup() {
    const router = useRouter()
    const navigateToAbout = () => {
      router.push('/about')
    }

    return {
      navigateToAbout
    }
  }
}
  1. useRoute:它返回当前激活的路由对象,允许你在组件内访问路由信息,如路由参数、查询参数、元信息等。使用 useRoute,你可以根据当前路由的状态来改变组件的显示内容或行为。
import { useRoute } from 'vue-router'

export default {
  setup() {
    const route = useRoute()

    const userId = route.params.userId
    const page = route.query.page

    return {
      userId,
      page,
    }
  },
}

总结:useRouter 主要用于执行导航操作和访问路由器相关的方法,而 useRoute 主要用于访问当前激活路由的信息。在实际应用中,根据需要选择使用它们。

9.4.5 页面跳转与传参案例

1.使用router.push()进行页面跳转并传递参数。在目标组件中,使用 useRoute 获取传递的参数。

页面跳转与传参

import {useRouter} from 'vue-router'
export default {
  setup(){
    let router = useRouter();
    function gologin(){
      router.push({
        //导航到下一个页面
        path:'/login',
        /*
        query属性可以将当前页面的数据传到下一个页面 
        */
        query:{
          name:'刘备',
          age:18
        }
      });
    };
    return{
      gologin,
    }
  }
}

获取参数

export default {
  setup(){
   /*
   useRoute方法会返回一个route对象,route对象
   上有一个属性query,这个query属性的值就是上一个
   页面传过来的数据!
   */
   let route = useRoute();
   let data = reactive({
    query:{}
   });
   data.query = route.query;
   return{
    ...toRefs(data)
   }
  }
}

2.router-link方法: 除了使用 router.push() 进行编程式导航外,你还可以使用 <router-link> 组件实现声明式导航。通过设置 to 属性,你可以定义目标 URL 和参数。

<!-- 使用路由参数 -->
<router-link :to="{ name: 'User', params: { id: 123 } }">User 123</router-link>

<!-- 使用查询参数 -->
<router-link :to="{ path: '/search', query: { keyword: 'Vue.js' } }">Search Vue.js</router-link>

9.5 嵌套路由

嵌套路由(Nested Routes)是 Vue Router 中的一个功能,允许你在一个组件内部渲染其他组件。这在构建具有多层次结构的应用程序时非常有用,例如侧边栏导航、子页面等。

要实现嵌套路由,请按照以下步骤操作:

  1. 在路由配置中,为父路由添加 children 属性,该属性包含一个子路由数组。
  2. 在父组件的模板中添加 <router-view> 组件。当子路由被激活时,与子路由关联的组件将在父组件的 <router-view> 中渲染。

以下是一个简单的嵌套路由示例:

首先,创建父组件和子组件:

<!-- ParentComponent.vue -->
<template>
  <div>
    <h1>Parent Component</h1>
    <router-view></router-view>
  </div>
</template>
<!-- ChildComponent.vue -->
<template>
  <div>
    <h2>Child Component</h2>
  </div>
</template>

接下来,配置嵌套路由:

import ParentComponent from '@/components/ParentComponent.vue'
import ChildComponent from '@/components/ChildComponent.vue'

const routes = [
  {
    path: '/parent',
    component: ParentComponent,
    children: [
      {
        path: 'child',
        component: ChildComponent
      }
    ]
  }
]

在这个示例中,当访问 /parent/child 时,ChildComponent 将在 ParentComponent<router-view> 中渲染。

你可以根据需要添加更多子路由,甚至可以在子路由中继续嵌套子路由,以构建复杂的多层次结构。

10.axios库请求

10.1 axios简介

  • axios: 这是一个基于 Promise 的 HTTP 客户端,用于在浏览器和 node.js 环境中发送各种 HTTP 请求。它是一个流行的库,因为它简化了原生 JavaScript XMLHttpRequestfetch API 的复杂性。它提供了简洁的 API 来发送 HTTP 请求,包括 GET、POST 等方法。在 Vue.js 应用程序中,Axios 常用于与后端 API 进行通信。

10.2 get请求无参

<template>
  <div>
    随机文本:{{data.msg}}
  </div>
</template>

<script>
/*
引入axios库 
*/
import axios from 'axios'
import {onMounted,reactive} from 'vue'
export default {
  setup(){
    let data = reactive({
      msg:''
    });
    /*
    数据请求一般写在onMounted这个生命周期函数里面,当组件已经被插入到 DOM 中后,这个钩子中的代码将会执行。
    */
    onMounted(()=>{
      /* 获取随机文本接口 */
      axios.get("http://127.0.0.1:3000/text").then(res=>{
        /*
        res对象里面有什么数据,以及结构是什么样子的都是不确定的,因此每次使用axios发请求,都需要将获取到的res对象使用console.log打印出来,打印出来之后你就可以从里面找你需要的属性和数据了!   */
        data.msg = res.data;
      });
    });
    return{
      data
    }
  }
}
</script>

以上代码是使用 axios 这个 JavaScript 库来发起一个 HTTP GET 请求的。下面是对代码的详细解释:

  • axios: 这是一个基于 Promise 的 HTTP 客户端,用于在浏览器和 node.js 环境中发送各种 HTTP 请求。它是一个流行的库,因为它简化了原生 JavaScript XMLHttpRequestfetch API 的复杂性。

  • .get("http://127.0.0.1:3000/list"): 这是 axios 的一个方法,用于发起一个 GET 请求。.get 方法接受至少一个参数,即请求的 URL。在这个例子中,URL 是 "http://127.0.0.1:3000/list"。这个 URL 指向本地服务器(127.0.0.1 是本地回环地址,也就是指向你自己的计算机),3000 是服务器监听的端口号,/list 是服务器上的一个路由或资源路径。

  • then(res=>{...}): .get 方法返回一个 Promise 对象。Promise 是异步编程的一种模式,它代表了一个可能现在、也可能将来才会完成的操作的结果。.then 方法是用来指定 Promise 完成后的回调函数的。在这个回调函数中,你可以处理请求的结果。

  • res=>{...}: 这是一个箭头函数,它是 .then 方法的参数。当 GET 请求成功完成时,这个函数会被调用。res 是一个包含了响应信息的对象。这个对象通常包含了如下属性:

    • data: 服务器返回的数据。
    • status: HTTP 状态码,比如 200 表示成功。
    • statusText: HTTP 状态信息,如 “OK”。
    • headers: 响应头信息。
    • config: 请求的配置信息,包括请求的 URL、HTTP 方法等。
    • request: 请求的原始 XMLHttpRequest 对象(在浏览器中)。

在这个箭头函数内部,你可以执行任何你需要的操作来处理响应。例如,你可以将响应数据赋值给某个变量,或者更新应用的状态,或者将数据渲染到页面上。

在实际应用中,你还应该考虑处理可能发生的错误情况。这通常是通过在 .then 后面链式调用 .catch 方法来实现的,.catch 方法同样接受一个函数,用于处理 Promise 被拒绝的情况,即请求失败的情况。

10.3 get请求传参

对于 GET 请求,参数通常通过 URL 查询字符串传递.get方法的第二个参数是一个对象,这个对象有个属性params,params的值也是一个对象,我们可以将接口需要的参数作为params对象的属性传递给后端!

<script>
import axios from 'axios'
import {reactive} from 'vue'
export default {
  setup(){
    let data = reactive({
      age:'',
      year:''
    });
    function calc(){
      /*
      get请求传参:
        get方法的第二个参数是一个对象,
        这个对象有个属性params,params的值也是
        一个对象,我们可以将接口需要的参数作为params
        对象的属性传递给后端!!!
      */
      axios.get('http://127.0.0.1:3000/calcage',{
        params:{
          birth:data.year
        }
      }).then(res=>{
        console.log('res',res);
        data.age = res.data;
      })
    }
    return{
      data,
      calc
    }
  }
}
</script>

10.4 post请求传参

对于 POST 请求,参数通常通过请求体(request body)传递。使用 Axios 发送 POST 请求时,你可以将参数作为第二个参数传递给 axios.post()

import axios from 'axios'
const data = {
  username: 'user',
  password: 'password'
}

axios.post('https://api.example.com/login', data)
.then(response => {
  console.log(response.data)
})
.catch(error => {
  console.error(error)
})

在这个示例中,data 对象作为请求体发送到后端 API。请求体将包含 JSON 格式的参数数据。

10.5 get和post请求的区别

GET 和 POST 请求是两种常见的 HTTP 请求方法,它们在发送数据和用途上有一些区别:

  1. 数据传递方式:

    • GET 请求:参数通过 URL 查询字符串传递,通常用于请求数据。查询字符串以问号(?)开头,参数之间用 & 分隔。例如:https://api.example.com/data?query=Vue.js&page=1
    • POST 请求:参数通过请求体(request body)传递,通常用于提交数据。请求体可以包含各种数据格式,如 JSON、表单数据等。
  2. 安全性:

    • GET 请求:因为参数直接附加在 URL 上,它们可能会泄露到浏览器历史记录、服务器日志等地方。因此,不适合传递敏感信息,如密码、API 密钥等。
    • POST 请求:参数在请求体中传递,相对更安全。当需要传递敏感信息时,应使用 POST 请求。
  3. 缓存和幂等性:

    • GET 请求:通常用于获取数据,具有幂等性,即多次执行相同的 GET 请求,结果应该是一致的。浏览器可能会缓存 GET 请求的响应。
    • POST 请求:通常用于提交数据,可能会改变服务器上的数据状态,因此不具有幂等性。浏览器通常不会缓存 POST 请求的响应。
  4. 数据大小限制:

    • GET 请求:由于参数在 URL 中传递,它们受到 URL 长度的限制。不同浏览器和服务器对 URL 长度的限制可能有所不同,但通常限制在 2000-8000 个字符之间。
    • POST 请求:参数在请求体中传递,因此可以传输较大的数据。数据大小限制取决于服务器和客户端的配置。

在使用 Axios 发送请求时,GET 和 POST 请求的主要区别在于参数传递的方式。对于 GET 请求,使用 params 属性将参数传递给请求配置对象;而对于 POST 请求,将参数作为第二个参数传递给 axios.post()

11.element-plus

Element Plus 是一个基于 Vue 3 的高质量 UI 组件库。它为 Vue.js 开发者提供了一套丰富的组件,包括布局、表单、导航、数据展示等多种类型。Element Plus 的设计和实现遵循了一致的设计原则和风格,使得开发者能够快速构建美观且易用的 Web 应用程序。

以下是如何在 Vue 3 项目中安装和使用 Element Plus:

安装

首先,确保你已经创建了一个 Vue 3 项目。然后,通过 npm 或 yarn 安装 Element Plus:

npm install element-plus --save
# 或者
yarn add element-plus

引入

在项目的入口文件(通常是 main.jsmain.ts)中引入 Element Plus 并将其注册为全局插件:

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

这样,Element Plus 的所有组件和样式都会被引入到项目中。

使用组件

现在,你可以在 Vue 组件中直接使用 Element Plus 提供的 UI 组件。例如,创建一个带有按钮和对话框的简单页面:

<template>
  <div>
    <el-button type="primary" @click="dialogVisible = true">打开对话框</el-button>
    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" @close="dialogVisible = false">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false
    }
  }
}
</script>

在这个例子中,我们使用了 Element Plus 的 <el-button><el-dialog> 组件。点击按钮时,对话框会显示出来。
你可以在Element Plus 官方文档 中查找更多组件和使用方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值