VuejsによるインタラクティブMatcher
フロントエンドの開発者として新しい仕事に応募するときは、インタビュープロセスのいくつかのレベルからのインタビューといくつかのタスクの任意のタイプを得ることができます.現在、我々は2種類のタスク「多くの人気テスト(インタビュー)タスク」と「人気のないテストタスク」をフロントエンド開発者に持っています.BTW多くの会社は、彼らの会社からのテストタスクがユニークであると思います、そして、彼らはあなたにそれを秘密にしておくよう頼みます、そして、あなたは公共のgithubレポを公表しません.しかし、タスクの検索キーワードは、多くの場合、同じAPIで同じタスクで完全なGitHubパブリックプロジェクトを見つけることができます.それで.この仕事を解決しましょうinteractive matcher Vuejsとのインタビュータスクから、この公共githubrepo .
2つのCVSファイル1で資産フォルダーを作成するこのプロジェクトの中で、私たちは新しいVujsプロジェクトを作成します.
州管理をするために、我々は店をつくります.プロジェクトsrcフォルダ内のJSと以下のコードを追加します.
私はこの記事は、インタビュープロセスを通過するのに役立ちます願っています.
2つのCVSファイル1で資産フォルダーを作成するこのプロジェクトの中で、私たちは新しいVujsプロジェクトを作成します.
州管理をするために、我々は店をつくります.プロジェクトsrcフォルダ内のJSと以下のコードを追加します.
import Vue from "vue";
import Vuex from "vuex";
import recordingsdata from "./assets/sound_recordings.csv";
import inputsdata from "./assets/sound_recordings_input_report.csv";
Vue.use(Vuex);
const appendId = (tempArray) => {
return tempArray.map((item) => ({
id: Math.random().toString().slice(2),
...item,
}));
};
const postRecordingsData = appendId(recordingsdata);
const postInputs = appendId(inputsdata);
export const store = new Vuex.Store({
state: {
// origin
recordings: postRecordingsData,
// left aside list
inputs: postInputs,
// right aside list
results: postRecordingsData,
selectedInputsItem: {},
selectedResultsItem: {},
},
mutations: {
SET_STATE(state, payload) {
Object.keys(payload).forEach((key) => {
if (key in state) {
state[key] = payload[key];
}
});
},
S_INPUT(state, payload) {
state.selectedInputsItem = payload;
},
addInput(state) {
console.log("state.selectedInputsItem:", state.selectedInputsItem);
state.recordings.push(state.selectedInputsItem.item);
state.results.push(state.selectedInputsItem.item)
console.log("state:",state);
},
},
});
と内部アプリ.Vue file以下のコードを追加します.<template>
<div id="app">
<Header />
<div class="container">
<div class="row">
<div class="col-md-5">
<Inputs />
</div>
<div class="col-md-2">
<Actions />
</div>
<div class="col-md-5">
<Database />
</div>
</div>
</div>
</div>
</template>
<script>
import Header from "./components/Header.vue";
import Inputs from "./components/inputs/Inputs.vue";
import Actions from "./components/actions/Actions.vue";
import Database from "./components/database/Database.vue";
export default {
name: "App",
components: {
Header,
Inputs,
Actions,
Database,
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #181c20;
/* margin-top: 60px; */
}
</style>
コンポーネントフォルダで、入力、データベース、およびアクションコンポーネントを作成します.アクションは次のコードを追加します.<template>
<div>
<button class="btn btn-outline-primary" @click="register"><i class="fa fa-arrow-right"></i> Register</button>
</div>
</template>
<style scoped>
</style>
<script>
import { mapMutations } from "vuex";
export default {
methods: {
...mapMutations(["SET_STATE"]),
register() {
console.log("selected:----",this.$store.state.selectedInputsItem);
this.$store.commit('addInput')
},
},
};
</script>
次のようなデータベースコンポーネントコード<template>
<div>
<input type="text" v-model="search" placeholder="Search title.." />
<div>Records: {{ recordings.length }}</div>
<ul class="list-group list-group-flush">
<li class="mt-4" v-for="item in recordings" :key="item.id">
<div class="card">
<div class="card-body">
<h5 style="">{{ item.title }}</h5>
<p>{{ item.artist }}</p>
<div style="display: flex; justify-content: space-between">
<h6>{{ item.isrc }}</h6>
<h6>{{ item.duration | formatTime }}</h6>
</div>
</div>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
search: "",
};
},
computed: {
recordings() {
const searchrg=new RegExp(this.search,'i');
return this.$store.state.results.filter((item) =>
[item.isrc, item.artist, item.title].some((el) =>
el && el.toLowerCase().match(searchrg)
)
);
},
},
filters: {
formatTime(time) {
if (time > 0) {
var mins = ~~((time % 3600) / 60);
var secs = ~~time % 60;
var ret = "";
ret += "0" + mins + "m" + " " + (secs < 10 ? "0" : "");
ret += "" + secs + "s";
return ret;
} else return "";
},
},
methods: {
};
</script>
<style scoped>
ul {
list-style-type: none;
overflow: scroll;
overflow-x: hidden;
height: 80vh;
}
</style>
次のコードを追加します<template>
<ul class="list-group list-group-flush">
<div>Inputs: {{ inputs.length }}</div>
<li class="mt-4" v-for="item in inputs" :key="item.id">
<div class="card " v-bind:class="{isActive:activeItem===item}" @click="findMatch(item)">
<div class="card-body">
<h5 style="">{{ item.title }}</h5>
<p>{{ item.artist }}</p>
<div style="display: flex; justify-content: space-between">
<h6>{{ item.isrc }}</h6>
<h6>{{ item.duration | formatTime }}</h6>
</div>
</div>
</div>
</li>
</ul>
</template>
<style scoped>
ul {
list-style-type: none;
overflow: scroll;
overflow-x: hidden;
height: 80vh;
}
.isActive{
border:18px solid #e19eae ;
}
</style>
<script>
import { mapMutations } from "vuex";
export default {
data() {
return {
activeItem:null
};
},
computed: {
inputs() {
return this.$store.state.inputs;
},
},
methods: {
...mapMutations(["SET_STATE","S_INPUT"]),
findMatch(item) {
console.log(item);
this.activeItem=item;
this.S_INPUT({item});
const targetFields =(item.title.toUpperCase()+' '+item.artist.toUpperCase() +(item.isrc?' ' + item.isrc?.toUpperCase():'')).split(' ');
const t = this.$store.state.recordings.filter((elem) => {
const ele=(elem.title.toUpperCase()+' '+elem.artist.toUpperCase() +' '+elem.isrc?.toUpperCase()).split(' ');
return ele.filter(field=> targetFields.includes(field)).length>0;
this.SET_STATE({
results: t || [],
});
},
},
filters: {
formatTime(time) {
if (time > 0) {
var mins = ~~((time % 3600) / 60);
var secs = ~~time % 60;
var ret = "";
ret += "0" + mins + "m" + " " + (secs < 10 ? "0" : "");
ret += "" + secs + "s";
return ret;
} else return "";
},
},
};
</script>
プロジェクトを実行すると、下のブラウザのタブイメージに表示できます.私はこの記事は、インタビュープロセスを通過するのに役立ちます願っています.
Reference
この問題について(VuejsによるインタラクティブMatcher), 我々は、より多くの情報をここで見つけました https://dev.to/ilyoskhuja/interactive-matcher-with-vuejs-1b8iテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol