铁佛 发表于 2024-11-15 06:05:57

苍穹外卖-day13(vue基础回顾+进阶):vue基础(脚手架、根本语法,axios,

vue基础回顾+进阶

课程内容



[*]VUE 基础回顾
[*]路由 Vue-Router
[*]状态管理 vuex
[*]TypeScript
1. VUE 基础回顾

1.1 基于脚手架创建前端工程

1.1.1 环境要求

要想基于脚手架创建前端工程,需要具备如下环境要求:


[*]​ node.js 前端项目的运行环境

[*]学习web阶段已安装

[*]​ npm JavaScript的包管理工具

[*]安装完node.js之后自带了npm这个命令

[*]​ Vue CLI 基于Vue举行快速开辟的完整系统,实现交互式的项目脚手架

[*]需要通过npm命令来安装

安装完node.js后,可以通过命令行来查看版本号,如下:
https://i-blog.csdnimg.cn/blog_migrate/88245f6d58cbfee9b59cd6f06c30304e.png
安装 Vue CLI,命令如下:
https://i-blog.csdnimg.cn/blog_migrate/392c7eeb0fe4f7428afa40e6991af2ab.png
1.1.2 操纵过程

利用 Vue CLI 创建前端工程的方式:


[*]方式一:vue create 项目名称

[*] 管理员的方式打开Dos窗口,之后进入到一个非中文目录(这个目录当做我们的VScode工作空间),输入命令vue create vue-demo-1
https://i-blog.csdnimg.cn/blog_migrate/8489a205a2d411035a0efcd42cfa82fb.png
[*] 上下键选择vue的版本,这里以vue2为例
https://i-blog.csdnimg.cn/blog_migrate/d7974f067f26f4ad22572428ea73029a.png
https://i-blog.csdnimg.cn/blog_migrate/88bf910c2367d043a4c2a1701f42ae70.png
[*] 可以看到vue项目创建乐成
https://i-blog.csdnimg.cn/blog_migrate/6d4f157a5af7448a2a51ba1f1614a454.png
https://i-blog.csdnimg.cn/blog_migrate/f56086a9bdd78a44cca4dff0c7750145.png



[*]​ 方式二:vue ui(推荐)
重点先容利用 vue ui 命令创建前端工程的过程:
第一步:同样首先以管理员的方式打开命令行窗口,之后切换到一个非中文的目录(这个目录当做我们的VScode工作空间),在命令行输入命令 vue ui,在浏览器ui界面中选择前端工程存放的位置
https://i-blog.csdnimg.cn/blog_migrate/e8ffa0a35329138b0de8e0e9a1a54af8.png
https://i-blog.csdnimg.cn/blog_migrate/535750704089d7995461bd0884e71e27.png
第二步:点击“在此创建新项目”按钮,跳转到创建新项目设置页面。填写项目名称、选择包管理器为npm,点击“下一步”按钮
https://i-blog.csdnimg.cn/blog_migrate/f393f38879831d879a6f5d2a985ecf79.png
第三步:选择 Default(Vue 2),点击"创建项目"按钮,完成项目的创建
https://i-blog.csdnimg.cn/blog_migrate/b146a023b69a601dc01c897920564208.png
https://i-blog.csdnimg.cn/blog_migrate/42b1376532edc9d2c5003e839655f59e.png
https://i-blog.csdnimg.cn/blog_migrate/521daf4e74ea363f9a99d3507b03a86a.png
https://i-blog.csdnimg.cn/blog_migrate/c0a6fbc5745bab8c936e15c1d8bc5d99.png
1.1.3 工程结构

工程目录结构:
https://i-blog.csdnimg.cn/blog_migrate/78c73a5ef0b2510489603eb2392d5f0a.png
1.1.4 启动前端服务

利用VS Code打开创建的前端工程,启动前端工程:
https://i-blog.csdnimg.cn/blog_migrate/e6eca6324c95f1130c613e7bb4166200.png
访问前端工程:
https://i-blog.csdnimg.cn/blog_migrate/57b6d6a03ba0a21e64595c94aae8a6eb.png
注:要停止前端服务,可以在命令行终端利用 ctrl + C
前端项目启动后,服务端口默以为8080,很容易和后端tomcat端口号冲突。如何修改前端服务的端口号?
可以在vue.config.js中配置前端服务端口号:
https://i-blog.csdnimg.cn/blog_migrate/bbd01f6a489917e712c7ef6bbdb30efa.png
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
    port: 7070//指定前端服务端口号
}
})
1.2 vue根本利用方式

本章节从如下几个方面举行vue回顾:


[*]vue 组件
[*]文本插值
[*]属性绑定
[*]事件绑定
[*]双向绑定
[*]条件渲染
[*]axios
1.2.1 vue 组件

Vue 的组件文件以 .vue 末了,每个组件由三部门组成:


[*]结构 <template>
[*]样式 <style>
[*]逻辑 <script>
https://i-blog.csdnimg.cn/blog_migrate/e6913c034f266f71786d5dc763c0790f.png
1.2.2 测试准备工作

说明:


[*]当前页面比力乱它自带了很多的数据,为了方便测试效果把数据给它清算一下。
https://i-blog.csdnimg.cn/blog_migrate/d30b426385647c37da258a3e97e66b2a.png
https://i-blog.csdnimg.cn/blog_migrate/ea85c8e74084901d37751d2fb9467443.png
https://i-blog.csdnimg.cn/blog_migrate/d2a540fd21229e8cb619671443ae101a.png
[*]可以看到页面上还显示一个图片,这是因为当前展示的这个页面并不是直接来自于HelloWorld.Vue组件而是这个App.vue,App.vue组件才是真正的项目入口页面,App.vue页面中又引入了HelloWorld.Vue组件,这个图片是设置在App.vue组件中,此时不想要图片需要到App.vue组件中举行删除。
https://i-blog.csdnimg.cn/blog_migrate/d0dd8e99165e04bc17818aac3a28cdc0.png
[*]效果
https://i-blog.csdnimg.cn/blog_migrate/b71b234789547d73b48778037e590505.png
1.2.3 文本插值

作用:用来绑定 data 方法返回的对象属性
用法:{{插值表达式}}
示例:
https://i-blog.csdnimg.cn/blog_migrate/cc46397c58d9ced003d2725f5a58b01f.png
测试:
代码:
https://i-blog.csdnimg.cn/blog_migrate/812cbe646d087f591a1843021632b0fd.png
<template>
<div class="hello">
    {{name}}
    {{age > 60 ? '老年' : '青年'}}
</div>
</template>

<script>
export default {
name: 'HelloWorld',
props: {
    msg: String
},
data() {
    return {
      name: '张三',
      age: 22
    }
},

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

效果:
https://i-blog.csdnimg.cn/blog_migrate/40bc569b6eb82e26a69f0f36680809d1.png
1.2.4 属性绑定

作用:为标签的属性绑定 data 方法中返回的属性
用法:v-bind:xxx,简写为 :xxx
示例:
https://i-blog.csdnimg.cn/blog_migrate/9da7585c3bd4d1ab0df3941811e9489f.png
测试:
代码
https://i-blog.csdnimg.cn/blog_migrate/26eee9cc1bdc215e15413ff5560b5d85.png
效果
https://i-blog.csdnimg.cn/blog_migrate/1b2f73fc11b681a893450ce7d72b3b7d.png
1.2.5 事件绑定

作用:为元素绑定对应的事件
用法:v-on:xxx,简写为 @xxx
示例:
https://i-blog.csdnimg.cn/blog_migrate/c13797322d092f3a92ee1ca08fb173d3.png
测试:
代码
https://i-blog.csdnimg.cn/blog_migrate/89a77218ce1c82bea53600659411b8ba.png
效果
https://i-blog.csdnimg.cn/blog_migrate/1c85590a943ea952f552ceef5146be50.png
1.2.6 双向绑定

作用:表单输入项和 data 方法中的属性举行绑定,任意一方改变都会同步给另一方
用法:v-model
示例:
https://i-blog.csdnimg.cn/blog_migrate/eefd3a07401b743ff784569ccd40a2cd.png
测试:
代码
https://i-blog.csdnimg.cn/blog_migrate/621f115439ec528ffcf0150fedc8e99f.png
效果:修改输入框的值name会发生变化,点击事件方法修改name的值输入框的值会跟着改变
https://i-blog.csdnimg.cn/blog_migrate/97fedd467492f5a580901912c1235462.png
https://i-blog.csdnimg.cn/blog_migrate/067e35171e5583d43529a78f29e7941b.png
1.2.7 条件渲染

作用:根据表达式的值来动态渲染页面元素
用法:v-if、v-else、v-else-if
示例:
https://i-blog.csdnimg.cn/blog_migrate/b92c3d8f49175d13b21d8def7cd03001.png
测试:
代码
https://i-blog.csdnimg.cn/blog_migrate/17a12986b87adcbfce9383bfc3a1dc6e.png
效果
https://i-blog.csdnimg.cn/blog_migrate/349f45001f8ee3653e85a864db978252.png
1.2.8 axios

Axios 是一个基于 promise 的 网络哀求库,作用于浏览器和 node.js 中。利用Axios可以在前端项目中发送各种方式的HTTP哀求。
安装axios的命令:npm install axios(以管理员的方式打开VScode)
https://i-blog.csdnimg.cn/blog_migrate/d476c9a69b4170f45930339e7690e835.png
导入:import axios from 'axios'
https://i-blog.csdnimg.cn/blog_migrate/fba02ff5b7e1cde1e0f1239470e95cc6.png
axios 的 API 列表:[ ]代表可选参数,可以有可以没有。
https://i-blog.csdnimg.cn/blog_migrate/826145b8a3e3094ffe54a979223c12c2.png
参数说明:


[*]url:哀求路径
[*]data:哀求体数据,最常见的是JSON格式数据
[*]config:配置对象,可以设置查询参数、哀求头信息
注:在利用axios时,经常会遇到跨域问题。为相识决跨域问题,可以在 vue.config.js 文件中配置代理:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
    port: 7070,
    proxy: {
      '/api': {
      target: 'http://localhost:8080',
      pathRewrite: {
          '^/api': ''
      }
      }
    }
}
})
axios的post哀求示例:
axios.post('/api/admin/employee/login',{
      username:'admin',
      password: '123456'
    }).then(res => {
      console.log(res.data)
    }).catch(error => {
      console.log(error.response)
    })
axios的get哀求示例:
axios.get('/api/admin/shop/status',{
      headers: {
          token: ‘xxx.yyy.zzz’
      }
      })
axios提供的统一利用方式示例一(可以发送各种方式的哀求):
https://i-blog.csdnimg.cn/blog_migrate/bd2fba5500b185adf5016bef12a066c8.png
axios提供的统一利用方式示例二(可以发送各种方式的哀求):
axios({
      url: '/api/admin/employee/login',
      method:'post',
      data: {
      username:'admin',
      password: '123456'
      }
    }).then((res) => {
      console.log(res.data.data.token)
      axios({
      url: '/api/admin/shop/status',
      method: 'get',
      params: {id: 100},
      headers: {
          token: res.data.data.token
      }
      })
    }).catch((error) => {
      console.log(error)
    })
1.2.9 axios 测试:没有配置跨域----post哀求

HelloWorld.vue代码:
https://i-blog.csdnimg.cn/blog_migrate/8053bdc83766d911bb2b6b1ec59d4ea6.png
https://i-blog.csdnimg.cn/blog_migrate/f341a39d3f83a323993d14685f228f26.png
<input type="button" value="发送POST请求" @click="handleSendPOST"/>




    handleSendPOST() {
      //通过axios发送post请求 提供了urldata没有提供config
      //地址是苍穹外卖后台登录的接口地址,后台项目要先启动
      axios.post('http://localhost:8080/admin/employee/login',{
      username: 'admin',
      password: '123456'
      }).then(res => {//调用成功的回调函数
      console.log(res.data)
      }).catch(error => { //调用失败的回调函数
      console.log(error.response)
      })
    },
启动后台项目,启动前端项目vue-demo-2,点击按钮发送哀求发现前后台没有任何反应,f12查看控制台发现报错(发生了跨域)
https://i-blog.csdnimg.cn/blog_migrate/a8c8b75359b29aaef34aa54901e2d26d.png
https://i-blog.csdnimg.cn/blog_migrate/44005ce7fd7b937eaa31d6001940a41f.png
https://i-blog.csdnimg.cn/blog_migrate/546126b9ec00626c142356f27e0bfca7.png
原因:发生了跨域问题,前端的访问端口是7070,后端的是8080,当前是在7070服务中往8080这个端口发送,以是产生了跨域。
解决:需要配置代理
1.2.10 axios 测试:配置跨域----post哀求

为相识决跨域问题,可以在 vue.config.js 文件中配置代理:
代理的作用:前端发送的哀求先哀求到代理上,然后由代理举行转发到我们的后台服务,这样就可以解决跨域问题了。
https://i-blog.csdnimg.cn/blog_migrate/e093ecc3a032ed0401ac885a03d4b877.png
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
    port: 7070,
    proxy: {
      '/api': {//拦截前端发送的请求都含有api前缀的地址
      target: 'http://localhost:8080',//拦截后转发到的目标服务器地址
      pathRewrite: {//请求转发到后端后,后端接口路径多了个/api,匹配不上找不到controller,所以需要去掉
          '^/api': '' //路径重写:把/api替换为空串^api表示以/api作为开头
      }
      }
    }
}
})
修改HelloWorld.vue中发送的后台哀求地址:http://localhost:8080—》/api
https://i-blog.csdnimg.cn/blog_migrate/deb237809e97822433c68736e6d21265.png
因为修改的是配置文件以是需要重启前端项目才能生效
https://i-blog.csdnimg.cn/blog_migrate/972c6d1a8b5e8af145dee6578918c9fe.png
再次发送哀求:
https://i-blog.csdnimg.cn/blog_migrate/9299cc4477feffb01a6c8986c37865c9.png
https://i-blog.csdnimg.cn/blog_migrate/caa800ef2e66a147ad6405524816684e.png
1.2.11 axios 测试:get哀求

HelloWorld.vue代码:
https://i-blog.csdnimg.cn/blog_migrate/0ecd6d537c4f52c3afac722970ded528.png
https://i-blog.csdnimg.cn/blog_migrate/579c917b1f8c2d3d12cf1896966bf859.png
<input type="button" value="发送GET请求" @click="handleSendGET"/>


    handleSendGET() {
      //通过axios发送get方式请求指定了url(店铺的营业状态)指定config
      axios.get('/api/admin/shop/status',{
      //这个请求需要携带jwt的令牌地址才能正确访问,复制上面发送post请求调用登录接口生成的令牌地址
      headers: { //指定config,在请求头里追加参数token
          token: 'eyJhbGciOiJIUzI1NiJ9.eyJlbXBJZCI6MSwiZXhwIjoxNzEwNjkyMTgxfQ.WAb2SoElTlJcobDCXUAqKPlm0At68LAexTz1MTwZdz4'
      }
      }).then(res => {
      console.log(res.data)
      })
    },
对应的店铺营业状态接口:
https://i-blog.csdnimg.cn/blog_migrate/4392ad08cd4fb032300afe1f95accc82.png
首先发送post哀求,复制返回的token.
https://i-blog.csdnimg.cn/blog_migrate/493a82c1d60e7e122c22b5f99459885d.png
https://i-blog.csdnimg.cn/blog_migrate/f4a9ab2cd88106206516246f67fb8c34.png
刷新页面发送get哀求:乐成
https://i-blog.csdnimg.cn/blog_migrate/ecc0deb4864c2186cb87a9c42f6f5b39.png
1.2.12 axios 测试:通用方式发送哀求

axios 统一利用方式:axios(config)
HelloWorld.vue代码:
https://i-blog.csdnimg.cn/blog_migrate/277bd4442bed3892a376480ab6bb330f.png
https://i-blog.csdnimg.cn/blog_migrate/d5bae39d874a3ffe1d01cc0a9eff7ac7.png
<input type="button" value="统一请求方式" @click="handleSend"/>


    handleSend() {
      //使用axios提供的统一调用方式发送请求
      axios({
      url: '/api/admin/employee/login',
      method: 'post',//默认是get
      data: { //data表示通过请求体传参
          username: 'admin',
          password: '123456'
      }
      }).then(res => {//成功回调
      console.log(res.data.data.token) //res.data:返回的result对象,里面包含data,data中又包含token
      axios({//在成功的回调函数里又发送一个get请求   获取店铺的营业状态
          url: '/api/admin/shop/status',
          method: 'get',
          headers: {
            token: res.data.data.token //因为这个get方法实际上是在post请求的回调函数里面,所以这个地方可以动态的获取token
          }
      })
      })
    }
测试:2次哀求都乐成发送
https://i-blog.csdnimg.cn/blog_migrate/a54264044c78a66656033a022b7a22d5.png
https://i-blog.csdnimg.cn/blog_migrate/a953e6dd9fed29ddfd82f6d42cb4164f.png
2. 路由 Vue-Router

2.1 Vue-Router 先容

vue 属于单页面应用,所谓路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容。
单页面应用:在整个vue应用中,实际上只有一个页面,我们看到的浏览器多个页面实在是一种假象,它是通过页面切换 切换不同的视图组件
现实举例:一块黑板,不同的老师上课把之前老师写的内容删除掉,之后写上本身课的内容。
这个替换的过程就是通过路由来完成的。
https://i-blog.csdnimg.cn/blog_migrate/7d5fc6c6e8150962f2dd9881c4d3460a.png
https://i-blog.csdnimg.cn/blog_migrate/4bec3f196cf47be89baf141f55549c70.png
如上图所示:不同的访问路径,对应不同的页面展示。
基于Vue CLI 创建带有路由功能的前端项目:
在vue应用中利用路由功能,需要安装Vue-Router:
https://i-blog.csdnimg.cn/blog_migrate/164df6b94cfde01f116dd540cd3071f7.png
https://i-blog.csdnimg.cn/blog_migrate/b1d23fb8479dabb5a7a8f6fb197a43e7.png
https://i-blog.csdnimg.cn/blog_migrate/77eebcb2fc2613ae71f88bddd3d1c58e.png
https://i-blog.csdnimg.cn/blog_migrate/ee85a0958021e4066033cf9a46f1335f.png
https://i-blog.csdnimg.cn/blog_migrate/90b23b7f1501bd1a5043dab3e91c6a65.png
https://i-blog.csdnimg.cn/blog_migrate/73dddffa67e8276dc4716851c7b8f24b.png
注:创建完带有路由功能的前端项目后,在工程中会天生一个路由文件,如下所示:
https://i-blog.csdnimg.cn/blog_migrate/13febcc7a0ab5a78ad6d801212ff029f.png
关于路由的配置,重要就是在这个路由文件中完成的。
为了能够利用路由功能,在前端项目的入口文件main.js中,创建Vue实例时需要指定路由对象:
创建完路由项目后主动天生
https://i-blog.csdnimg.cn/blog_migrate/fc7fa8c0445c9b1fc4d2cd41b61b306b.png
启动项目查看效果:点击不同的地址会主动切换页面
https://i-blog.csdnimg.cn/blog_migrate/6c69851dd5c2c2641b2e9d83e9b921d0.png
说明:


[*]什么是路由?

[*]根据浏览器访问路径不同,展示不同的视图组件

[*]vue应用中如何实现路由?

[*]通过 vue-router 实现路由功能,需要安装js库(npm install vue-router)
[*]刚才之以是没有显示的去安装是因为,在页面上利用了脚手架构建项目并且勾选了路由功能,这样的话在创建这个前端工程时,实际上就会通过这个命令安装所需要的库。
[*]如果是一个老项目利用路由功能,此时需要实行此命令手动安装。

2.2 路由配置

首先相识一下路由组成:


[*]VueRouter:路由器,根据路由哀求在路由视图中动态渲染对应的视图组件

[*]路由器作用:根据路由哀求来渲染这个不同的视图
[*]具体渲染哪一个视图组件呢???在路由器中实在会维护一个路由表,它里面生存了映射关系,某一个路由路径对应的那一个视图组件。

[*]<router-link>:路由链接组件,浏览器会解析成<a>

[*]作用:天生超链接标签的

[*]<router-view>:路由视图组件,用来展示与路由路径匹配的视图组件

[*]展示某一个视图组件指定的位置,本质是页面中的一个占位符,通过路由去渲染不同的视图组件,视图组件要渲染的就是这个页面<router-view>占位符地点的位置。

https://i-blog.csdnimg.cn/blog_migrate/77bf008edb87faed4d3c43d655614a62.png
这三部门之间是如何协作的:


[*]点击路由链接组件(超链接)发起路由哀求,这个哀求会交给路由器处理。
[*]路由器会根据路由路径的不同然后去渲染对应的视图组件
[*]具体渲染到这个路由视图组件 <router-view>这个占位符位置。
具体配置方式:
基于脚手架创建前端项目的时候勾选了路由功能,此时工程中路由的代码已经主动天生好了。
首先在package.json里面参加vue-router:此时就可以在前端项目中利用路由功能了
https://i-blog.csdnimg.cn/blog_migrate/0a044bb83cadd68b2250bf2516f3239c.png
然后在main.js入口文件中引入router,这个router来自于index.js文件
https://i-blog.csdnimg.cn/blog_migrate/97fae1b6d1451e1208f463eec92ad756.png
找到router下面有一个index.js,然后在这个文件里引入VueRouter,这个VueRouter来自于node_modules(生存创建好项目之后所依赖的包)中的vue-router里
https://i-blog.csdnimg.cn/blog_migrate/66c7c72e075fbce9996c47437934e9fb.png
https://i-blog.csdnimg.cn/blog_migrate/b07f660113b6e9efc293b016255a029b.png

[*]在路由文件index.js中配置路由路径和视图的对应关系:路由表
https://i-blog.csdnimg.cn/blog_migrate/f541c8ca749df26b73f4cc03092da47d.png
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

//维护路由表,某个路由路径对应哪个视图组件
const routes = [
{
    path: '/',   //对应一个路由路径
    name: 'home',//名字
    component: HomeView//路径所对应的视图组件   方式一:静态导入,最终项目上线需要打包,打包会把这些组件
},                     //                           打到同一个js文件里面,两种打包方式不同
                         //                        性能稍差:不管你视图展示不展示都打入到同一个js文件里面,导致这个js文件非常大,
                         //                                  哪怕你这个视图从来没有强求过没显示过,但是这部分资源已经加载了,
{
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about..js) for this route
    // which is lazy-loaded when the route is visited.
    //方式二:动态导入(推荐)懒加载策略:打包的时候会单独的把这些组件打到js文件里面
    //                   性能更好:按需引入因为它是单独的把这些视图组件单独的打到js文件里面,
    //                            只有请求这个视图它才会加载这个js文件,如果不请求就不会加载了。
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]

const router = new VueRouter({
routes
})

export default router


[*]在视图组件App.vue入口页面文件中配置 router-link标签,用于天生超链接
https://i-blog.csdnimg.cn/blog_migrate/a7dc701ee80dcd8861c1cf4f62350a84.png
      <router-link to="/">Home</router-link> |<!-- 路由链接组件生成超链接 -->
      <router-link to="/about">About</router-link>

[*]在视图组件汇总配置router-view标签:占位符,视图渲染到的位置
https://i-blog.csdnimg.cn/blog_migrate/176b50b77906cca94254d3e92cd5c8ef.png
[*]效果:可以来回切换
https://i-blog.csdnimg.cn/blog_migrate/9a9fd2ae30fee1f14eed4af26d762609.png
https://i-blog.csdnimg.cn/blog_migrate/5586cfb9b279ff4e72ec33e101b3e6e4.png
要实现路由跳转,可以通过标签式和编程式两种:


[*]标签式:<router-link to="/about">About</router-link>

[*]通过router-link标签天生超链接实现跳转

[*]编程式:this.$router.push('/about')

[*]通过js代码实现跳转
https://i-blog.csdnimg.cn/blog_migrate/5fde243e774f3d3ce1686b46c9ea5490.png

测试编程式:
代码:
https://i-blog.csdnimg.cn/blog_migrate/fb298435d636cd686ef3bf43eeeaacce.png
<input type="button" value="编程式路由跳转" @click="jump"/> <!-- 方法不需要参数的话()可以省略掉 -->


<script>
export default {
methods: {
    jump() {
      //使用编程路由的方式跳转   具体的路由路径(路由表中配置的路径)
      this.$router.push('/about',()=> {})
    }
}
}
</script>
效果:点击按钮也能跳转到about页面
https://i-blog.csdnimg.cn/blog_migrate/d2e55cdc92f15121900a357a09d85191.png
https://i-blog.csdnimg.cn/blog_migrate/576bbe378054a5039db942a7bf27caf3.png
问题思考:如果用户访问的路由地址不存在,该如何处理?
可以通过配置一个404视图组件,当访问的路由地址不存在时,则重定向到此视图组件,具体配置如下:
index.js文件:路由表
https://i-blog.csdnimg.cn/blog_migrate/46e114f8ec8a3afaa97029dea1c965af.png
/* 只写这一个配置的效果:我们访问到404路径的时候就可以访问到这个组件,而我们的需求是
   当用户访问一个不存在的路径时才会跳转到404视图去展示,所以还需要接着配置重定向*/
{
    path: '/404',   //name可以不用配置
    component: () => import('../views/404View.vue')
},
/* 配置重定向流程:当用户访问到一个不存在的路径就会重定向到/404,/404路径对应的就是404页面组件 */
{
    path: '*', //上面这些访问的路径都没匹配上才会走这最后一个路径
    redirect: '/404' //重定向到/404访问路径,
}
App.vue:超链接
<router-link to="/test">Test</router-link> |   <!-- 没有对应的路由路径/test -->
https://i-blog.csdnimg.cn/blog_migrate/e72a60c0dcfd8df5d7b0a3de09df10f5.png
路由哀求路径不存在,跳转的页面组件:
https://i-blog.csdnimg.cn/blog_migrate/d68d701b4194247e32ffeab1b2aef17d.png
<template>
<div class="about">
    <h1>您请求的资源不存在</h1>
</div>
</template>

效果:
https://i-blog.csdnimg.cn/blog_migrate/0d78502b035d4f1532449d92aeb5034f.png
2.3 嵌套路由

嵌套路由:组件内要切换内容,就需要用到嵌套路由(子路由),效果如下:
在App.vue视图组件中有<router-view>标签,其他视图组件可以展示在此
https://i-blog.csdnimg.cn/blog_migrate/7d635f7c14d0a6346dd3ec4abcc7844e.png
ContainerView.vue组件可以展示在App.vue视图组件的<router-view>位置
https://i-blog.csdnimg.cn/blog_migrate/c0c170341e38e182bb14486c9bad0dd2.png
ContainerView.vue组件举行了区域分别(分为上、左、右),在右边编写了<router-view>标签,点击左侧菜单时,可以将对应的子视图组件展示在此
https://i-blog.csdnimg.cn/blog_migrate/6d1f90053fadbc9bac1c80cb14ba0832.png
总结:


[*]原先是不同的vue组件嵌套到App.vue入口视图组件页面中
[*]现在是不同的子组件先嵌套到ContainerView.vue组件中,ContainerView.vue组件在嵌套到App.vue入口视图组件中。
实现步骤:
第一步:安装并导入 elementui,实现页面布局(Container 布局容器)—ContainerView.vue
安装: elementui
https://i-blog.csdnimg.cn/blog_migrate/bb037f97c3b816a2ad23a3451bdd733b.png
npm i element-ui -S
https://i-blog.csdnimg.cn/blog_migrate/8f7381fd5fb677b930ccf32a2395e6c6.png
导入: elementui,在 main.js 中写入以下内容:
https://i-blog.csdnimg.cn/blog_migrate/0ddcce4b26da0758c204117895fc468e.png
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);//全局使用ElementUi
实现页面布局(Container 布局容器)—ContainerView.vue
https://i-blog.csdnimg.cn/blog_migrate/bf16ccf99501ca16b6b11379314918ab.png
<template>
<el-container>
    <el-header>Header</el-header>
    <el-container>
      <el-aside width="200px">
      </el-aside>
      <el-main>
      </el-main>
    </el-container>
</el-container>
</template>

<script>
export default {

}
</script>

<style>
.el-header, .el-footer {
    background-color: #B3C0D1;
    color: #333;
    text-align: center;
    line-height: 60px;
}

.el-aside {
    background-color: #D3DCE6;
    color: #333;
    text-align: center;
    line-height: 200px;
}

.el-main {
    background-color: #E9EEF3;
    color: #333;
    text-align: center;
    line-height: 160px;
}

body > .el-container {
    margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
    line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
    line-height: 320px;
}
</style>
第二步:提供子视图组件,用于效果展示 —P1View.vue、P2View.vue、P3View.vue
https://i-blog.csdnimg.cn/blog_migrate/2c54423b0451121d247bfe907896a9ee.png
<template>
<div>
    这是P1 View
</div>
</template>

<script>
export default {

}
</script>

<style>
.el-header, .el-footer {
    background-color: #B3C0D1;
    color: #333;
    text-align: center;
    line-height: 60px;
}

.el-aside {
    background-color: #D3DCE6;
    color: #333;
    text-align: center;
    line-height: 200px;
}

.el-main {
    background-color: #E9EEF3;
    color: #333;
    text-align: center;
    line-height: 160px;
}

body > .el-container {
    margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
    line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
    line-height: 320px;
}
</style>
第三步:在 src/router/index.js 中配置路由映射规则(嵌套路由配置)
https://i-blog.csdnimg.cn/blog_migrate/c8a2ff12561df5d2d2b62e3d534cbbd9.png
   {
    path: '/c',
    component: () => import('../views/container/ContainerView.vue'),
    //嵌套路由(子路由),对应的组件会展示在当前组件内部
    children: [//通过children属性指定子路由相关信息(path、component)
      {
      path: '/c/p1',
      component: () => import('../views/container/P1View.vue')
      },
      {
      path: '/c/p2',
      component: () => import('../views/container/P2View.vue')
      },
      {
      path: '/c/p3',
      component: () => import('../views/container/P3View.vue')
      }
    ]
}
第四步:在ContainerView.vue 布局容器视图中添加,实现子视图组件展示
https://i-blog.csdnimg.cn/blog_migrate/92e31917077842826a0c9aa216e4e74e.png
<el-main>
    <router-view/>
</el-main>
第五步:在ContainerView.vue 布局容器视图中添加,实现路由哀求
https://i-blog.csdnimg.cn/blog_migrate/a5dc401541b5616b76a9c83a8b3c7ad1.png
<el-aside width="200px">
    <router-link to="/c/p1">P1</router-link><br>
    <router-link to="/c/p2">P2</router-link><br>
    <router-link to="/c/p3">P3</router-link><br>
</el-aside>
效果:http://localhost:8080/#/c
https://i-blog.csdnimg.cn/blog_migrate/5e2de07b00a5fc793a0e18d975573c77.png
点击超链接(http://localhost:8080/#/c/p1)右侧会举行替换组件。
https://i-blog.csdnimg.cn/blog_migrate/558ebdb2c54c48385f479fc34201fdc9.png
注意:子路由变化,切换的是【ContainerView 组件】中 <router-view></router-view> 部门的内容
问题思考:
1.对于前面的案例,如果用户访问的路由是 /c,会有什么效果呢?
https://i-blog.csdnimg.cn/blog_migrate/c7a59297dbdde3088739db4af3b55245.png
2.如何实现在访问 /c 时,默认就展示某个子视图组件呢?
配置重定向,当访问/c时,直接重定向到/c/p1即可,如下配置:
https://i-blog.csdnimg.cn/blog_migrate/e0d7f3b3a9271f0666282113f93f78ef.png
https://i-blog.csdnimg.cn/blog_migrate/16fc1a232a2a0f100fa04726b806c186.png
redirect :'/c/p1',
效果:
https://i-blog.csdnimg.cn/blog_migrate/f1cc2d347eceb8ad6040d65e9ff5e9b0.png
3. 状态管理 vuex(待定:P177)

3.1 vuex 先容



[*]vuex 是一个专为 Vue.js 应用程序开辟的状态管理库
[*]vuex 可以在多个组件之间共享数据,并且共享的数据是相应式的,即数据的变动能及时渲染到模板
[*]vuex 采用集中式存储管理所有组件的状态
每一个 Vuex 应用的焦点就是 store(堆栈)。“store”根本上就是一个容器,它包罗着你的应用中大部门的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

[*]Vuex 的状态存储是相应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
[*]你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具资助我们更好地相识我们的应用。
安装vuex:npm install vuex@next --save
vuex中的几个焦点概念:


[*]state:状态对象,集中定义各个组件共享的数据
[*]mutations:雷同于一个事件,用于修改共享数据,要求必须是同步函数
[*]actions:雷同于mutation,可以包罗异步操纵,通过调用mutation来改变共享数据
3.2 利用方式

本章节通过一个案例来学习vuex的利用方式,具体操纵步骤如下:
第一步:创建带有vuex功能的前端项目
https://i-blog.csdnimg.cn/blog_migrate/092da797034d5f1117855d0bb3cfb89e.png
注:在创建的前端工程中,可以发现主动创建了vuex相干的文件(src/store/index.js),并且在main.js中创建Vue实例时,需要将store对象传入,代码如下:
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
store,//使用vuex功能
render: h => h(App)
}).$mount('#app')
第二步:在src/store/index.js文件中集中定义和管理共享数据
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

//集中管理多个组件共享的数据
export default new Vuex.Store({
//集中定义共享数据
state: {
    name: '未登录游客'
},
getters: {
},
//通过当前属性中定义的函数修改共享数据,必须都是同步操作
mutations: {
},
//通过actions调用mutation,在actions中可以进行异步操作
actions: {
},
modules: {
}
})
第三步:在视图组件中展示共享数据
<template>
<div class="hello">
    <h1>欢迎你,{{$store.state.name}}</h1>
</div>
</template>
注:$store.state为固定写法,用于访问共享数据
第四步:在mutations中定义函数,用于修改共享数据
//通过当前属性中定义的函数修改共享数据,必须都是同步操作
mutations: {
    setName(state,newName) {
      state.name = newName
    }
},
第五步:在视图组件中调用 mutations 中定义的函数
https://i-blog.csdnimg.cn/blog_migrate/bb855c287b259d3ce1ba4b3e862a886d.png
注:mutations中定义的函数不能直接调用,必须通过状态对象的 commit 方法来调用
第六步:如果在修改共享数据的过程中有异步操纵,则需要将异步操纵的代码编写在actions的函数中
//通过actions调用mutation,在actions中可以进行异步操作
actions: {
    setNameByAxios(context){
      axios({ //异步请求
      url: '/api/admin/employee/login',
      method: 'post',
      data: {
          username: 'admin',
          password: '123456'
      }
      }).then(res => {
      if(res.data.code == 1){
          //异步请求后,需要修改共享数据
          //在actions中调用mutation中定义的setName函数
          context.commit('setName',res.data.data.name)
      }
      })
    }
},
注:在actions中定义的函数可以声明context参数,通过此参数可以调用mutations中定义的函数
第七步:在视图组件中调用actions中定义的函数
https://i-blog.csdnimg.cn/blog_migrate/ff70b05a37b1e3ad3a631fa6dbf28054.png
注:在actions中定义的函数不能直接调用,必须通过 this.$store.dispatch(‘函数名称’) 这种方式调用
4. TypeScript

4.1 TypeScript 先容



[*]TypeScript(简称:TS) 是微软推出的开源语言
[*]TypeScript 是 JavaScript 的超集(JS 有的 TS 都有)
https://i-blog.csdnimg.cn/blog_migrate/0b3a2bc6fcf0cb58deacfee384ae9bc8.png


[*]TypeScript = Type + JavaScript(在 JS 基础上增长了范例支持)
[*]TypeScript 文件扩展名为 ts
[*]TypeScript 可编译成标准的 JavaScript,并且在编译时举行范例查抄
https://i-blog.csdnimg.cn/blog_migrate/4e7e5b0dc9edbe219543e14cecd426f4.png
在前端项目中利用TS,需要举行安装,命令为:npm install -g typescript
查看TS版本:
https://i-blog.csdnimg.cn/blog_migrate/9172342cc8a7a202e22d4f0ccd5e17aa.png
TS初体验:

[*]创建 hello.ts 文件,内容如下:
//定义一个函数 hello,并且指定参数类型为string
function hello(msg:string) {
      console.log(msg)
}

//调用上面的函数,传递非string类型的参数
hello(123)

[*]利用 tsc 命令编译 hello.ts 文件
https://i-blog.csdnimg.cn/blog_migrate/45edac7e575a38267ef0794e36d5d8f5.png
可以看到编译报错,提示参数范例不匹配。这说明在编译时TS会举行范例查抄。需要注意的是在编译为JS文件后,范例会被擦除。
思考:TS 为什么要增长范例支持 ?


[*]TS 属于静态范例编程语言,JS 属于动态范例编程语言
[*]静态范例在编译期做范例查抄,动态范例在实行期做范例查抄
[*]对于 JS 来说,需要等到代码实行的时候才能发现错误(晚)
[*]对于 TS 来说,在代码编译的时候就可以发现错误(早)
[*]配合 VSCode 开辟工具,TS 可以提前到在编写代码的同时就发现代码中的错误,减少找 Bug、改 Bug 的时间
在前端项目中利用TS,需要创建基于TS的前端工程:
https://i-blog.csdnimg.cn/blog_migrate/3d1ee1d0a2c28eb45dffd39f4b360c4e.png
https://i-blog.csdnimg.cn/blog_migrate/0805dd787baa26f3e4204be64c9bc76e.png
4.2 TypeScript 常用范例

TS中的常用范例如下:
范例例备注字符串范例string数字范例number布尔范例boolean数组范例number[],string[], boolean[] 依此类推任意范例any相称于又回到了没有范例的时代复杂范例type 与 interface函数范例() => void对函数的参数和返回值举行说明字面量范例“a”|“b”|“c”限制变量或参数的取值class 类class Animal 4.2.1 范例标注的位置

基于TS举行前端开辟时,范例标注的位置有如下3个:


[*]标注变量
[*]标注参数
[*]标注返回值
https://i-blog.csdnimg.cn/blog_migrate/46b385e90c91df526267b467bb9e37d4.png
4.2.2 字符串、数字、布尔范例

字符串、数字、布尔范例是前端开辟中常用的范例
https://i-blog.csdnimg.cn/blog_migrate/6f87f7d855d923283999b55f2f921e48.png
4.2.3 字面量范例

字面量范例用于限定命据的取值范围,雷同于java中的枚举
https://i-blog.csdnimg.cn/blog_migrate/f34c7b1091d8e3424c11d7c03b2d249c.png
4.2.4 interface 范例

interface 范例是TS中的复杂范例,它让 TypeScript 具备了 JavaScript 所缺少的、描述较为复杂数据结构的本领。
https://i-blog.csdnimg.cn/blog_migrate/9dd81fd91e58fa625e0df420660d9809.png
可以通过在属性名后面加上?,表示当前属性为可选,如下:
https://i-blog.csdnimg.cn/blog_migrate/f01af9bc7dfdf46fc98629426ef74fd5.png
4.2.5 class 范例

利用 class 关键字来定义类,类中可以包罗属性、构造方法、普通方法等
https://i-blog.csdnimg.cn/blog_migrate/6f417725f89fabafb0c84a34efb80b99.png
在定义类时,可以利用 implments 关键字实现接口,如下:
https://i-blog.csdnimg.cn/blog_migrate/e3932051e08f8dc29829a731a4b38c1f.png
在定义类时,可以利用 extends 关键字 继承其他类,如下:
https://i-blog.csdnimg.cn/blog_migrate/686ea6e9f4d8e87275416f98bb62becd.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 苍穹外卖-day13(vue基础回顾+进阶):vue基础(脚手架、根本语法,axios,