一. 为什么学 typescript
var 三大框架都是用 ts 写的,做个类比,如果你不晓得阿拉伯数字和加减法,怎么解应用题?同理不会 ts 如何应用 vue 开发工作我的项目?
二. 开发环境筹备
1. 装置 node,https://nodejs.org/en/, 下载安装,一路默认下一步,输出 node - v 显示版本胜利
2. 装置 ts,npm install -g typescript
, 输出 tsc - v 显示版本 阐明胜利
3. 装置 vscode https://code.visualstudio.com/
三. 新建一个 Helloworld 文件夹,用 vscode 关上,而后新建 app.ts, 外面就写一句
console.log('hello world')
而后在 vscode 终端输出 tsc app.ts,如果报错 先输出 set-ExecutionPolicy RemoteSigned
最初看到生成一个编译同名 app.js 阐明胜利了。你说我想看看打印成果,整个 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="app.js"></script>
</head>
<body>
</body>
</html>
console.log('hello world')
改成 console.log('真香')
终端按上箭头,从新 tsc app.ts,看浏览器控制台,能看到真香。
三、typescript 基础知识
1. 模块治理
传统教程该讲数据类型了,咱们先放放间接将外围的模块治理,因为根底的数据类型 number string 不讲你也会,高级的数据类型讲到了当初你也不明确怎么用。就说一件事,ts 下怎么定义各种数据类型省的遇见 ts 外面类型报错,你就懵圈了,这里跟 js 是不一样的。
就简要提一嘴,常见的就是定义数组:
let num = 0;
let str = '彬哥好帅';
// 下面的没区别,上面说不一样的
//js 这么写是没问题的:// 定义数组,第一种:let person: string[] = ['张三', '帅彬'];
// 第一种有个毛病,比方我要解决一个数组过程中 split 的时候,可能会呈现,[1,'张三',2,'帅彬'],这样你定义成 string 就报错两种类型
let worker: [number, string] = [1, "张三",2,"帅彬"];
// 记住以上两种数组就够用了,接下来咱们说说数组外面套对象{},这个最罕用,以前咱们在 js 下定义一个数组含对象
//js 下
let worker = [{1, "张三"},
{2, "帅彬"}
];
//ts 下 这样写
interface Worker {
id: number;
name: string;
}
let worker: Worker[] = [{ id: 1, name: "张三"},
{id: 2, name: "帅彬"}
];
// 你在我的项目中很可能遇到一种状况就是你通过对象的 key 的值去索引对象的 value, 比方 worker[// 这里是什么也可能是动静的变量],// 这种状况怎么定义?interface Worker {
id: number;
[key: string]: string;// 要害是这一句,前面你甭管它叫啥只有是 string 类型编译就不错
}
let worker: Worker[] = [{ id: 1, name: "张三"},
{id: 2, jobName: "帅彬"}
];
最初一句,数据类型你不晓得也不要用 any,不要用 any, 不要用 any,因为往往报 any 的时候,意味着你代码写的有问题。
咱们回到 vue 中立即就要会用到的模块治理,也就是组件。
咱们先定义一个组件,你叫一个文件也好,一个模块也好不必管它叫啥,反正就这么个玩意,就叫 mod1.ts
各个文件外面代码是这样子的:
//mod1.ts
// 我定义了一个 a 并导出
export let a = 12;
//app.ts
// 因为我定义的是 a 所以导入的名字也必须跟 mod1.ts 外面的统一,也得是 a 还得用花括号括起来,另外 mod1 门路用./ 同级 mod1 不必加后缀
import {a} from './mod1'
console.log(a);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>
index.html 留神一下几点:
1.script type=”module” 必须写
2. 要扔到 body 外面
3. 要想反对 import 和 export 必须用服务器环境相似这样 http://localhost/HelloWorld/,能够轻易装个 wamp 之类的而后扔到 www 文件夹下
4. 这些都记不住也没事依照我说的做即可,我只是阐明 mod1.ts 和 app.ts 外面的内容,这两个文件内容是外围
vscode 终端输出:
tsc --module ES2015 app.ts
这个命令也不必记,就是为了让程序跑起来,咱们持续外围,批改下 mod1.ts
export let a = 12; //mod1.ts// 我定义了一个 a 并导出 export let a = 12;
每次改货色 tsc 太吃力,咱们用监督命令,仍然不必记,只看文件中源码即可,用了这个命令你就不必管 tsc 了,改变主动变
tsc --w --module ES2015 app.ts mod1.ts
批改 mod1.ts
export let a = 12;
export let b = 5;
export let c = 8;
批改 app.ts
import {a,b,c} from './mod1'
console.log(a,b,c);
浏览器控制台,呈现 12,5,8, 大家看从 mod1 外面导入了三个 mod1 中导出的,a,b,c 等导出的名字太多了记不住怎么办?我也不想去 mod1.ts 外面去找导出的叫什么名字,那就不记了,间接批改 app.ts,这样都被我放到了 arrAbc 数组里
import * as arrAbc from './mod1'
console.log(arrAbc.a,arrAbc.b,arrAbc.c);//12,5,8
你说 我想默认一个导出,也不想记名字,怎么办?
批改 mod1.ts
let a = 666;
export default a;
export let b = 5;
export let c = 8;
批改,app.ts
// import * as arrAbc from './mod1'
// console.log(arrAbc.a,arrAbc.b,arrAbc.c);
import numA from './mod1'
import{b,c} from './mod1'
console.log(numA,b,c);
刷浏览器,呈现 666,12,5,8
总结一下:
1. 通过 export default 形式导入,在导入时不须要加 {} 在一个文件或模块中, 名字轻易起,比方 numA
2.export default 只能有一个 export default 前面不能跟 const 或 let 的关键词
export default 一个文件只能有一个
对了,你不定义名字都没事,比方,批改 mod1.ts
let a = 666;
export default {
"name":"大彬哥",
"age":18
};
export let b = 5;
export let c = 8;
批改 app.ts
import teacher from './mod1'
console.log(teacher.name,teacher.age);
刷浏览器,后果就进去了,大彬哥 18,这种形式 vue 中用的最多
2. 类型定义(vue 用到再说)
总结,到这里你就彻底明确了 vue 中 import 了或者 export 什么 import * as 什么的。就有了写组件或者援用他人库的根底。有了这个根底咱们就能够做应用题了,咱们装上 Vue 最新版,看看还有啥用不明确的。
四、vue 基础知识
一、咱们怎么创立 vue 我的项目?
npm create vite@latest
你不必管下面 vite 不 vite,你就依照这个命令跑一把梭,而后你就会看到,
咱们从 index.html 看,有这么一句,
<script type="module" src="/src/main.ts"></script>
是不是咱们方才说的模块治理的货色?顺藤摸瓜,看看 main.ts
import {createApp} from 'vue'
import './style.css'
import App from './App.vue'
createApp(App).mount('#app')
引入了 vue 模块下的 createApp,还有其它一堆,显著咱们当初只关怀
import App from './App.vue'
持续顺藤摸瓜,App.vue,仍然是三段论,script、template、style
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo" alt="Vite logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<HelloWorld msg="Vite + Vue" />
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
}
.logo:hover {filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
外围就两句话,第一句:
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>
这里引入了一个组件,setup 是啥你也不必管,反正你晓得引入了 HelloWorld.vue 就 OK(前面我会讲),而后是
<HelloWorld msg="Vite + Vue" />
给 HelloWorld 的 msg 属性服了一个 ”Vite + Vue” 的值,再致力一下就到底了!看看 components 外面的 HelloWorld 组件,敲黑板划,重点来了:
<script setup lang="ts">
import {ref} from "vue";
defineProps<{msg: string}>();
const count = ref(0);
</script>
<template>
<h1>{{msg}}</h1>
<div class="card">
<button type="button" @click="count++">count is {{count}}</button>
</div>
</template>
<style scoped>
.read-the-docs {color: #888;}
</style>
当然咱们写我的项目不可能这么简略,更多状况下是一个父组件通过数组迭代子组件,就像上面这样,App.vue 外面:
<script setup lang="ts">
import {ref} from "vue";
import HelloWorld from './components/HelloWorld.vue'
const fatherItems = ref([{ id: 1, title: "春天", content: "我把裤衩一脱,春姑娘就来了"},
{id: 2, title: "夏天", content: "我把短裤一穿,夏姑娘就来了"}
])
</script>
<template>
<HelloWorld v-for="item in fatherItems" :key="item.id" :title="item.title" :content="item.content" />
</template>
<style scoped>
</style>
Helloword.vue
<script setup>
defineProps(["title","content"]);
</script>
<template>
<h4>{{title}}</h4>
<p>{{content}}</p>
</template>
展现成果如下:
好了,到这咱们做我的项目就够用,整太简单就懵逼了。接下来咱们就间接撸我的项目。
五、开始撸我的项目
1. 看看市场需求文档
咱们看看需要文档,bula,bula 一堆,我看到的是:
第一个问题:我为什么要开发霍兰德职业趣味测试零碎?
1. 手工测试速度太慢(客户和本人),开发着玩玩
2. 值得我做一天搞定
3. 市面上的都须要付费,搞完当前我能够让他人付费说白了就是
想做
能做
值得做第二个问题:要实现什么内容?
性能:https://baike.baidu.com/item/…
翻译翻译:
原理:据趣味的不同,人格可分为研究型
第一步:人分六种,(I)、艺术型(A)、社会型(S)、企业型(E)、传统型(C)、事实型(R)六个维度
第二步:十题一测 每种通过 10 道题测试,最初判断你是哪一种,得出你是什么人格,比方 SEC
第三步:对号入座,依据索引找对应工作
因为是我本人用,所以没什么要说的。然而你要是公司开发,咋说呢,活当然要干的丑陋,然而不好开发的尽量开发之前就砍掉,不论你是利诱还是理由,反正尽可能扼杀需要在摇篮之中,如果额杀不了也要记住,需要上的失误,不要到代码实现层去沟通。
你只是大自然的搬运工,把市场需求搬运给计算机,不必带太多脑子。
2.整个产品文档
原理:据趣味的不同,人格可分为研究型
第一步:人分六种,(I)、艺术型(A)、社会型(S)、企业型(E)、传统型(C)、事实型(R)六个维度
第二步:十题一测 每种通过 10 道题测试,最初判断你是哪一种,得出你是什么人格,比方 SEC
第三步:对号入座,依据索引找对应工作
3.我的项目开发文档
接到市场需求和产品需要文档,我的想法:你们给我圆润的走开,翻滚吧牛宝宝。我不想干活。(简称,滚犊子),既然推不掉就想怎么实现:
在应用 Vue.js 来实现霍兰德职业测试的应用程序时,我思考到的:
1. 筹备问卷: 须要筹备一份问卷,其中蕴含若干个问题,用于测试人的趣味、偏向和人格
特点。(用 ant-design-vue,本场上演就我本人,又不想界面丑爆了)
2. 创立表单: 你须要应用 Vue.js 的模板语法来创立表单,包含问卷中的各个问题和答案选项。
3. 解决表单提交: 当用户实现填写并提交表单时,你须要应用 Vue.js 的办法来解决表单提
交,并计算出测试后果。(用 pinia 状态治理,必定会用到跨组件通信,顺便还能够装下 13)
4. 展现测试后果: 最初,你能够应用 Vue.js 的指令来展现测试后果,并向用户提供倡议的职
业列表。(用个 vue-chartjs 雷达图,用了很屡次很稳固,也是一款装 13 的利器)
以上纯属脑袋中意淫,咳咳,头脑风暴。而后开始写我的项目开发文档。大家认为我是这么想的:
开发思路:
1. 创立 Vue.js 我的项目: 应用 构建工具创立 Vue.js 我的项目。
2. 筹备测试题目和选项: 筹备好测试题目和选项,能够应用数组格局存储。
3. 创立组件: 创立一个测试组件,用于显示测试题目和选项,并解决用户的抉择。
4. 实现组件逻辑: 在组件中实现逻辑,包含显示以后测试题目和选项,解决用户的抉择,计
算测试后果等。
5. 显示测试后果: 应用另一个组件显示测试后果,能够依据测试后果提供倡议的职业。
其实我是这样想的:
1. 有没有现成的开源的我的项目,我改吧改吧完事儿
2. 有没有网上现成的,让我扒一个改吧改吧,能实现完事儿
然而我是一个脱离了低级趣味的人呢,我决定本人实现一个,毕竟我的头发还容许我再折腾一把。顺着方才的开发思路,要实现这个指标我得有三个步骤:
第一步:先整一个 vue 表单组件,可能输出数据,能切换上一题下一题
第二步:把输出数据能装一个数组,实现各种计算,提供给雷达图
第三步:通过雷达图展现数据
想明确了,就一把梭上代码。
别的不说我先用 router 搭一个 三个页面切换的 SPA 利用。首先咱们先在 src>views 下创立三个文件,别离是 Home.vue,CareerTest.vue 和 About.vue
其中 Home.vue 内容如下,其余只是文字不同,略。
<template>
<div>{{msg}}</div>
</template>
<script lang="ts">
import {defineComponent} from "vue";
export default defineComponent({setup() {
// 在 `setup` 办法里申明变量
const msg = "我是 Home 页";
// 将须要在 `<template />` 里应用的变量 `return` 进来
return {msg,};
},
});
</script>
<style scoped>
</style>
留神这里我没有用
<script setup>
const msg = "我是 Home 页";
</script>
<template>
<div>{{msg}}</div>
</template>
这样的语法糖,不写 setup 是规范的写法,两种都写写,大家就都会用了。至于区别也不必特意记,写着写着也就会了。其实你一比照就晓得,无非就是省了 return, 还有不必写 setup 办法,当然还有组件不必注册跟 this 什么的,这些你不必记,记住:
鲁迅说过,只有我的项目中你用不到又不影响你撸我的项目效率和成果的性能,那就是没有用的性能。
配置路由,src>router(src 上面建一个 router 文件夹,上面都这么简写), 上面两个文件 index.vue 和 routes.vue,为什么这么做,因为这样最适宜理论工作架构清晰
其中 index.ts 是路由的入口文件,如果路由很少,那么能够只保护在这个文件里,但对简单我的项目来说,往往须要配置上二级、三级路由,逻辑和配置都放到一个文件的话,太臃肿了。
所以如果我的项目略微简单一些,能够像下面这个构造一样拆分成两个文件:index.ts 和 routes.ts,在 routes.ts 里保护路由树的构造,在 index.ts 导入路由树结构并激活路由,同时能够在该文件里配置路由钩子。
如果我的项目更加简单,例如做一个 Admin 后盾,能够依照业务模块,再把 routes 拆分得更细,例如 game.ts / member.ts / order.ts 等业务模块,再对立导入到 index.ts 文件里。这里我用最新的 router4 写法,传统的写法,这里会报错,你不必放心为什么我这么写,你照猫画 HelloKity 就行了。
//router>index.ts
import {createRouter, createWebHistory} from 'vue-router'
import type {RouteRecordRaw} from 'vue-router'
import routes from './routes';
const router = createRouter({routes,// 外围就这个单词而已别的能够都不必管,这个来自于 routes.vue})
export default router;
别写那些引入 vue 啦 引入 vue-router 等写法,那个是过来式的写法了,她就像你的后任,忘了她吧。彬哥敲代码养你。
咱们再看看 routes.vue 怎么写
import Home from '../views/Home.vue';
import CareerTest from '../views/CareerTest.vue';
import About from '../views/About.vue';
// 有多少路由都能够在这外面配置
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/Career-Test',
name: 'CareerTest',
component: CareerTest
},
{
path: '/about',
name: 'About',
component: About
}
];
export default routes;
咱们搭了三个页面,又配置了路由,总得弄个导航点击能力切换吧,往 App.ts 外面写,
<script setup lang="ts">
</script>
<template>
<div>
<router-link to="/"> 首页 </router-link>
<router-link to="/career-test"> 职业测评 </router-link>
<router-link to="/about"> 对于咱们 </router-link>
<router-view />
</div>
</template>
<style scoped>
</style>
而后,你要再 main.js 上搞事件,就 game over 了。你得告诉整个 SPA 利用,我要全局应用路由,如下:
import {createApp} from 'vue'
import App from './App.vue'
// import './assets/main.css'
import router from './router';
createApp(App).use(router).mount('#app')
页面会报错,因为咱们用了 router 然而没有装啊!
npm create vite@latest
装的是小纯净版本,什么都本人装,本人开发,省的我的项目臃肿。
咱们先整一个 router 装上,官网:https://router.vuejs.org/zh/i…
命令:
npm install vue-router@4
最初,切换好用了
总结一下:
1. 用 components 上面默认的 HelloWorld.vue,在新建的 views 上面另存三个页面,Home、About 和 CareerTest.vue
2. 新建文件夹 router,上面两个文件一个是 index.ts 做入口配置,一个是 routers.vue 专门写门路对应
3.App.vue 上面弄三个 router-link 和一个 router-view,三个链接切换,一个显示。
4.main.ts 外面 import 和 use router。
5. 装置 router
大家留神我是从我的项目角度倒着操作的,个别教程是会通知你先装 router 而后在弄 main.ts,然而那样容易让你懵逼。咱们从性能登程,缺什么补什么,你就明确为什么这么做了。比方当初这么丑爆的 LowB, 你是不是想整个好看的界面?咱们就用 ant-design-vue UI 库造一下。
1. 在四 vue 基础知识的根底上,先装个 ant-design-vue 先搭个架子。
npm i --save ant-design-vue@next
2. 关上官网复制代码,https://2x.antdv.com/componen… 到 App.vue,
<style scoped>
</style>
<template>
<a-layout>
<a-layout-header :style="{position:'fixed', zIndex: 1, width:'100%'}">
<div class="logo" />
<a-menu
theme="dark"
mode="horizontal"
v-model:selectedKeys="selectedKeys"
:style="{lineHeight:'64px'}"
>
<router-link to="/"
><a-menu-item key="1"> 首页 </a-menu-item></router-link
>
<router-link to="/Career-Test"
><a-menu-item key="2"> 职业测评 </a-menu-item></router-link
>
<router-link to="/About"
><a-menu-item key="3"> 对于咱们 </a-menu-item></router-link
>
</a-menu>
</a-layout-header>
<a-layout-content :style="{padding:'0 50px', marginTop:'64px'}">
<a-breadcrumb :style="{margin:'16px 0'}">
<a-breadcrumb-item>Home</a-breadcrumb-item>
<a-breadcrumb-item>List</a-breadcrumb-item>
<a-breadcrumb-item>App</a-breadcrumb-item>
</a-breadcrumb>
<div :style="{padding:'24px', minHeight:'380px'}">
<router-view />
</div>
</a-layout-content>
<a-layout-footer :style="{textAlign:'center'}">
彬哥头发多 ©2022 Created by Leolau
</a-layout-footer>
</a-layout>
</template>
<script lang="ts">
import {defineComponent, ref} from "vue";
export default defineComponent({setup() {
return {selectedKeys: ref<string[]>(["2"]),
};
},
});
</script>
<style>
#components-layout-demo-fixed .logo {
width: 120px;
height: 31px;
background: rgba(255, 255, 255, 0.2);
margin: 16px 24px 16px 0;
float: left;
}
.site-layout .site-layout-background {background: #fff;}
[data-theme="dark"] .site-layout .site-layout-background {background: #141414;}
</style>
显然页面是乱的因为咱们只是装了 antdv 没有应用它,怎么搞?关上 main.ts,引入组件和 css, 而后全局 use 一下。
import {createApp} from 'vue'
import App from './App.vue'
import router from './router';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css'
createApp(App).use(router).use(Antd).mount('#app')// 留神这里我用了两个 use, 没用.use(Antd,router),还是那句话坑我给你屏蔽了你不须要晓得用就好了
刷新,页面如下就鸟了:
这个就是套 Html 的活儿,仔细点就行。
总结,
1. 其实下面的路由配置写法很多,然而我没讲是因为不想减少复杂度同时很多写法都有坑我给屏蔽了你不须要晓得
2. 你是要开发我的项目,不是为了秀技术,知不知道茴香豆的茴字有四种写法不影响你写好文章
到这里,根本的架子打完了,剩下的活无非就是,拉组件,而后写逻辑。接下来咱们先把组件构造搞清楚。
六、整站的组件组织构造
架构解释两点:
1. 为什么我要从 CareerTest 跳到 HollandTest?因为一级导航只想作为 page 页解释阐明和展现,波及业务的跳转到对应的 page,这样业务 page 和组件一体化同时防止了 CareerTest 的臃肿与凌乱
2. 数据和款式别离放到独自的文件夹,同理。尤其是数据这块拆分解决理论我的项目尤其重要,比方这个我的项目 60 个选择题,如果都扔到 components 外面就太臃肿了。也利于将来数据交互与扩大。
啥也不说先撸一个 CareerTest 的界面,咱们应用 antdv 的 cart 组件, 有 UI 库撸代码就是快,间接复制粘贴代码地址:
https://2x.antdv.com/componen… 外面的栅格卡片
<template>
<div class="gutter-example">
<p class="title"> 人格的六种类型 </p>
<p>
霍兰德职业趣味自测(Self-Directed Search)是由美国职业指导专家霍兰德(John
Holland)依据他自己大量的职业咨询教训及其职业类型实践编制的测评工具。霍兰德认为,集体职业趣味个性与职业之间应有一种外在的对应关系。依据趣味的不同,人格可分为研究型(I)、艺术型(A)、社会型(S)、企业型(E)、传统型(C)、事实型(R)六个维度,每个人的性情都是这六个维度的不同水平组合。</p>
<a-row :gutter="[16, 16]" type="flex" justify="center">
<a-col :span="12">
<router-link to="/holland-test"
><a-button type="primary" class="testBtn" block size="large"
> 进入测试零碎 </a-button
>
</router-link>
</a-col>
</a-row>
<div style="padding: 0px 20px 20px 20px">
<a-row :gutter="16">
<a-col :span="8" class="vGap">
<a-card title="事实型(Realistic)" :bordered="false">
<span> 独特特色:</span>
<p>
违心应用工具从事操作性工作,入手能力强,做事手脚灵便,动作协调。偏好于具体任务,不善言辞,做事激进,较为虚心。</p>
</a-card>
</a-col>
<a-col :span="8" class="vGap">
<a-card title="研究型(Investigative)" :bordered="false">
<span> 独特特色:</span>
<p>
思想家而非实干家,抽象思维能力强,求知欲强,肯动脑,善思考,不愿入手。喜爱独立的和富裕创造性的工作。</p>
</a-card>
</a-col>
<a-col :span="8" class="vGap">
<a-card title="艺术型(Artistic)" :bordered="false">
<span> 独特特色:</span>
<p>
有创造力,乐于发明新鲜、不同凡响的成绩,渴望体现本人的共性,实现本身的价值。做事理想化,谋求完满,不重理论。</p>
</a-card>
</a-col>
<a-col :span="8" class="vGap">
<a-card title="社会型(Social)" :bordered="false">
<span> 独特特色:</span>
<p>
喜爱与人来往、一直结交新的敌人、善言谈、违心教诲他人。喜爱关怀社会问题、渴望施展本人的社会作用。</p>
</a-card>
</a-col>
<a-col :span="8" class="vGap">
<a-card title="企业型(Enterprise)" :bordered="false">
<span> 独特特色:</span>
<p>
谋求势力、权威和物质财富,具备领导能力。喜爱竞争、敢冒风险、有野心、抱负。</p>
</a-card>
</a-col>
<a-col :span="8" class="vGap">
<a-card title="传统型(Conventional)" :bordered="false">
<span> 独特特色:</span>
<p>
尊重权威和规章制度,喜爱按计划办事,仔细、有条理,习惯承受别人的指挥和领导,本人不谋求领导职务。</p>
</a-card>
</a-col>
</a-row>
</div>
</div>
</template>
<style scoped>
.gutter-example :deep(.ant-row > div) {border: 0;}
.gutter-box {padding: 5px 0;}
.title {
text-align: center;
font-size: 24px;
font-weight: bold;
}
.ant-card-body span {font-weight: bold;}
.testBtn {
margin: 5px 0;
display: block;
}
.vGap {margin-top: 20px;}
</style>
这里强调两点:
1. 你不管怎么套 UI,你肯定要写成 6 个 card 的反复
<a-col :span="8" class="vGap">
<a-card title="Card title" :bordered="false">
<p>card content</p>
</a-card>
</a-col>
……反复六次
别写成 3 个一组两头加间距,那样后盾一套数据就乱了,容易跟你打起来。我这里是写死的就不从数据外面取了。
2. 我加了一个 vGap 类,不是说你用 UI 库,就不本人搞事件了。别被 UI 库限制住了后果本人不会写改款式了。
到这里大家看到我,整了一个跳转,咱们依照架构图来:
<router-link to="/holland-test">
<a-button type="primary" class="testBtn" block size="large"> 进入测试零碎 </a-button>
而后咱们创立一个 HollandTest.vue 的组件,里用到了 HollandLib 组件 views>HollandTest.vue 文件如下
<script setup lang="ts">
import {Modal} from "ant-design-vue";
import {defineComponent, ref} from "vue";
import {onMounted} from "vue";
import {useRouter} from "vue-router";
import HollandLib from "../components/HollandLib.vue";
const router = useRouter();
onMounted(() => {
Modal.confirm({title: () => "舒适提醒",
okText: () => "开始吧 >>",
cancelText: "我再想想……",
content:
() => ` 测评选项没有对错之分,如果您想对本人有一个实在的认知,请依据本人的理论状况抉择是或否√
本测试题共 60 题,测试工夫为 20 分钟。当初,请找到一个宁静的场合...`,
onCancel() {router.push({ path: "/Career-Test"});
},
});
});
</script>
<template>
<HollandLib />
</template>
这里我用了一个模态确认框,https://2x.antdv.com/componen… 用的是自定义按钮文字的模态框
重点是这句,
const router = useRouter();// 这是新写法 相当于原来的 $router
router.push({path: "/Career-Test"});
点击勾销按钮跳转。另外,定义组件用 setup 语法糖 十分的嗨皮,你不必 return,你就放心大胆的定义各种变量和应用各种组件,剩下的交给 setup.
敲黑板划重点要写外围构造了。
七、外围测试性能实现
<template>
<div>
<a-row type="flex" justify="center" align="middle" class="rowContainer">
<a-col :span="4" class="previous">
<div>
<a-button> 上一题 </a-button>
</div>
</a-col>
<a-col :span="8" class="process">
<div>
<a-progress type="line" :percent="75" :format="() => `12/60`" />
</div>
</a-col>
<a-col :span="4"><div class="timeC">04:33</div></a-col>
</a-row>
<a-row
:gutter="[16, 16]"
type="flex"
justify="center"
align="middle"
class="rowContainer"
>
<a-col class="gutter-row" :span="16">
<div class="gutter-box">
<a-card title="1. 我喜爱把一件事件做完后再做另一件事。">
<a-button
size="large"
block
class="yesBtn"
@click="nextQuestion(' 是 ')"
> 是 </a-button
>
<a-button size="large" block @click="nextQuestion(' 否 ')"
> 否 </a-button
>
</a-card>
</div>
</a-col>
</a-row>
</div>
</template>
<script setup>
</script>
<style scoped>
.gutter-box {margin-top: 10px;}
.ant-card {padding: 30px;}
.previous {text-align: left;}
.process {min-height: 35px;}
.timeC {text-align: right;}
.yesBtn {margin: 10px 0;}
</style>
对于怎么套页面我就不多墨迹,你看就明确了,咱们核心在性能上。
1. 测评页套数据
将数据处理完而后套到 card 上,data>QuestionsData.ts
当初 QuestionsData.ts 是这样的:
export const quesStr = `
1、我喜爱把一件事件做完后再做另一件事。2、在工作中我喜爱单独策划,不愿受他人干预。……
`;
这里留神市场给你的是 word 文档,你须要记事本透一下格局,第二千万别本人一个个写数组,容易把本人写死。也别要求需求方依照你的格局给你数据,那是你的事件跟人家没有半毛钱关系,过分要求他人做不该人家干的事儿,容易被怼死或者打死。
还有就是能不必数据库就别搞太简单,一是为了响应速度,第二是为了开发速度够用就好。
当下咱们只有解决成
['1、我喜爱把一件事件做完后再做另一件事。',
'2、在工作中我喜爱单独策划,不愿受他人干预'。]
的模式,留神每一个问题前面有不定数量空格须要解决
代码也很简略一句话:
let questArrr = quesStr.split('\n').map(s => s.trim()).filter(s => s);
// 定义一个响应式数组 questions 来提供卡片内容
let questions = reactive(questArrr);
而后在模板外面套 questions[0]就能够了,代码如下:
<template>
<div>
<a-row type="flex" justify="center" align="middle" class="rowContainer">
<a-col :span="4" class="previous">
<div>
<a-button> 上一题 </a-button>
</div>
</a-col>
<a-col :span="8" class="process">
<div>
<a-progress type="line" :percent="75" :format="() => `12/60`" />
</div>
</a-col>
<a-col :span="4"><div class="timeC">04:33</div></a-col>
</a-row>
<a-row
:gutter="[16, 16]"
type="flex"
justify="center"
align="middle"
class="rowContainer"
>
<a-col class="gutter-row" :span="16">
<div class="gutter-box">
<a-card :title="questions[0]">
<a-button
size="large"
block
class="yesBtn"
@click="nextQuestion(' 是 ')"
> 是 </a-button
>
<a-button size="large" block @click="nextQuestion(' 否 ')"
> 否 </a-button
>
</a-card>
</div>
</a-col>
</a-row>
</div>
</template>
<script setup>
import {quesStr} from "../data/QuestionsData";
import {ref, reactive} from "vue";
let questArrr = quesStr
.split("\n")
.map((s) => s.trim())
.filter((s) => s);
// 定义一个响应式数组 questions 来提供卡片内容
let questions = reactive(questArrr);
</script>
<style scoped>
.gutter-box {margin-top: 10px;}
.ant-card {padding: 30px;}
.previous {text-align: left;}
.process {min-height: 35px;}
.timeC {text-align: right;}
.yesBtn {margin: 10px 0;}
</style>
接下来要实现上一题下一题,还有把你抉择的后果用一个 resArr 数组接管,为计算最终后果给雷达图做筹备。代码如下:
<template>
<div>
<a-row type="flex" justify="center" align="middle" class="rowContainer">
<a-col :span="4" class="previous">
<div>
<a-button @click="previousQuestion"> 上一题 </a-button>
</div>
</a-col>
<a-col :span="8" class="process">
<div>
<a-progress type="line" :percent="75" :format="() => `12/60`" />
</div>
</a-col>
<a-col :span="4"><div class="timeC">04:33</div></a-col>
</a-row>
<a-row
:gutter="[16, 16]"
type="flex"
justify="center"
align="middle"
class="rowContainer"
>
<a-col class="gutter-row" :span="16">
<div class="gutter-box">
{{resArr}}
<a-card :title="questions[curIndex]">
<a-button
size="large"
block
class="yesBtn"
@click="nextQuestion(' 是 ')"
> 是 </a-button
>
<a-button size="large" block @click="nextQuestion(' 否 ')"
> 否 </a-button
>
</a-card>
</div>
</a-col>
</a-row>
</div>
</template>
<script setup lang="ts">
import {quesStr} from "../data/QuestionsData";
import {ref, reactive} from "vue";
let questArrr = quesStr
.split("\n")
.map((s) => s.trim())
.filter((s) => s);
// 定义一个响应式数组 questions 来提供卡片内容
let questions = reactive(questArrr);
// 点击任意一个选项就是下一题
// 定义一个题号 index
let curIndex = ref(0);
// 定义一个抉择后果的数组
const resArr = ref([] as any[]);
function nextQuestion(answer: any) {resArr.value.splice(curIndex.value, 1, answer);
curIndex.value++;
if (curIndex.value == questions.length) {curIndex.value = questions.length - 1;}
}
function previousQuestion() {
curIndex.value--;
if (curIndex.value == -1) {alert("第一题");
curIndex.value = 0;
}
}
</script>
<style scoped>
.gutter-box {margin-top: 10px;}
.ant-card {padding: 30px;}
.previous {text-align: left;}
.process {min-height: 35px;}
.timeC {text-align: right;}
.yesBtn {margin: 10px 0;}
</style>
成果如下:
解决一下上一题,第一题就没必要显示上一题了,
<a-button v-if="curIndex > 0" @click="previousQuestion"> 上一题 </a-button>
最初一题,提醒是否提交的模态框
import {Modal} from "ant-design-vue";
function showCompop() {
Modal.confirm({title: () => "舒适提醒",
okText: () => "提交",
cancelText: "勾销",
content: () => ` 祝贺你所有问题曾经实现,确认提交查看后果吗?`,
onOk() {
router.push({path: "/result",});
},
onCancel() {router.push({ path: "/holland-test"});
},
});
}
路由跳转还是老办法,就不赘述。另存一个 Result.vue, 在 routes.ts 外面加配置具体如下:
import Home from '../views/Home.vue';
import CareerTest from '../views/CareerTest.vue';
import About from '../views/About.vue';
import HollandTest from '../views/HollandTest.vue';
// 有多少路由都能够在这外面配置
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/Career-Test',
name: 'CareerTest',
component: CareerTest
},
{
path: '/About',
name: 'About',
component: About
},
{
path: '/holland-test',
name: '霍兰德测试',
component: HollandTest
},
{
path: '/result',
name: '测试后果',
component: Result
},
];
export default routes;
1. 后果页套数据
我须要整一个雷达图,而后一段文字说一下测评后果。
npm i vue-chartjs chart.js
而后咱们套一个界面,仍然用 antdv
<template>
<div style="background: #fff; padding: 14px 24px; min-height: 380px">
<a-descriptions
title="职业趣味报告:"
bordered
size="middle"
layout="vertical"
>
<a-descriptions-item
label="您的职业趣味代码是"
:labelStyle="{
textAlign: 'center',
display: 'block',
fontWeight: 'bold',
}":span="1":contentStyle="{textAlign: 'center', display: 'block'}"
>
<div class="codeBox">
<div class="code1">S</div>
<div class="code2">E</div>
<div class="code3">C</div>
<p class="code">SEC</p>
</div>
</a-descriptions-item>
<a-descriptions-item
label="您的各类型占比"
:labelStyle="{
textAlign: 'center',
display: 'block',
fontWeight: 'bold',
}":contentStyle="{textAlign: 'center', display: 'block'}":span="2"
>
<div style="max-width: 350px; margin: 0 auto">
<Radar id="my-chart-id" :data="chartData" />
</div>
</a-descriptions-item>
<a-descriptions-item label="CAS 型适宜的职业" :span="3">
<a-badge
text="厨师、林务员、跳水员、潜水员、染色员、电器修理、眼镜制作、电工、纺织机器装配工、服务员、装玻璃工人"
/>
</a-descriptions-item>
<a-descriptions-item label="状态" :span="1"> 事实型 R </a-descriptions-item>
<a-descriptions-item label="人格偏向" :span="1"
> 喜爱与人来往、一直结交新的敌人、善言谈、违心教诲他人。关怀社会问题、渴望施展本人的社会作用。寻求宽泛的人际关系,比拟看重社会任务和社会道德 </a-descriptions-item
>
<a-descriptions-item label="典型职业" :span="3"
><div class="codeBox"> 工人 农民 土木工程师 </div></a-descriptions-item
>
<a-descriptions-item label="状态" :span="1"> 事实型 R </a-descriptions-item>
<a-descriptions-item label="人格偏向" :span="1"
> 具备抗拒、坦白、虚心、天然、刚毅、理论、有礼、害羞、持重、勤俭的特色,体现为
1、青睐实用性的职业或情境,以从事所爱好的流动,防止社会性的职业或情境
2、用具体理论的能力解决工作及其他方面的问题,较不足人际关系方面的能力。3、器重具体的事物,如金钱,势力、位置等。</a-descriptions-item
>
<a-descriptions-item label="典型职业" :span="3"
><div class="codeBox"> 喜爱要求与人打交道的工作,可能一直结交新的敌人,从事提供信息、启迪、帮忙、培训、开发或医治等事务,并具备相应能力。如: 教育工作者(老师、教育行政人员),社会工作者(征询人员、公关人员)。</div></a-descriptions-item
>
<a-descriptions-item label="状态" :span="1"> 事实型 R </a-descriptions-item>
<a-descriptions-item label="人格偏向" :span="1"
> 具备抗拒、坦白、虚心、天然、刚毅、理论、有礼、害羞、持重、勤俭的特色,体现为
1、青睐实用性的职业或情境,以从事所爱好的流动,防止社会性的职业或情境
2、用具体理论的能力解决工作及其他方面的问题,较不足人际关系方面的能力。3、器重具体的事物,如金钱,势力、位置等。</a-descriptions-item
>
<a-descriptions-item label="典型职业" :span="3"
><div class="codeBox"> 工人 农民 土木工程师 </div></a-descriptions-item
>
<a-descriptions-item
label="舒适提醒"
:labelStyle="{
textAlign: 'left',
display: 'block',
fontWeight: 'bold',
}":contentStyle="{textAlign: 'left'}":span="3"
>
<p>
除了关注得分最高的前三项 CAS,找到适宜本人倒退的职业畛域外,还心愿您也特地关注一下本人最不适宜倒退的职业畛域,即得分最低的那个类型所指向的畛域,防止长时间地在不适宜本人倒退的职业畛域摸索。</p>
</a-descriptions-item>
</a-descriptions>
</div>
</template>
<script setup lang="ts">
import {Radar} from "vue-chartjs";
import {ref, reactive} from "vue";
import {
Chart as ChartJS,
RadialLinearScale,
PointElement,
LineElement,
Filler,
Tooltip,
Legend,
} from "chart.js";
ChartJS.register(
RadialLinearScale,
PointElement,
LineElement,
Filler,
Tooltip,
Legend
);
let chartData = reactive({
labels: [
"研究型(I)",
"艺术型(A)",
"社会型(S)",
"企业型(E)",
"传统型(C)",
"事实型(R)",
],
datasets: [
{
label: "您的各类型占比",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
pointBackgroundColor: "rgba(255,99,132,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(255,99,132,1)",
data: [0, 0, 0, 0, 0, 0],
},
],
});
</script>
<style scoped>
.codeBox {
position: relative;
width: 300px;
}
.code1,
.code2,
.code3 {
width: 100px;
height: 100px;
position: absolute;
border-radius: 50px;
line-height: 100px;
font-size: 40px;
color: #fff;
}
.code {
position: absolute;
color: black;
z-index: 100;
left: 125px;
top: 80px;
font-size: 30px;
}
.code1 {
background: green;
left: 100px;
top: -110px;
}
.code2 {
background: orange;
left: 50px;
top: -25px;
}
.code3 {
background: blue;
left: 150px;
top: -25px;
}
</style>
报告局部用了形容列表 https://2x.antdv.com/componen…
八、数据对接
当初咱们测试选项页能把测试题后果拿到了,而后后果报告页动态页面也进去了,当初最要害的点就来了,
如何将测试后果数组解决成 报告页的数据展现进去。
这里分三步:
1. 把数据传过来
2. 把数据处理成用来展现的
3. 套数据展现
九、状态治理与 pinia
解决第一步数据的时候,咱们须要把数据 components> 从 HollandLib.vue 的 resArr 传到 views>Result.vue 外面。
咱们当然能够用通过向父组件传递数据而后传递给兄弟组件,然而大量数据的时候就很乱了,所以咱们应用的 Vue 状态治理库 pinia。
别墨迹 先装上再说, 官网 https://pinia.vuejs.org/zh/ge…
npm install pinia
关上 main.ts 跟应用 router 和 ant-design-vue 一样。
import {createApp} from 'vue'
import App from './App.vue'
import router from './router';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css'
import {createPinia} from 'pinia'
const pinia = createPinia()
createApp(App).use(router).use(Antd).use(pinia).mount('#app')// 留神这里我用了多个个 use, 没用.use(Antd,router),还是那句话坑我给你屏蔽了你不须要晓得用就好了
装上了就开整,你不要一看到状态治理就感觉简单和高大上。其实简略的令人发指。我做个类比你就秒懂。
你家水果能够放厨房柜子里,也能够放客厅冰箱里,你家里好几个人都吃水果,洗衣局部顺手放在水池子边上或者其它两个地位,下一个人吃,就得很麻烦的找来找去。另外你一会拿个香蕉一会拿个苹果忒麻烦了吧。怎么办呢?
你家里就规定了,水果都放在冰箱的保鲜区,用水果篮子洗和放水果吃完都要放回去。
咱们在 src>stores>userCheckStore.ts, 内容如下:
import {defineStore} from 'pinia'
import {reactive} from 'vue'
//defineStore 以冰箱 userCheckStore
export const userCheckStore = defineStore('QueuserChecktionRes', {
// sate 就是保鲜区,resArr 就是苹果、香蕉各种你要拿走的水果(数据),你不必管为啥我用 reactive,你包一层不错,有时候你不包可能就错,所以不必记照着搞就行了
state: () => {
return {resArr: reactive([])
}
},
})
而后咱们在各个组件用 resArr 用它,怎么用 HollandLib.vue 下
import {userCheckStore} from "../stores/userCheckStore";
import {storeToRefs} from "pinia";
const store = userCheckStore();
const {resArr} = storeToRefs(store);
userCheckStore 就是咱们冰箱,store 就是保鲜区,resArr 是苹果,是不是很简略?storeToRefs 是为了响应式数据的,你也不必管是啥,你就包上就完事儿了。反正作为老手,我讲 storeToRefs 包不包的区别意义也不大。下面那段话你想在哪个组件用就在那个组件这么写就行。而后咱们说下怎么把香蕉放回冰箱,也就是批改数据。
store.resArr.splice(curIndex.value, 1, answer);
就跟批改对象没区别留神后面带上 store.resArr(改的是保鲜区里的香蕉,你不能改错了,这样所有组件都能接管到你的批改。
store.name = ‘xxxx’ 这样的模式,因为我玩的是数组,所以 splice 了一下,情理一样。这样做目标是我把每道题的选项上一题的时候能批改成点击的那个值,最初是[][][‘ 是 ’,’ 否 ’,’ 是 ’],这个数组 views>Result.vue 能拿到,就能够计算和嵌套数据了,计算数据这个跟 ts 和 vue3 无关,是原生 js 根底的货色。这里去强调一点要纯熟应用数组、对象和正则解决数据,而嵌套数据就跟咱们后面七、外围测试性能实现嵌套问题卡没区别了。
最初是打包上线,
npm run build
把 dist 文件家里的内容扔到服务器根目录下就能够了。
十、对于开发效率
最初我说一下如何进步开发效率,用框架必定是快,然而前提是原生 js 的语法和算法要很理解,还有逻辑清晰。
比方给大家举个例子:resultData.ts 这个数据是市场部们给的,
export let sixTypeStr = `
1、社会型:(S)
独特特色:喜爱与人来往、一直结交新的敌人、善言谈、违心教诲他人。关怀社会问题、渴望施展本人的社会作用。寻求宽泛的人际关系,比拟看重社会任务和社会道德
典型职业:喜爱要求与人打交道的工作,可能一直结交新的敌人,从事提供信息、启迪、帮忙、培训、开发或医治等事务,并具备相应能力。如: 教育工作者(老师、教育行政人员),社会工作者(征询人员、公关人员)。2、企业型:(E)
独特特色:谋求势力、权威和物质财富,具备领导能力。喜爱竞争、敢冒风险、有野心、抱负。为人求实,习惯以利益得失,权力、位置、金钱等来掂量做事的价值,做事有较强的目的性。典型职业:喜爱要求具备经营、治理、劝服、监督和领导能力,以实现机构、政治、社会及经济指标的工作,并具备相应的能力。如项目经理、销售人员,营销管理人员、政府官员、企业领导、法官、律师。3、惯例型:(C)
独特特点:尊重权威和规章制度,喜爱按计划办事,仔细、有条理,习惯承受别人的指挥和领导,本人不谋求领导职务。喜爱关注理论和细节状况,通常较为审慎和激进,不足创造性,不喜爱冒险和竞争,富裕自我牺牲精力。典型职业:喜爱要求留神细节、精确度、有零碎有条理,具备记录、归档、据特定要求或程序组织数据和文字信息的职业,并具备相应能力。如:秘书、办公室人员、记事员、会计、行政助理、图书馆管理员、出纳员、打字员、投资分析员。4、理论型:(R)
独特特点:违心应用工具从事操作性工作,入手能力强,做事手脚灵便,动作协调。偏好于具体任务,不善言辞,做事激进,较为虚心。不足社交能力,通常喜爱独立做事。典型职业:喜爱应用工具、机器,须要根本操作技能的工作。对要求具备机械方面能力、膂力或从事与物件、机器、工具、运动器材、动物、动物相干的职业有趣味,并具备相应能力。如:技术性职业(计算机硬件人员、摄影师、制图员、机械装配工),技能性职业(木匠、厨师、技工、修理工、农民、个别劳动)。5、调研型:(I)
独特特点:思想家而非实干家, 抽象思维能力强,求知欲强,肯动脑,善思考,不愿入手。喜爱独立的和富裕创造性的工作。常识渊博,有学识能力,不长于领导别人。思考问题感性,做事喜爱准确,喜爱逻辑剖析和推理,一直探讨未知的畛域。典型职业:喜爱智力的、形象的、剖析的、独立的定向工作,要求具备智力或剖析能力,并将其用于察看、估测、掂量、造成实践、最终解决问题的工作,并具备相应的能力。如科学研究人员、老师、工程师、电脑编程人员、医生、系统分析员。6、艺术型:(A)
独特特点:有创造力,乐于发明新鲜、不同凡响的成绩,渴望体现本人的共性,实现本身的价值。做事理想化,谋求完满,不重理论。具备肯定的艺术能力和共性。长于表白、念旧、心态较为简单。典型职业:喜爱的工作要求具备艺术修养、创造力、表达能力和直觉,并将其用于语言、行为、声音、色彩和模式的审美、考虑和感触,具备相应的能力。不长于事务性工作。如艺术方面(演员、导演、艺术设计师、雕刻家、建筑师、摄影家、广告制作人),音乐方面(歌唱家、作曲家、乐队指挥),文学方面(小说家、诗人、剧作家)。`;
拿到当前多余空格不必管,你用编辑器格式化就全没了,然而空格你必定不能手动删除吧?很多人想都不想间接 split
let resultArr = resultStr.split("\n");
也的确该这么做,然而问题就来了,
这就要求你纯熟的应用数组办法,正则了和字符串操作方法。
还有再解决 sixTypeStr
export let sixTypeStr = `
1、社会型:(S)
独特特色:喜爱与人来往、一直结交新的敌人、善言谈、违心教诲他人。关怀社会问题、渴望施展本人的社会作用。寻求宽泛的人际关系,比拟看重社会任务和社会道德
典型职业:喜爱要求与人打交道的工作,可能一直结交新的敌人,从事提供信息、启迪、帮忙、培训、开发或医治等事务,并具备相应能力。如: 教育工作者(老师、教育行政人员),社会工作者(征询人员、公关人员)。2、企业型:(E)
独特特色:谋求势力、权威和物质财富,具备领导能力。喜爱竞争、敢冒风险、有野心、抱负。为人求实,习惯以利益得失,权力、位置、金钱等来掂量做事的价值,做事有较强的目的性。典型职业:喜爱要求具备经营、治理、劝服、监督和领导能力,以实现机构、政治、社会及经济指标的工作,并具备相应的能力。如项目经理、销售人员,营销管理人员、政府官员、企业领导、法官、律师。3、惯例型:(C)
时候,你 split 完会是这样,
你其实要的是 三个一组,蕴含社会型,独特特色,还有职业。个别人又会去循环解决数组再扔到一个对象里,这样做当然更好更灵便,然而你解决的时候又会波及到又要隔 3 个循环,还有思考数组中对象类型如何对应,比方 S 要对应前三项,E 要对应 456 我的项目,这样又要做一个数组放六种类型……
其实到这里曾经能够用了,你只有找到蕴含字母 S 的,而后下标 +1 + 2 你要的数据就能够嵌套了,一句话搞定。
const index = sixTypeArr.findIndex((item) => item.includes(searchChar[i]));
应用了数组的 findIndex 和 includes 办法,所以大家能够看到,纯熟的应用数组操作可能极大的晋升开发效率与升高代码量。
十一,与需求方和产品沟通与扯皮
很多程序员要跟产品、测试和需求方关系十分缓和,吵架。很大部分起因是没有搞明确程序员是干什么的。
程序员是把需求方的需要准确无误的通知电脑高效的执行,这是最低需要。
比方我测试后果是 ECA,然而并没有 ECA 类型的测试后果与职业匹配对照后果,这个问题第一做好揭示需求方,第二你解决好这种状况的提醒即可。至于你通过威逼利诱砍掉你不想开发的性能那是进阶了,至多你得做到后面这点,你才是一个合格的程序员。
十二,写在最初
1. 程序员不要自嗨,够用就好。
因为这个工具我本人和公司用,另外想通过这个我的项目让大家迅速的可能用 vue3 开发我的项目,而不是卡住大家,所以我省略了很多的细节,比方路由我理论开发的时候应用 v -for 循环的,然而讲的时候,我就间接写死了,因为不想减少大家了解复杂度。
2. 不要手里有锤子,眼里都是钉子
程序是为了实现性能和业务服务,而程序永远不是惟一的实现形式(然而往往是高效的形式),能不必程序就能高效解决,那就不要写程序。
最初奉上效果图:
最初网站展现成果:https://leolau2012.github.io/
对于这个教程 Follow 的过程中,有人任何问题和卡顿,欢送留言或私信。