Vue从入门到精通(第三方插件使用+Axios封装+Vuex状态管理+Vue3新特性)

文章目录


一、Vue 是什么,为什么要学习他

在这里插入图片描述

我们要学习他的原因其实有很多点,必须说简单易学,学习成本低,应用场景多,很多项目也都是用Vue来实现的。Vue社区也比较繁荣,所以Vue的选择应该是前端人员选择学习最优先的,最重要的原因就是–企业要用它!!!
vue是什么
Vue是前端优秀框架(MVVM),是一套用于用于构建用于页面的渐进式框架
为什么要学习Vue

  1. Vue是目前前端最火的框架之一
  2. Vue是目前企业技术栈中要求的知识点
  3. Vue 可以提升开发体验
  4. Vue学习难度较低

二、Vue开发前的准备

vue2官网
vue3官网

安装Vue工具Vue CLI

vue cli官网
Vue CLI 是Vue开发的标准工具,Vue CLI是一个基于Vue。js进行快速开发的完整系统。可以一键创建vue的开发环境
在官网进入cli=>生态系统=>官方项目下面=>vue cli
安装

npm install -g @vue/cli

安装之后,你就可以在命令行中访问vue命令。你可以通过简单运行vue,看看是否展示出了一份所有可用命令的帮助信息,来验证他是否安装成功

vue --version
创建一个项目

运行以下命令来创建一个新项目

vue create vue-demo
注意创建项目名字不能存在大写,可以用-连接多个单词

温馨提示:

  1. 在控制台中,可以用上下按键调整选择项
  2. 在控制台中,可以用空格(spacebar)选择是否选中和取消选中

可以选择默认项目模板,或者选"手动选择特性"来选择需要的特性。
在这里插入图片描述
我们选择Babel和Peogressive Web App(PWA) Support俩个选项即可

温馨提示:
在学习期间,不要选中Linter/Fomatter,以避免不必要的错误提示

在这里插入图片描述

vue目前有俩大主流大版本vue2和vue3,我选择vue3最新版本
在这里插入图片描述
配置放在哪里? In dedicated config files专用配置文件或者Inpackage.json在package.json文件

在这里插入图片描述
将其桃村为未来项目的预置?y代表保存,并添加名字,n不保存
选n即可,因为日后这个选项会改了,会增加更多内容
在这里插入图片描述
项目创建成功如下提示信息在这里插入图片描述
运行项目
第一步: 进入项目根目录 cd 项目文件夹名称=>我这里是

cd vue-demo

第二步:运行 npm run serve 启动项目

npm run serve 

运行成功,在游览器属于地址启动项目
在这里插入图片描述
在这里插入图片描述
项目文件目录
在这里插入图片描述
文件目录介绍

  • assets => 静态资源文件夹
  • components => 公共组件
  • App.vue => 根组件
  • main.js => 主入口文件

清理HelloWolrd组件文件
清理成以下例子即可
在这里插入图片描述

  • template => 用来写结构HTML代码的
  • script => 用来写业务逻辑JS代码的
  • style => 用来写样式css代码的
    安装Vue高亮插件
    VSCode安装vetur或者volar都可,前者针对vue2版本,后者针对vue3版本

三、Vue模板语法

vue官网模板语法
数据绑定最常见的形式就是使用"Mustache"(双大括号)语法的文本插值

<span>Message: {{ msg }}</span>

一般配合js中 data()设置数据

export default {
  name: 'HelloWorld',
  data(){
    return{
      message:'demo'
    }
  }
}

例子
在这里插入图片描述

原始HTML

双大括号会将数据解释为普通文本,而非HTML代码。为了输出真正的HTML,你需要使用v-html指令

    <div>{{ rawHtml }}</div>
    <div v-html="rawHtml"></div>
data(){
    return{
      rawHtml:"<a href='http://www.baidu.com'>百度</a>"
    }
  }

例子
在这里插入图片描述

属性Atribute

Mustache 语法不能在HTML属性中使用,然而人,可以使用v-bind指令

 <div v-bind:id="cId">bind</div>
  <div :id="cId">bind</div>
  data(){
    return{
      cId:1001
    }
  }

例子
在这里插入图片描述

温馨提示:
v-bind 可以简写成 :

使用JavaScript表达式

在我们的模块中,我们一直都只绑定简单的propetry键值,vue.js都提供了完全的JavaScript表达式支持

{{number+1}}
{{ok?'yes':''no}}
{{}message.split('').reverse().join('')}

这些表达式会在当前活动实例的数据作用域下作为JavaScript被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面这些例子都不会生效

<!-- 这是语句,不是表达式 -->
{{var a=1}}
<!-- 流程控制也不会生效,请使用三元表达式 -->
{{if(ok){return message}}}

例子
在这里插入图片描述

四、Vue条件渲染

v-if

v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true值的时候被渲染。

 <p v-if="flag">我是要成为海贼王的男人--路飞</p>
data(){
    return{
     flag:true
    }
  }

例子
在这里插入图片描述

v-else

你可以使用v-else来表示v-if的else块

    <p v-if="flag">我是要成为海贼王的男人--路飞</p>
    <p v-else>路飞</p>
  data(){
    return{
     flag:false
    }
  }

例子
在这里插入图片描述

v-show

另一个用于条件性展示元素的选项式v-show指令

<p v-show="flag">我是要成为海贼王的男人--路飞</p>
data(){
    return{
     flag:true
    }
  }
v-if和v-show的区别

也是经典的面试题

  • v-if是真正的渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建
  • v-if也是惰性的,如果在初始渲染时条件为假,则什么也不做–一直到条件第一次变为真时,才会开始渲染条件块。
  • 相比之下,v-show就简单得多–不管初始条件是什么,条件总是会被渲染,并且只是简单地基于CSS进行切换。=>display=>none和block之间切换。
  • 一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此如果需要非常频繁地切换,则使用v-show较好。如果在运行条件很好改变,则使用v-if较好。

五、Vue列表渲染

v-for

v-for把一个数组映射为一组元素

我们可以用v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items形式的特殊语法,其中items是原数据数组,而item则是被迭代的数组元素的别名

<ul>
      <li v-for="item in newsList">{{ item.title }}</li>
    </ul>
  data(){
    return{
     newsList:[
      {
        id:1001,
        title:'新闻头条1'
      },
      {
        id:1002,
        title:'新闻头条2'
      },
      {
        id:1003,
        title:'新闻头条3'
      },
     ]
    }
  }

例子
在这里插入图片描述

维护状态
  • 当vue正在更新使用v-for渲染的元素列表时,它默认使用’就地更新’的策略。如果数据项的顺序被改变,vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保他们在没个索引位置正确渲染。
  • 为了给vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的key attribute:
    <ul>
      <li v-for="item in newsList" :key="item.id">{{ item.title }}</li>
    </ul>
     <ul>
      <li v-for="{item,index} in newsList" :key="index">{{ item.title }}</li>
      //数据没有id,可以用index下面绑定key
    </ul>

五、Vue事件处理

监听事件

我们可以使用v-on指令(通常缩写为@符号)来监听DOM事件,并在触发事件时执行一些JavaScript。用法为v-on:click='methodName’或使用快捷方式@click=“methodName”

    <button v-on:click="num+=1">点击:{{ num }}</button>
    <button @click="num+=1">点击:{{ num }}</button>
  data(){
    return{
     num:0
    }
  }

例子
在这里插入图片描述

事件处理方法

然而许多事件处理逻辑会更为复杂,所以直接把JavaScript代码写在v-on指令中是不可行的。因此v-on还可以接收一个需要调用的方法名称。

    <button @click="clickHandle">按钮</button>
    <p>{{ message }}</p>
  data(){
    return{
     num:0,
     message:'消息通知'
    }
  },
  methods:{
    clickHandle(e){
      //在事件中,读取data中的属性,是需要通过this.属性
      this.message='消息被撤回了'
      console.log(e)
      // e是原生DOM event
      e.target.innerHTML='点击之后'
    }
  }

例子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

内联处理器中的方法

这是官方的翻译称呼,其实我们可以直接叫他“事件传递函数”

    <button @click="say('hi')">say hi</button>
    <button @click="say('what')">say what</button>
  methods:{
    say(data){
      console.log(data)
    }
  }
}

例子
在这里插入图片描述
例子2

    <ul>
      <li v-for="item in names
      " @click="clickItemHandle(item)">{{ item }}</li>
    </ul>
  data(){
    return{
     names:['路飞','索隆','乔巴']
    }
  },
  methods:{
    clickItemHandle(item){
      console.log(item)
    }
  }

在这里插入图片描述

六、Vue表单输入绑定

v-model

你可以用v-model指令在表单input、textarea及select元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。

<input type="text" v-model="useName">
    <input type="text" v-model="password">
    <p>{{ useName }},{{ password }}</p>
    <button @click="clickGetUserName">获取用户名</button>
data(){
    return{
     useName:"",
     password:""
    }
  },
  methods:{
    clickGetUserName(){
      console.log(this.useName)
    }
  }

例子
在这里插入图片描述

修饰符

lazy: 在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步,你可以添加lazy修饰符,从而转为change事件之后进行同步=>或者或失去焦点时=>减少性能消耗

   <input type="text" v-model.lazy="useName">

.trim:
如果要自动过滤用户输入的首尾空白符,可以给v-model添加trim修饰符

   <input type="text" v-model.trim="password">

七、Vue组件基础

单文件组件

vue单文件组件(又名==.vue文件==,缩写SFC)是一种特殊的文件格式,它允许将vue组件的 teplate => 模板、 script =>逻辑与 style => 样式封装在单个文件中

<template>
  <div class="hello">
    <h3>单文件组件</h3>
  </div>
</template>

<script>
export default {
  // innerHTML innerText
  name: 'HelloWorld',
  data(){
    return{
    }
  },
  methods:{
  }
}
</script>

<!-- 如果在style中添加scoped ,就代表着当前样式,只在当前组件中生效-->
<style scoped>
h3{
  color:red
}
</style>

加载组件
  • 第一步:引入组件=>import HelloWorld from ‘./components/HelloWorld.vue’
  • 第二步:挂载组件=>components: {HelloWorld}
  • 第三步:显示组件=>
    <HelloWorld/>
组件的组织

通常一个应用以一颗嵌套的组件树的形式来组织
在这里插入图片描述

在这里插入图片描述

八、Vue中Props组件交互

Props

组件与组件之间是需要存在交互的,否则完全没关系,组件的意义就很小了
prop是你可以在组件上注册的一些自定义attribute
从父组件传递

  <pop1 :title="title" :age="age" :names="names"/>
  data(){
    return{
      title:'我是一个标题',
      age:20,
      names:['路飞','索隆']
    }
  },

从子组件接收

  <p>{{ title }}</p>
  <p>{{ age }}</p>
  <ul>
    <li v-for="(item,index) in names" :key="index">{{ item }}</li>
  </ul>
export default{
  name:'pop1',
  props:{
    title:{
      type:String,
      // 接收值的类型
      default:''
      // 默认值
    },
    age:{
      type:Number,
      default:''
    },
    names:{
      type:Array,
      // 数组和对象必须使用函数进行返回
      default:function(){
        return []
    }
    }
  }
}
Props类型

Props传递参数其实是没有类型限制的

温馨提示
数据类型为数组或者对象的时候,默认值是需要返回工厂模式(工厂模式=>函数模式)

Props:{
	title:String,
	likes:Number,
	isPublished:Boolean,
	commentIds:Array,
	author:Object,
	callback:Function
}

例子
在这里插入图片描述
在这里插入图片描述

九、Vue中自定义事件组件交互

自定义事件可以在组件中反向传递数据,prop可以将数据从父组件传递到子组件,那么反向如何操作呢,就可以利用自定义事件实现 $emit
从子组件通过自定义事件向父组件传递数据

<button @click="sendClickHandle">点击向父组件传递数据</button>
  data(){
    return{
      message:'我是emits组件数据'
    }
  },
  methods:{
    sendClickHandle(){
      // 参数1:字符串:理论上是随便的,但是需要具有意义
      // 参数2:传递的数据
      this.$emit('onEvent',this.message)
  }

父组件接收数据

  <!-- 自定义事件 -->
  <emits @onEvent="getDateHandle" />
  <p>{{ message }}</p>
  data(){
    return{
    //先定义一个接收数据的字段
      message:'',
    }
  },
    methods:{
    //自定义的事件
    getDateHandle(data){
      console.log(data)
      this.message=data
    }
  }

例子
在这里插入图片描述

十、Vue组件生命周期

每个组件在被创建时都要经历一系列的初始化1过程一一例如,需要设置数据监听,编译模板、将实例挂载到DOM并在数据变化时更新DOM等,同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会

下方是vue官方生命周期图示=>所有红色框都输入vue的生命周期
一定要记住,这也是面试和前端必须掌握的
在这里插入图片描述
为了方便记忆,我将它们进行了一下分类:

  • 创建时 :beforeCreate创建之前created创建完成
  • 渲染时: beforeMount渲染之前mounted渲染完成
  • 更新时: beforeUpdate更新之前updated更新完成
  • 卸载时: beforeUnmount卸载之前unmounted卸载完成
export default {
  data() {
    return {
      message: ''
    }
  },
  // 创建时
  beforeCreate() {
    console.log('beforeCreate:组件创建之前');
  },
  created() {
    console.log('created:组件创建完成');
  },
  // 渲染时
  beforeMount() {
    console.log('beforeMount:组件渲染之前');
  },
  mounted() {
    console.log('mounted:组件渲染完成');
    //把网络请求放到这里
  },
  // 更新时
  beforeUpdate(){
    console.log('beforeUpdate:组件更新之前');
  },
  updated(){
    console.log('updated:组件更新完成');
  },
   // 销毁时
  beforeUnmount(){
    console.log('beforeUnmount:组件卸载之前');
    //卸载之前,把消耗性能的处理都干掉
    //比如定时器
  },
  unmounted(){
    console.log('unmounted:组件卸载完成');
  }
}

运行顺序
组件创建完成就会执行这四个声明周期=>如控制台打印所示:
在这里插入图片描述
页面发生变化执行的生命周期=>如控制台打印所示:
在这里插入图片描述
组件销毁时执行的生命周期,这里就先不给大家测试了,等后续用到我会写在文档中,总而言之,这些生命周期大家日后根据自己项目的业务逻辑进行熟悉,这里先做一些简单的了解

  // 销毁时
  beforeUnmount(){
    console.log('beforeUnmount:组件卸载之前');
  },
  unmounted(){
    console.log('unmounted:组件卸载完成');
  }

十一、Vue之引入第三方插件

关于大家在日常开发中有一些需求,可以在github上搜和vue官网推的

温馨提示
GitHub

在这里插入图片描述
根据点星数进行筛选
在这里插入图片描述

另外一个就是vue官网整合的一些比较好的第三方

温馨提示
Vue2官网
注意一定要注意自己使用vue的版本,并不是每个都可以用的,一定要找版本对应的

在这里插入图片描述
在这里插入图片描述

Swiper轮播图插件

在这里插入图片描述

温馨提示
Swiper官方文档
在vue中使用Swiper官方文档

  • Swiper开源、免费、强大的触摸滑动插件
  • Swiper是JavaScript打造的滑动特效插件,面向手机、平板、平板电脑等移动终端
  • Swiper能实现触屏焦点图、触屏Tab切换、触屏轮播切换等常用效果
  npm i swiper--save
  //在终端安装
  npm i swiper--save@8.16
  //安装指定版本
<template>
  <div>
    <Swiper>
      <SwiperSlide>
        图片1
      </SwiperSlide>
      <SwiperSlide>
        图片2
      </SwiperSlide>
      <SwiperSlide>
        图片3
      </SwiperSlide>
    </Swiper>
  </div>
</template>
<script>
import { Swiper, SwiperSlide } from 'swiper/vue';
// 引入Swiper
import 'swiper/css';
// 引入样式
export default{
  name:'lb',
  components:{
    Swiper,
    SwiperSlide
  },
  data(){
    return{
    }
  }
}

</script>
<style scoped>

</style>

例子
在这里插入图片描述

Swiper添加指示器
<template>
  <div>
    <!-- 使用指示器 -->
    <Swiper :modules="modules"   :pagination="{ clickable: true }">
      <SwiperSlide>
        <img src="图片地址" alt="">
      </SwiperSlide>
      <SwiperSlide>
       <img src="" alt="">
      </SwiperSlide>
      <SwiperSlide>
        <img src="" alt="">
      </SwiperSlide>
    </Swiper>
  </div>
</template>
<script>
import { Swiper, SwiperSlide } from 'swiper/vue';
// 引入Swiper
import 'swiper/css';
// 引入样式
import { Pagination} from 'swiper';
// 引入指示器
import 'swiper/css/pagination';
// 引入指示器样式
export default{
  name:'lb',
  components:{
    Swiper,
    SwiperSlide
  },
  data(){
    return{
      modules:[Pagination]
    }
  }
}

</script>
<style scoped>

</style>

例子
在这里插入图片描述

十二、Axios网络请求

Axios官方API
看云–Axios文档
Axios是一个基于Promise的网络请求库

Axios安装

Axios的应用是需要单独安装的

npm install --save axios
Axios引入

组件中引入:

import axios from "axios"
Axios网络请求基本实例
get请求
    <p>{{ chengpin.title }}</p>
import axios from 'axios'
// 引入axios
export default{
  name:'axiosob',
  mounted(){
    console.log('mounted:组件渲染完成');
    //把网络请求放到这里
    // get请求方式
    axios({
      method:'get',
      // 请求方式
      url:'http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php'
      // 请求地址
    }).then(res=>{
      console.log(res.data)
      this.chengpin=res.data.chengpinDetails[0]
      // 取数据
    })
  },
  data(){
    return{
      chengpin:{}
      //用来接受请求的数据
    }
  }
}
get请求快捷方案
    axios.get('http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php').then(res=>{
      console.log(res.data)
      this.chengpin=res.data.chengpinDetails[0]
      // 取数据
    })

例子
在这里插入图片描述

post请求
import axios from 'axios'
// 引入axios
export default{
  name:'axiosob',
  mounted(){
    console.log('mounted:组件渲染完成');
    //把网络请求放到这里
    // post请求方式
    axios({
      method:'post',
      // 请求方式
      url:'http://iwenwiki.com/api/blueberrypai/login.php',
      // 请求地址
      data:{
        user_id:'iwen@qq.com',
        password:'iwen123',
        verification_code:'crfvw'
      }
      // data是向后端接口传递的数据,可以数据实际工作中一定要根据后端给的文档规范传
    }).then(res=>{
      // 取数据
      console.log(res.data)
    })
  },
  data(){
    return{

    }
  }
}

但是遇到了一个问题
在这里插入图片描述

post请求向后端传递数据时,可能会遇到格式的问题,转字符串可以用以下第三方插件,可能已经过时了,这种第三方有很多,像qs等等

温馨提示
post请求参数需要额外处理的

  1. 转依赖:npm install --save querystring
  2. 转换参数格式:querystring.stringify({})
npm install --save querystring

安装完成,在组件中引用

import querystring from 'querystring'

使用querystring

    // post请求方式
    axios({
      method:'post',
      // 请求方式
      url:'http://iwenwiki.com/api/blueberrypai/login.php',
      // 请求地址
      data:querystring.stringify({
        user_id:'iwen@qq.com',
        password:'iwen123',
        verification_code:'crfvw'
      })
      // data是向后端接口传递的数据,可以数据实际工作中一定要根据后端给的文档规范传
    }).then(res=>{
      // 取数据
      console.log(res.data)
    })

使用后这样就没问题了

例子在这里插入图片描述

post请求快捷方案
    axios.post('http://iwenwiki.com/api/blueberrypai/login.php',querystring.stringify({
        user_id: 'iwen@qq.com',
        password: 'iwen123',
        verification_code: 'crfvw'
      })).then(res=>{
        console.log(res.data)
      })
  },
全局引用axios:

在main.js主入口文件引入

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import axios from 'axios'
// 全局引入axios

const app=createApp(App)
app.config.globalProperties.$axios = axios
//axios挂载到全局 
app.mount('#app')

在组件中使用就要变一下,例如

    this.$axios.get('http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php').then(res => {
      console.log(res.data)
      this.chengpin = res.data.chengpinDetails[0]
      // 取数据
    })

例子
在这里插入图片描述

十三、Axios网络请求封装

Axios官方API
看云–Axios文档
在日常开发过程中,一个项目中的请求会很多,此时一般采取的方案是网络请求封装起来

request.js封装Axios网络请求代码

src目录下创建文件夹utils,并创建文件request.js,用来存储网络请求对象axios

import axios from "axios";
// 引入axios
import querystring from "querystring";
// 引入querystring

const errorHandle = (status, info) => {
  // errorHandle错误函数
  switch (status) {
    case 400:
      console.log("400--语义错误");
      break;
    case 401:
      console.log("401--服务器认证失败");
      break;
    case 403:
      console.log("403--服务器拒绝访问");
      break;
    case 404:
      console.log("404--地址错误");
      break;
    case 500:
      console.log("500--服务器遇到意外");
      break;
    case 502:
      console.log("502--服务器无响应");
      break;
    default:
      console.log(info);
      break;
  }
};

const instance = axios.create({
  // 网络请求的公共配置
  timeout: 5000,
  // 请求超时时间最长5秒
});

// 这里最常用的=>拦截器
// 发送数据之前
instance.interceptors.request.use(
  (config) => {
    // config=>发送数据成功的函数
    if (config.method === "post") {
      config.data = querystring.stringify(config.data);
      // 格式化post传递参数的格式
    }
    // config:包含着网络请求的所有信息
    return config;
  },
  (error) => {
    // error=>发送数据失败的函数
    return Promise.reject(error);
    // 把失败的信息返回出去
  }
);

// 获取之前
instance.interceptors.response.use(
  (response) => {
    // response=>获取成功的函数
    return response.status === 200
      ? Promise.resolve(response)
      : Promise.reject(response);
    // response.status=>状态码
  },
  (error) => {
    // error=>获取数据失败的函数,错误的处理才是需要关注的
    const { response } = error;
    // response这里指错误的信息
    errorHandle(response.status,response.info)
  }
);
export default instance;
path.js封装请求公共路径和api接口路径

src目录下创建文件夹api,并创建文件==path.js(或base.js)用来设置路径

const base={
  // base把所有的路径都放在这里
  baseUrl:'http://iwenwiki.com',
  // baseUrl=>公共路径
  chengpin:'/api/blueberrypai/getChengpinDetails.php'
  // chengpin成品地址
}
export default base
index.js封装调接口api方法

src目录下创建文件夹api,并创建文件index.js调接口的文件

// 把所有网络请求的方法都放在这个文件
import axios from  "../utils/request"
// 引入封装好的request文件
import path from'./path'
// 引入path路径文件
const api={
  // 成品详情接口
  getChengpin(){
    return axios.get(path.baseUrl+path.chengpin)
  }
}
export default api
在组件中使用封装好的方法
import api from '../api/index'
// 引入调接口文件
export default {
  name: 'axiosob',
  mounted() {
    //使用封装好的方法
   api.getChengpin().then(res=>{
      console.log(res.data)
    })
  },
  data() {
    return {
    }
  }
}

例子
在这里插入图片描述

十五、网络请求跨域解决方案

JS采取的是同源策略

同源策略是游览器的一项安全策略,游览器只允许js代码请求和当前服务器域名,端口,协议相同的数据接口上的数据,这就是同源策略。
也就是说,当协议、域名、端口任意一个不同时,都会产生跨域问题,所以又应该如何解决跨域问题呢

跨域错误提示信息

下方是一个标准的跨域错误
在这里插入图片描述

在这里插入图片描述

目前主流的跨域解决方案有俩种
  • 后台解决:cors
  • 前端解决proxy

vue.config.js文件下配置

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  // 下列是解决跨域问题
  devServer:{
    proxy:{
      '/api':{
        target:'http://iwenwiki.com/',
        // target产生跨域的地址
        changeOrigin:true
      }
    }
  }
})

温馨提示
解决完跨域配置之后,要记得重启服务器才行哦!

这样就可以取到数据了
在这里插入图片描述

十六、Vue引入路由配置

在vue中,我们可以通过vue-router路由管理页面之间的关系
Vue Router是Vue.js的官方路由。它与Vue.js核心深度集成,让Vue.js构建单页面应用变得轻而易举

Vue-Router官网
在这里插入图片描述
在这里插入图片描述

Vue中引入路由
第一步:安装路由
npm install --save vue-router
第二步:配置独立的路由文件

src=>views文件夹=>放一些组件

  • HomeView组件
<template>
  <h3>HomeView组件</h3>
</template>
  • About组件
<template>
  <h3>About组件</h3>
</template>
  • index配置路由文件

src=>router路由文件夹=>index文件

// 路由配置文件
//1.引入路由
import { createRouter, createWebHashHistory,createWebHistory } from "vue-router";
// 2.引入页面组件
import HomeView from "../views/HomeView.vue";
import About from "../views/About.vue";
// 页面配置
const routes = [
  {
    path: "/",
    // path访问路径
    name: "Home",
    component: HomeView,
  },
  {
    path: "/about",
    name: "About",
    component: About,
  },
];

// 配置信息中需要页面的相关配置
const router = createRouter({
  // 配置路由
  /**
   * createWebHashHistory
   *    http://localhost:8081/#/
   *    http://localhost:8081/#/about
   * 原理:a标签的锚点链接
   */
  /**
   * createWebHistory
   *    http://localhost:8081/
   *    http://localhost:8081/about
   * 此种方式需要后台配合做重定向,否则会出现404问题
   * 原理:h5 pushState()
   */
  history: createWebHashHistory(),
  // history访问方式
  routes,
});
export default router;

第三步:引入路由到项目

在主入口文件main.js使用以下

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
// 引入配置好的路由文件
createApp(App).use(router).mount('#app')
// .use(router)进行使用
第四步:指定路由显示入口router-view

在页面中使用=>App.vue

<template>
  <router-view>
     <!-- RouterView路由的显示入口 -->
  </router-view>
   <RouterView></RouterView>

</template>
第五步:指定路由跳转
  <router-link to="/">
    <!--  router-link路由的跳转 -->
    首页
  </router-link>
  <router-link to="/about">
    <!--  router-link路由的跳转 -->
    关于
  </router-link>

效果
在这里插入图片描述

十七、Vue路由传递参数

页面跳转过程中,是可以携带参数的,这也是很常见的业务
例如:在一个列表页,点击进入查看每个列表项的详情

第一步:配置路由(router文件下index.js指定参数key)
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    path:'/news',
    name:'news',
    // 新闻列表页
    component:()=>import('../views/news.vue')
  },
  {
    path:'/newsDetails/:name',
    // 指定参数key
    name:'newsDetails',
    // 新闻详情页
    component:()=>import('../views/newsDetails.vue')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

第二步:在跳转过程中携带参数

在news组件下进行跳转

<template>
  <h3>新闻列表页</h3>
  <ul>
    <li><router-link to="/newsDetails/百度新闻"> 百度新闻 </router-link></li>
    <li><router-link to="/newsDetails/网易头条"> 网易新闻 </router-link></li>
    <li><router-link to="/newsDetails/头条新闻"> 头条新闻 </router-link></li>
  </ul>
</template>

在这里插入图片描述

第三步:在详情页面读取路由携带的参数

在newsDetails详情页

<template>
  <!-- 传递的key -->
  <h3>{{$route.params.name}}--新闻详情</h3>
</template>

效果
在这里插入图片描述

在这里插入图片描述

十七、Vue嵌套路由配置

路由嵌套是非常常见的需求

第一步:创建子路由要加载显示的页面
第二步:在路由配置文件中添加子路由配置

router文件下index.js

import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // name组件名字可加可不加
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),
    children:[{
      // 子页面路由配置
      // 二级导航的路径不要加 /
      path:'info',
      component:()=>import('../views/AboutSub/AboutInto.vue')
    },
    {
      path:'news',
      component:()=>import('../views/AboutSub/AboutNews.vue')
    }]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

第三步:指定子路由显示文章router-view
第四步:添加路由跳转链接

about页面

<template>
  <div class="about">
    <!-- 点击展示子页面 -->
    <router-link :to="{path:'info'}">关于信息</router-link>
   | <router-link :to="{path:'news'}">关于新闻</router-link>
   <router-view>
    <!-- 用来展示子页面信息 -->
   </router-view>
  </div>
</template>
第五步:重定向配置redirect

router文件下index.js

 {
    path: '/about',
    name: 'about',
    redirect:'/about/info',
    // 重定向
    // name组件名字可加可不加
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),
    children:[{
      // 子页面路由配置
      // 二级导航的路径不要加 /
      path:'info',
      component:()=>import('../views/AboutSub/AboutInto.vue')
    },
    {
      path:'news',
      component:()=>import('../views/AboutSub/AboutNews.vue')
    }]
  }

效果
在这里插入图片描述

总结

素材联系我

持续更新中

如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对前端端或者对python感兴趣的朋友,请多多关注💖💖💖,咱们一起探讨和努力!!!
👨‍🔧 个人主页 : 前端初见

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端初见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值