苍穹外卖-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(店铺的营业状态) 指定configaxios.get('/api/admin/shop/status',{//这个请求需要携带jwt的令牌地址才能正确访问,复制上面发送post请求调用登录接口生成的令牌地址headers: { //指定config,在请求头里追加参数tokentoken: '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', //默认是getdata: { //data表示通过请求体传参 username: 'admin',password: '123456'}}).then(res => {//成功回调console.log(res.data.data.token) //res.data:返回的result对象,里面包含data,data中又包含tokenaxios({ //在成功的回调函数里又发送一个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里
- 在路由文件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
- 在视图组件App.vue入口页面文件中配置 router-link标签,用于生成超链接
<router-link to="/">Home</router-link> | <!-- 路由链接组件生成超链接 --><router-link to="/about">About</router-link>
- 在视图组件汇总配置router-view标签:占位符,视图渲染到的位置
- 效果:可以来回切换
要实现路由跳转,可以通过标签式和编程式两种:
- 标签式:
<router-link to="/about">About</router-link>
- 通过router-link标签生成超链接实现跳转
- 编程式:
this.$router.push('/about')
- 通过js代码实现跳转
- 通过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 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 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 = falsenew 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初体验:
- 创建 hello.ts 文件,内容如下:
//定义一个函数 hello,并且指定参数类型为string
function hello(msg:string) {console.log(msg)
}//调用上面的函数,传递非string类型的参数
hello(123)
- 使用 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 关键字 继承其他类,如下:
相关文章:
苍穹外卖-day13:vue基础回顾+进阶
vue基础回顾进阶 课程内容 VUE 基础回顾路由 Vue-Router状态管理 vuexTypeScript 1. VUE 基础回顾 1.1 基于脚手架创建前端工程 1.1.1 环境要求 要想基于脚手架创建前端工程,需要具备如下环境要求: node.js 前端项目的运行环境 学习web阶段已安…...
蓝桥杯/慈善晚会/c\c++
问题描述 热心公益的G哥哥又来举办慈善晚会了,这次他邀请到了巴菲特、马云等巨富,还邀请到了大V、小C等算法界泰斗。晚会一共邀请了n位尊贵的客人,每位客人都位于不同的城市,也就是说每座城市都有且仅有一位客人。这些城市的编号为…...
2024.3.19
思维导图...
【Python】新手入门学习:详细介绍单一职责原则(SRP)及其作用、代码示例
【Python】新手入门学习:详细介绍单一职责原则(SRP)及其作用、代码示例 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyT…...
【DataWhale学习笔记】使用AgentScope调用qwen大模型
AgentScope AgentScope介绍 AgentScope是一款全新的Multi-Agent框架,专为应用开发者打造,旨在提供高易用、高可靠的编程体验! 高易用:AgentScope支持纯Python编程,提供多种语法工具实现灵活的应用流程编排ÿ…...
【C++】手撕AVL树
> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:能直接手撕AVL树。 > 毒鸡汤:放弃自…...
探索 TorchRe-ID--基于 Python 的人员再识别库
导言 人员再识别(re-ID)是计算机视觉中的一项重要任务,在监控系统、零售分析和人机交互中有着广泛的应用。TorchRe-ID 是一个功能强大、用户友好的 Python 库,它为人员再识别任务提供了一套全面的工具和模型。在本文中࿰…...
鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Flex)
以弹性方式布局子组件的容器组件。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。Flex组件在渲染时存在二次布局过程,因此在对性能有严格要求的场景下建议使用Column、Row代替。Flex组…...
tmux最基础的一点应用-不用一直挂着ssh,可以干点别的事情
文章目录 使用原因基础命令创建一个窗口退出当前窗口重新进入万一忘记了环境名字想要删除环境 使用原因 跑程序要很久,需要干别的事情,电脑不能一直开,可以使用tmux来管理。 基础命令 创建一个窗口 tmux new -s <你自己起的环境名字&g…...
Java推荐算法——特征加权推荐算法(以申请学校为例)
加权推荐算法 文章目录 加权推荐算法1.推荐算法的简单介绍2.加权推荐算法详细介绍3.代码实现4.总结 1.推荐算法的简单介绍 众所周知,推荐算法有很多种,例如: 1.加权推荐:分为简单的特征加权,以及复杂的混合加权。主要…...
探索什么便签软件好用,可以和手机同步的便签软件
在信息技术日新月异的今天,各类数字工具已经成为我们生活与工作的重要助手。便签软件作为一种简单却高效的辅助工具,悄然改变着人们的记录习惯与时间管理方式。而在诸多便签软件中,能够实现手机与电脑同步功能的产品尤显其独特的价值。那么&a…...
字符函数与字符串函数
前言 本次博客可以说内容最为多的一次博客,讲解同样很细致大家好好看看 1字符函数 在讲解字符函数时,大家得了解什么是字符吧 普通字符a b c 1 转义字符 \n 换行‘ \t’ 水平制表符\r回车 大家了解即可 在C语言中字符也可以有分类 所以我们先来看看…...
Kubernetes 项目整体布局 el-container
整体布局整体布局 你可能会去敲不同的项目,有很多种平台。那么其实都是可以复用的。唯一不同的就是main里面的内容是不同的,边框架子都是相同的。其实框架是不怎么变化的,变化的是main里面。 src/layout/Layout.vue 这里需要新增一个页面Lay…...
AI赋能写作:AI大模型高效写作一本通
❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。2022年度博客之星评选TOP 10🏆,Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作…...
unraid docker.img扩容
unraid 弹Docker image disk utilization of 99%,容器下载/更新失败 我的版本是6.11.5,docker.img满了导致容器不能更新,遇到同样问题的可以先用docker命令清除一下仓库(当然不一定能清理出来,我已经清理过只清理出来1G多点&…...
Python 实现1~100之间的偶数求和
result0 for i in range(101):if i%20:result result i print(result) 或者 result0 for i in range(2,101,2):result result i print(result)...
Leetcode 387. First Unique Character in a String
Problem Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1. Algorithm Use two lists: one list is used to count the letters in “s”; the other list is the position where the letter first …...
c++ 自己实现一个迭代器
具体代码 /*自定义迭代器的实现 */ #include <iostream> using namespace std; class num {int val; //具体的数字int length; //数字的位数void calculate_length(){if(val/100){ //这个数字只有1位length1;return;}int x10; //这里就是不断重复除直…...
HarmonyOS NEXT应用开发—图片压缩方案
介绍 图片压缩在应用开发中是一个非常常见的需求,特别是在处理用户上传图片时,需要上传指定大小以内的图片。目前图片压缩支持jpeg、webp、png格式。本例中以jpeg图片为例介绍如何通过packing和scale实现图片压缩到目标大小以内。 效果图预览 使用说明…...
深入理解nginx的请求限速模块[下]
目录 3. 源码分析3.1 配置指令3.1.1 limit_req_zone指令3.1.2 limit_req指令3.1.3 limit_req_dry_run指令3.1.4 limit_req_log_level指令3.1.5 limit_req_status指令3.2 模块初始化3.3 请求处理3.3.1 ngx_http_limit_req_handler3.3.1 ngx_http_limit_req_lookup3.3.2 ngx_http…...
王者归位:Kafka控制器组件解析
欢迎来到我的博客,代码的世界里,每一行都是一个故事 王者归位:Kafka控制器组件解析 前言控制器组件简介控制器组件的定义和作用:为什么控制器是分布式系统的核心? 保存了什么数据控制器的指定和切换故障转移控制器故障…...
XmlHttpRequest responseType: ‘stream‘ 图片代理服务器
它是一个存在于原生 XMLHttpRequest 对象中的属性。在 Web API 中,XMLHttpRequest 对象用于发送 HTTP 或 HTTPS 请求到服务器,并接收响应。responseType 属性就是用来指定预期从服务器返回的响应数据的类型。 默认值 responseType的默认值为json&#x…...
手写 UE4中的 TArray
#pragma once #include<iostream> #include<stdexcept> #define CHECK_INDEX_RANGE(Index) if (Index > ElementCount) throw std::out_of_range("索引超出界限")template<typename ElementType> class TArray {typedef unsigned int uint; pri…...
Flink实时写Hudi报NumberFormatException异常
Flink实时写Hudi报NumberFormatException异常 问题描述 在Flink项目中,针对Hudi表 xxxx_table 的 bucket_write 操作由于 java.lang.NumberFormatException 异常而从运行状态切换到失败状态。异常信息显示在解析字符串"ddd7a1ec"为整数时出现了问题。报…...
Dataset与DataLoader、transform
文章目录 1、Dataset2、DataLoader2.1 参数详解2.1.1 num_works2.1.2 pin_memory2.1.3 collate_fn 3、图像增强4、重写transform 1、Dataset 在 PyTorch 中,如果要创建自定义的数据集(Dataset),通常会继承 torch.utils.data.Data…...
海豚调度系列之:认识海豚调度
海豚调度系列之:认识海豚调度 一、海豚调度二、特性三、建议配置四、名次解释 一、海豚调度 Apache DolphinScheduler 是一个分布式易扩展的可视化DAG工作流任务调度开源系统。适用于企业级场景,提供了一个可视化操作任务、工作流和全生命周期数据处理过…...
MateBook 14s 2023款 集显 触屏(HKFG-16)原厂Win11系统
HUAWEI华为MateBook14s笔记本电脑2023款原装Windows11,恢复出厂开箱状态系统下载 适用型号:HKFG-XX、HKFG-16、HKFG-32 链接:https://pan.baidu.com/s/1GBPLwucRiIup539Ms2ue0w?pwdfm41 提取码:fm41 原厂系统自带所有驱动、…...
zookeeper快速入门(合集)
zookeeper作为一个分布式协调框架,它的创建就是为了方便或者简化分布式应用的开发。除了服务注册与发现之外,它还能够提供更多的功能,但是对于入门来说,看这一篇就够了。后续会讲zookeeper的架构设计与原理,比如zookee…...
鸿蒙App开发学习 - TypeScript编程语言全面开发教程(上)
背景 根据鸿蒙官方的说明: ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。因此,在学习ArkTS语言之前&#…...
Java语言: JVM
1.1 内存管理 1.1.1 JVM内存区域 编号 名字 功能 备注 1 堆 主要用于存放新创建的对象 (所有对象都在这里分配内存) jdk1.8之后永久代被替换成为了元空间(Metaspace) 2 方法区(加、常、静、即) 被虚拟机加载的类信息(版本、字段、方法、接口…...
网页设计网站/电商网站建设
这篇文章是一位 女读者 (加粗!太难得)的面试阿里的经历分享,虽然第二面就失败了,但是这样的经历对自己帮助应该还是很大的。下面的一些问题非常具有代表性,部分问题我简单做了修改(有些问题表述的不那么准确)。这些问题对于大家用…...
网站投票怎么做/网络推广属于什么专业
贪心算法入门 一、什么是贪心算法 “贪心算法(greedy algorithm,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义…...
如何用vc做网站/上海培训机构排名
很多易维清软件用户都有这么一个需求:系统不同用户在同一个功能界面可编辑或可浏览的字段信息的权限不同,这个在北京易维清源代码生成器里怎么实现呢? 首先,我得问问为什么要在同一个模块里费劲心思的设置不同权限呢,当…...
高大上的公司网站/搜索引擎优化的方法
本代码为 Springboot vue.js 前后分离 跨域 版本 (权限控制到菜单和按钮)后台框架:springboot2.1.2 mybaitsmaven接口前端页面:html vue.js 形式 jquery ajax 异步跨域 json 格式数据交互 前后分离,前后台分开部署&a…...
网站建设行业动态/搜狗网站收录
Compile,Provided,APK,Test compile,Debug compile,Release compile Compile compile是对所有的build type以及favlors都会参与编译并且打包到最终的apk文件中。 Provided Provided是对所有的build type以及favlors只在…...
网站克隆下来了然后再怎么做/河南网站推广那家好
一、填空题1. 对于一个具有n 个结点的单链表,在已知的结点半p 后插入一个新结点的时间. 复杂度为_____,在给定值为x 的结点后插入一个新结点的时间复杂度为_____。【答案】【解析】第一种情况只需直接修改指针的指向。第二种情况必须从头结点…...