苍穹外卖-day13:vue基础回顾+进阶

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后,可以通过命令行来查看版本号,如下:

在这里插入图片描述

安装 Vue CLI,命令如下:

在这里插入图片描述

1.1.2 操作过程

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

  • 方式一:vue create 项目名称
    • 管理员的方式打开Dos窗口,之后进入到一个非中文目录(这个目录当做我们的VScode工作空间),输入命令vue create vue-demo-1
      在这里插入图片描述

    • 上下键选择vue的版本,这里以vue2为例
      在这里插入图片描述
      在这里插入图片描述

    • 可以看到vue项目创建成功
      在这里插入图片描述
      在这里插入图片描述

  • ​ 方式二:vue ui(推荐)

重点介绍使用 vue ui 命令创建前端工程的过程:

第一步:同样首先以管理员的方式打开命令行窗口,之后切换到一个非中文的目录(这个目录当做我们的VScode工作空间),在命令行输入命令 vue ui,在浏览器ui界面中选择前端工程存放的位置

在这里插入图片描述

在这里插入图片描述

第二步:点击“在此创建新项目”按钮,跳转到创建新项目设置页面。填写项目名称、选择包管理器为npm,点击“下一步”按钮

在这里插入图片描述

第三步:选择 Default(Vue 2),点击"创建项目"按钮,完成项目的创建

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

1.1.3 工程结构

工程目录结构:
在这里插入图片描述

1.1.4 启动前端服务

使用VS Code打开创建的前端工程,启动前端工程:

在这里插入图片描述

访问前端工程:

在这里插入图片描述

注:要停止前端服务,可以在命令行终端使用 ctrl + C

前端项目启动后,服务端口默认为8080,很容易和后端tomcat端口号冲突。如何修改前端服务的端口号?

可以在vue.config.js中配置前端服务端口号:
在这里插入图片描述

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>

在这里插入图片描述

1.2.2 测试准备工作

说明:

  • 当前页面比较乱它自带了很多的数据,为了方便测试效果把数据给它清理一下。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 可以看到页面上还显示一个图片,这是因为当前展示的这个页面并不是直接来自于HelloWorld.Vue组件而是这个App.vue,App.vue组件才是真正的项目入口页面,App.vue页面中又引入了HelloWorld.Vue组件,这个图片是设置在App.vue组件中,此时不想要图片需要到App.vue组件中进行删除。
    在这里插入图片描述
  • 效果
    在这里插入图片描述
1.2.3 文本插值

作用:用来绑定 data 方法返回的对象属性

用法:{{插值表达式}}

示例:

在这里插入图片描述
测试:

代码:
在这里插入图片描述

<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>

效果:
在这里插入图片描述

1.2.4 属性绑定

作用:为标签的属性绑定 data 方法中返回的属性

用法:v-bind:xxx,简写为 :xxx

示例:

在这里插入图片描述
测试:

代码
在这里插入图片描述

效果
在这里插入图片描述

1.2.5 事件绑定

作用:为元素绑定对应的事件

用法:v-on:xxx,简写为 @xxx

示例:

在这里插入图片描述

测试:
代码
在这里插入图片描述

效果
在这里插入图片描述

1.2.6 双向绑定

作用:表单输入项和 data 方法中的属性进行绑定,任意一方改变都会同步给另一方

用法:v-model

示例:

在这里插入图片描述
测试:

代码
在这里插入图片描述

效果:修改输入框的值name会发生变化,点击事件方法修改name的值输入框的值会跟着改变
在这里插入图片描述
在这里插入图片描述

1.2.7 条件渲染

作用:根据表达式的值来动态渲染页面元素

用法:v-if、v-else、v-else-if

示例:

在这里插入图片描述
测试:
代码
在这里插入图片描述

效果
在这里插入图片描述

1.2.8 axios

Axios 是一个基于 promise 的 网络请求库,作用于浏览器和 node.js 中。使用Axios可以在前端项目中发送各种方式的HTTP请求。

安装axios的命令:npm install axios(以管理员的方式打开VScode)

在这里插入图片描述

导入:import axios from 'axios'

在这里插入图片描述

axios 的 API 列表:[ ]代表可选参数,可以有可以没有。

在这里插入图片描述

参数说明:

  • 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提供的统一使用方式示例一(可以发送各种方式的请求):

在这里插入图片描述

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代码:

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

<input type="button" value="发送POST请求" @click="handleSendPOST"/>




    handleSendPOST() {
      //通过axios发送post请求 提供了url  data  没有提供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查看控制台发现报错(发生了跨域)

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

原因:发生了跨域问题,前端的访问端口是7070,后端的是8080,当前是在7070服务中往8080这个端口发送,所以产生了跨域。

解决:需要配置代理

1.2.10 axios 测试:配置跨域----post请求

为了解决跨域问题,可以在 vue.config.js 文件中配置代理

代理的作用:前端发送的请求先请求到代理上,然后由代理进行转发到我们的后台服务,这样就可以解决跨域问题了。

在这里插入图片描述

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

在这里插入图片描述

因为修改的是配置文件所以需要重启前端项目才能生效
在这里插入图片描述

再次发送请求:
在这里插入图片描述
在这里插入图片描述

1.2.11 axios 测试:get请求

HelloWorld.vue代码:

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

<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)
      })
    }, 

对应的店铺营业状态接口:
在这里插入图片描述

首先发送post请求,复制返回的token.
在这里插入图片描述
在这里插入图片描述

刷新页面发送get请求:成功

在这里插入图片描述

1.2.12 axios 测试:通用方式发送请求

axios 统一使用方式:axios(config)

HelloWorld.vue代码:

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

<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次请求都成功发送

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

2. 路由 Vue-Router

2.1 Vue-Router 介绍

vue 属于单页面应用,所谓路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容。

单页面应用:在整个vue应用中,实际上只有一个页面,我们看到的浏览器多个页面其实是一种假象,它是通过页面切换 切换不同的视图组件

现实举例:一块黑板,不同的老师上课把之前老师写的内容删除掉,之后写上自己课的内容。

这个替换的过程就是通过路由来完成的。

在这里插入图片描述

在这里插入图片描述

如上图所示:不同的访问路径,对应不同的页面展示

基于Vue CLI 创建带有路由功能的前端项目:

在vue应用中使用路由功能,需要安装Vue-Router:

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

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

注:创建完带有路由功能的前端项目后,在工程中会生成一个路由文件,如下所示:

在这里插入图片描述

关于路由的配置,主要就是在这个路由文件中完成的。

为了能够使用路由功能,在前端项目的入口文件main.js中,创建Vue实例时需要指定路由对象:

创建完路由项目后自动生成

在这里插入图片描述

启动项目查看效果:点击不同的地址会自动切换页面

在这里插入图片描述

说明:

  • 什么是路由?
    • 根据浏览器访问路径不同,展示不同的视图组件
  • vue应用中如何实现路由?
    • 通过 vue-router 实现路由功能,需要安装js库(npm install vue-router)
    • 刚才之所以没有显示的去安装是因为,在页面上使用了脚手架构建项目并且勾选了路由功能,这样的话在创建这个前端工程时,实际上就会通过这个命令安装所需要的库。
    • 如果是一个老项目使用路由功能,此时需要执行此命令手动安装。

2.2 路由配置

首先了解一下路由组成:

  • VueRouter路由器,根据路由请求在路由视图中动态渲染对应的视图组件
    • 路由器作用:根据路由请求来渲染这个不同的视图
    • 具体渲染哪一个视图组件呢???在路由器中其实会维护一个路由表,它里面保存了映射关系,某一个路由路径对应的那一个视图组件。
  • <router-link>路由链接组件,浏览器会解析成<a>
    • 作用:生成超链接标签的
  • <router-view>路由视图组件,用来展示与路由路径匹配的视图组件
    • 展示某一个视图组件指定的位置,本质是页面中的一个占位符,通过路由去渲染不同的视图组件,视图组件要渲染的就是这个页面<router-view>占位符所在的位置。

在这里插入图片描述
这三部分之间是如何协作的:

  • 点击路由链接组件(超链接)发起路由请求,这个请求会交给路由器处理。
  • 路由器会根据路由路径的不同然后去渲染对应的视图组件
  • 具体渲染到这个路由视图组件 <router-view>这个占位符位置。

具体配置方式:

基于脚手架创建前端项目的时候勾选了路由功能,此时工程中路由的代码已经自动生成好了。

首先在package.json里面加入vue-router:此时就可以在前端项目中使用路由功能了

在这里插入图片描述
然后在main.js入口文件中引入router,这个router来自于index.js文件

在这里插入图片描述

找到router下面有一个index.js,然后在这个文件里引入VueRouter,这个VueRouter来自于node_modules(保存创建好项目之后所依赖的包)中的vue-router里
在这里插入图片描述
在这里插入图片描述

  1. 在路由文件index.js中配置路由路径和视图的对应关系:路由表

在这里插入图片描述

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.[hash].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

  1. 在视图组件App.vue入口页面文件中配置 router-link标签,用于生成超链接
    在这里插入图片描述
      <router-link to="/">Home</router-link> |  <!-- 路由链接组件生成超链接 -->
      <router-link to="/about">About</router-link>
  1. 在视图组件汇总配置router-view标签:占位符,视图渲染到的位置
    在这里插入图片描述
  2. 效果:可以来回切换

在这里插入图片描述

在这里插入图片描述

要实现路由跳转,可以通过标签式和编程式两种:

  • 标签式:<router-link to="/about">About</router-link>
    • 通过router-link标签生成超链接实现跳转
  • 编程式:this.$router.push('/about')
    • 通过js代码实现跳转
      在这里插入图片描述

测试编程式:

代码:
在这里插入图片描述

<input type="button" value="编程式路由跳转" @click="jump"/> <!-- 方法不需要参数的话()可以省略掉 -->


<script>
export default {
  methods: {
    jump() {
      //使用编程路由的方式跳转   具体的路由路径(路由表中配置的路径)
      this.$router.push('/about',()=> {})
    }
  }
}
</script>

效果:点击按钮也能跳转到about页面

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

问题思考:如果用户访问的路由地址不存在,该如何处理?

可以通过配置一个404视图组件,当访问的路由地址不存在时,则重定向到此视图组件,具体配置如下:

index.js文件:路由表
在这里插入图片描述

  /* 只写这一个配置的效果:我们访问到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 -->

在这里插入图片描述

路由请求路径不存在,跳转的页面组件:

在这里插入图片描述

<template>
  <div class="about">
    <h1>您请求的资源不存在</h1>
  </div>
</template>

效果:
在这里插入图片描述

2.3 嵌套路由

嵌套路由:组件内要切换内容,就需要用到嵌套路由(子路由),效果如下:

在App.vue视图组件中有<router-view>标签,其他视图组件可以展示在此

在这里插入图片描述

ContainerView.vue组件可以展示在App.vue视图组件的<router-view>位置

在这里插入图片描述

ContainerView.vue组件进行了区域划分(分为上、左、右),在右边编写了<router-view>标签,点击左侧菜单时,可以将对应的子视图组件展示在此

在这里插入图片描述
总结:

  • 原先是不同的vue组件嵌套到App.vue入口视图组件页面中
  • 现在是不同的子组件先嵌套到ContainerView.vue组件中,ContainerView.vue组件在嵌套到App.vue入口视图组件中。

实现步骤:

第一步:安装并导入 elementui,实现页面布局(Container 布局容器)—ContainerView.vue

安装: elementui
在这里插入图片描述

npm i element-ui -S

在这里插入图片描述
导入: elementui,在 main.js 中写入以下内容:
在这里插入图片描述

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);//全局使用ElementUi

实现页面布局(Container 布局容器)—ContainerView.vue
在这里插入图片描述

<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
在这里插入图片描述

<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 中配置路由映射规则(嵌套路由配置)
在这里插入图片描述

   {
    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 布局容器视图中添加,实现子视图组件展示
在这里插入图片描述

<el-main>
    <router-view/>
</el-main>

第五步:在ContainerView.vue 布局容器视图中添加,实现路由请求
在这里插入图片描述

<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
在这里插入图片描述
点击超链接(http://localhost:8080/#/c/p1)右侧会进行替换组件。
在这里插入图片描述

注意:子路由变化,切换的是【ContainerView 组件】中 <router-view></router-view> 部分的内容

问题思考:

1.对于前面的案例,如果用户访问的路由是 /c,会有什么效果呢?

在这里插入图片描述

2.如何实现在访问 /c 时,默认就展示某个子视图组件呢?

配置重定向,当访问/c时,直接重定向到/c/p1即可,如下配置:

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

redirect :'/c/p1',

效果:
在这里插入图片描述

3. 状态管理 vuex(待定:P177)

3.1 vuex 介绍

  • vuex 是一个专为 Vue.js 应用程序开发的状态管理库
  • vuex 可以在多个组件之间共享数据,并且共享的数据是响应式的,即数据的变更能及时渲染到模板
  • vuex 采用集中式存储管理所有组件的状态

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

安装vuex:npm install vuex@next --save

vuex中的几个核心概念:

  • state:状态对象,集中定义各个组件共享的数据
  • mutations:类似于一个事件,用于修改共享数据,要求必须是同步函数
  • actions:类似于mutation,可以包含异步操作,通过调用mutation来改变共享数据

3.2 使用方式

本章节通过一个案例来学习vuex的使用方式,具体操作步骤如下:

第一步:创建带有vuex功能的前端项目

在这里插入图片描述

注:在创建的前端工程中,可以发现自动创建了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 中定义的函数

在这里插入图片描述

注: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中定义的函数

在这里插入图片描述

注:在actions中定义的函数不能直接调用,必须通过 this.$store.dispatch(‘函数名称’) 这种方式调用

4. TypeScript

4.1 TypeScript 介绍

  • TypeScript(简称:TS) 是微软推出的开源语言
  • TypeScript 是 JavaScript 的超集(JS 有的 TS 都有)

在这里插入图片描述

  • TypeScript = Type + JavaScript(在 JS 基础上增加了类型支持)
  • TypeScript 文件扩展名为 ts
  • TypeScript 可编译成标准的 JavaScript,并且在编译时进行类型检查

在这里插入图片描述

在前端项目中使用TS,需要进行安装,命令为:npm install -g typescript

查看TS版本:

在这里插入图片描述

TS初体验:

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

//调用上面的函数,传递非string类型的参数
hello(123)
  1. 使用 tsc 命令编译 hello.ts 文件

在这里插入图片描述

可以看到编译报错,提示参数类型不匹配。这说明在编译时TS会进行类型检查。需要注意的是在编译为JS文件后,类型会被擦除。

思考:TS 为什么要增加类型支持 ?

  • TS 属于静态类型编程语言,JS 属于动态类型编程语言
  • 静态类型在编译期做类型检查,动态类型在执行期做类型检查
  • 对于 JS 来说,需要等到代码执行的时候才能发现错误(晚)
  • 对于 TS 来说,在代码编译的时候就可以发现错误(早)
  • 配合 VSCode 开发工具,TS 可以提前到在编写代码的同时就发现代码中的错误,减少找 Bug、改 Bug 的时间

在前端项目中使用TS,需要创建基于TS的前端工程:

在这里插入图片描述

在这里插入图片描述

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个:

  • 标注变量
  • 标注参数
  • 标注返回值

在这里插入图片描述

4.2.2 字符串、数字、布尔类型

字符串、数字、布尔类型是前端开发中常用的类型

在这里插入图片描述

4.2.3 字面量类型

字面量类型用于限定数据的取值范围,类似于java中的枚举

在这里插入图片描述

4.2.4 interface 类型

interface 类型是TS中的复杂类型,它让 TypeScript 具备了 JavaScript 所缺少的、描述较为复杂数据结构的能力。

在这里插入图片描述

可以通过在属性名后面加上?,表示当前属性为可选,如下:

在这里插入图片描述

4.2.5 class 类型

使用 class 关键字来定义类,类中可以包含属性、构造方法、普通方法等

在这里插入图片描述

在定义类时,可以使用 implments 关键字实现接口,如下:

在这里插入图片描述

在定义类时,可以使用 extends 关键字 继承其他类,如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/471884.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024普通人如何创业!2024年普通人创业五大热门项目 !五个适合穷人创业项目低成本生意! 2024最适合创业的五大行业! 2024适合上班族的创业

1、减肥减脂 贾玲1年瘦100斤狠狠刺激了减肥人群。用户群体体量极大&#xff0c;瑜伽、减肥、健身都可以切入&#xff0c;可以分享减肥的经历、运动跟练、饮食食谱等。有的一个春节期间就涨粉5000&#xff0c;变现嫁接到高客单的陪练全案。 2、卖随身WiFi 现在网络是共需&#…

Elasticsearch实战:索引阻塞 —— 数据保护的终极武器

文章目录 1、索引阻塞的种类2、什么时候使用阻塞&#xff1f;场景1&#xff1a;进行系统维护场景。场景2&#xff1a;保护数据不被随意更改场景。场景3&#xff1a;优化资源使用的场景。场景4&#xff1a;遵守安全规则场景。 3、添加索引阻塞API4、解除设置 API5、小结6、参考 …

如何在SpringCloud2023中快速集成注册中心

你好&#xff0c;这里是codetrend专栏“SpringCloud2023实战”。欢迎点击关注查看往期文章。 注册中心在前文提到有很多选型&#xff0c;在这里以Spring Cloud Zookeeper为例说明注册中心的集成和使用。 选择Spring Cloud Zookeeper作为注册中心原因如下&#xff1a; 依赖更少…

【3DsMax】UVW展开——以制作牙膏盒为例

效果 步骤 1. 从网上下载牙膏盒贴图&#xff0c;我下载的贴图地址为&#xff08;牙膏盒贴图链接&#xff09; 2. 打开3DsMax&#xff0c;创建一个长方体&#xff0c;设置长宽高分别为180、45、40毫米 打开材质编辑器&#xff0c;点击漫反射后的按钮 双击“位图” 将材质赋予长…

【每日八股】Java基础经典面试题4

前言&#xff1a;哈喽大家好&#xff0c;我是黑洞晓威&#xff0c;25届毕业生&#xff0c;正在为即将到来的秋招做准备。本篇将记录学习过程中经常出现的知识点以及自己学习薄弱的地方进行总结&#x1f970;。 本篇文章记录的Java基础面试题&#xff0c;如果你也在复习的话不妨…

重装系统后鼠标识别不了咋办

不知道大家在重装系统时,有没有遇到过系统重装完成后,鼠标不能使用的情况。在这种情况下,我们要怎么操作电脑解决这个问题呢?今天就跟大家分享重装系统后鼠标识别不了咋办。 一、主板没有设置兼容usb 在重装系统时,如果主板没有设置兼容usb,就会出现鼠标使用不了的现象。…

流畅的 Python 第二版(GPT 重译)(十一)

第二十章&#xff1a;并发执行器 抨击线程的人通常是系统程序员&#xff0c;他们心中有着典型应用程序员终其一生都不会遇到的用例。[…] 在 99%的用例中&#xff0c;应用程序员可能会遇到的情况是&#xff0c;生成一堆独立线程并将结果收集到队列中的简单模式就是他们需要了解…

【Linux】线程预备知识{远程拷贝/重入函数与volatile关键字/认识SIGCHILD信号/普通信号/实时信号}

文章目录 0.远程拷贝1.重入函数与volatile关键字2.认识SIGCHILD信号3.普通信号/实时信号 0.远程拷贝 打包资源&#xff1a;tar czf code.tgz *远程传输&#xff1a;scp code.tgz usr服务器ip:/home/usr/路径解压&#xff1a;tar xzf code.tgz 1.重入函数与volatile关键字 先看…

深度解析 Android 系统属性

目录 Android系统属性 1.属性在哪里&#xff1f; 2.属性长什么样&#xff1f; 3.如何读写属性&#xff1a; 4.属性的作用 属性文件生成过程 如何添加系统属性 1.添加系统属性到 /system/build.prop 2.添加系统属性到 /vendor/build.prop 3.添加系统属性到 /product/b…

cdn尝试(减少打包体积)

如果是vue-cli创造的工程&#xff0c;在build后面加上 --report&#xff0c;就会在dist文件夹下出现report.html用于分析打包后个文件的体积 也可以使用插件&#xff1a; webpack使用webpack-bundle-analyzer进行分析&#xff1b; vite使用rollup-plugin-visualizer进行分析…

论文解读—— 基于边缘梯度方向插值和 Zernike 矩的亚像素边缘检测

论文&#xff1a;《 Subpixel edge detection based on edge gradient directional interpolation and Zernike moment》 地址&#xff1a; http://www.dpi-proceedings.com/index.php/dtcse/article/view/24488 摘要 在本文中&#xff0c;我们提出了一种基于边缘梯度方向插值…

D2587A高压大电流DC-DC,采用TO220T-5L或TO263-5L封装形式

1、概述 D2587A稳压器是专为反激式、升压和正向转换器应用而设计的单片集成电路。该器件提供四种不同的输出电压版本&#xff1a;3.3V、5V、12V 和可调节电压。这些稳压器需要的外部元器件很少&#xff0c;因此具有成本效益&#xff0c;并且易于使用。该电源开关是一款5A NPN器…

介绍5款 世界范围内比较广的 5款 mysql Database Management Tool

介绍5款 世界范围内比较广的 5款 Mysql Database Management Tool 文章目录 介绍5款 世界范围内比较广的 5款 Mysql Database Management Tool前言MySQL Workbench&#xff1a;Navicat Premium&#xff1a;DBeaver Community&#xff1a;HeidiSQL&#xff1a;SQLyog&#xff1a…

每日学习笔记:C++ STL 的无序容器(unordered_set、unordered_map)

定义 特性 能够快速查找元素 操作函数 负载系数 元素个数 / bucket个数 提供哈希函数 提供等价准则 方法一&#xff1a;重写元素的操作符 方法二&#xff1a;自定义函数对象

点云配准:从二维到三维的艺术

点云配准&#xff1a;从二维到三维的艺术 在计算机视觉和机器学习的领域中&#xff0c;配准是一个至关重要的步骤&#xff0c;它涉及到将不同视角或时间点捕获的数据集对齐到同一个坐标系统中。这一过程不仅对二维图像至关重要&#xff0c;而且在三维世界的理解中也发挥着关键作…

Apipost IDEA插件新升级,Apipost Helper上架IDEA插件市场

大家好&#xff01;今天向大家介绍一个非常方便的IDEA插件——Apipost Helper&#xff01;相信很多使用过Apipost的朋友在开发过程中都希望能够直接将编写好的API同步至Apipost&#xff0c;而无需手动填写。前段时间&#xff0c;Apipost推出了Apipost IDEA插件的内测版&#xf…

YOLOv4学习

YOLOv4学习 什么是 parameter aggregation&#xff1f;什么是 Skip-connections&#xff1f;正是梯度的反向传播才使得损失函数得以在训练过程中不断优化&#xff0c;以使得模型逐渐学习到“正确的”知识&#xff0c;对吗&#xff1f;什么是Bag-of-Freebies&#xff1f;什么是B…

LLM—Transformer作用及信息流

一、Transformer的作用 Transformer架构的精髓在于其创新性地采用了编码器与解码器的堆叠设计&#xff0c;这一设计巧妙地融合了多头自注意力机制&#xff08;Multi-Head Attention&#xff09;和位置前馈网络&#xff08;Position-wise Feed Forward Network&#xff09;两大核…

LeetCode:2312. 卖木头块(DP Java)

目录 2312. 卖木头块 题目描述&#xff1a; 实现代码与解析&#xff1a; dp 原理思路&#xff1a; 2312. 卖木头块 题目描述&#xff1a; 给你两个整数 m 和 n &#xff0c;分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices &#xff0c;其中 prices[…

LLM之RAG实战(三十二)| 使用RAGAs和LlamaIndex评估RAG

在之前的文章中&#xff0c;我们介绍了RAG的基本流程和各种优化方法&#xff08;query重写&#xff0c;语义分块策略以及重排序等&#xff09;。那么&#xff0c;如果发现现有的RAG不够有效&#xff0c;该如何评估RAG系统的有效性呢&#xff1f; 在本文中&#xff0c;我们将介绍…