2022 年,我所用的語言被評為全球最爛語言。為什麼呢?垃圾框架層出不窮,執行環境千差萬別,型別錯誤數量全網第一。
這是事實,無法否認,但開發者們還是蜂擁而來。這語言總會給你一絲希望,vite 也好,next 也罷,但如此近,彷彿觸手可及,讓人奮不顧身。
這裡充斥著網頁,而我正是那頁面仔!
程式碼請移步至 GitHub OverflowCat/lanqiao-14-web。
憑空消失的 TA
題目
初始程式碼中的
index.html在瀏覽器中並沒有顯示出來表單元件myform。考生需要認真檢查提供的程式碼,找出表單消失的原因,並修復掉,最終讓表單 “重見天日”。
思路
這題跟 Vue 2 半毛錢關係沒有,單純是 index.html 中沒有引用 Element UI 的 js
程式碼
diff --git 憑空消失的TA/index.html
@@ -8,6 +8,7 @@ <title>憑空消失的 TA</title>
<script src="./js/vue.min.js"></script>
<script src="./js/http-vue-loader.js"></script>
+ <script src="./element-ui-2.15.10/index.js"></script>
<!-- 引入 element-ui 樣式 -->
<link rel="stylesheet" href="./element-ui-2.15.10/index.css" />
</head>使用者名稱片
思路
The year is 2049...
All websites use Tailwind, there are only 69 people remaining that know how to write custom CSS.
These 69 people have to center divs to save the world.
They are our only hope.
(This is my pitch to Netflix for an upcoming movie)
Credit: TheJackForge
In case you still do not know how to center divs horizontally & vertically, refer to 11 Ways to Center Div or Text in Div in CSS or CSS-水平居中、垂直居中、水平垂直居中.
程式碼

.avatar,
.card {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}
.user-card {
width: 150px;
height: 100%;
position: relative;
float: left;
display: flex;
justify-content: center;
}芝麻開門
題目
找到
index.js檔案中的mPrompt函式,完成函式中的 TODO 部分。
- 點選 “點選彈出對話方塊,輸入咒語” 按鈕會呼叫
mPrompt函式,mPrompt呼叫後頁面顯示對話方塊。mPrompt函式必須返回一個promise物件。- 在對話方塊中的輸入框中輸入文字後,點選確認按鈕,對話方塊消失,
promise返回成功,promise成功的值為輸入的值。- 只有當成功的值為 “芝麻開門” 時門自動開啟(已實現)。
- 點選取消,對話方塊消失,
promise返回失敗,失敗的值為false。- 對話方塊的顯示隱藏請使用 DOM 節點的新增刪除實現。
思路
本題考察 Promise。在返回的 Promise 中新增 onclick 事件,並在函式中呼叫 Promise 的引數。
程式碼
const incantations = "芝麻開門";
function init(el) {
document.querySelector(".wrapper .btn").addEventListener("click", () => {
mPrompt()
.then((res) => {
if (res === incantations) {
document
.querySelectorAll("#door .doors")[0]
.classList.add("door-left");
document
.querySelectorAll("#door .doors")[1]
.classList.add("door-right");
}
})
.catch((err) => {
console.log(err);
});
});
}
/**
* @description: 呼叫函式,開啟彈窗,記錄輸入框的內容,並透過 promise 非同步返回輸入框中的內容
* @return {Promise}
*/
function mPrompt() {
// 彈窗必須使用以下結構 template 儲存的是彈窗的結構字串,可以先轉化為 DOM 再透過 appendChild 方式插入到 body 中
const template = `
<div class="modal">
<div class="message-box">
<div class="message-header">請輸入咒語</div>
<div class="message-body">
<input type="text">
</div>
<div class="message-footer">
<button class="btn btn-small" id='cancel'>取消</button>
<button class="btn btn-small btn-primary" id='confirm'>確定</button>
</div>
</div>
</div>
`;
const div = document.createElement("div");
// TODO:待補充程式碼
div.innerHTML = template;
document.body.appendChild(div);
const hide = () => div.remove();
return new Promise(
(resolve, reject) => {
div.querySelector("button#cancel").onclick = e => {
hide();
reject(false);
}
div.querySelector("button#confirm").onclick = e => {
resolve(div.querySelector("input").value);
}
hide();
}
);
}寶貴的一票
題目
完成
index.html檔案中的 TODO 部分。
- 點選新增選項,頁面中新增一個選項。選項前文字按照:選項 1,選項 2,選項 3 ...... 順序排列,當頁面中的選項大於 2 個時,選項後面跟隨刪除按鈕(即 x 圖示)。帶有刪除圖示的選項 DOM 結構如下:
<div> <label>選項1</label> <div> <input type="text" /> </div> <div> <!-- 刪除圖示 --> <img src="./images/x.svg" alt="" /> </div> </div>
- 點選刪除按鈕,刪除當前選項,並且選項前文字按照:選項 1,選項 2,選項 3 ...... 順序排列,當選項數量小於等於 2 個時,選項後面無刪除按鈕。
思路
這題要求點刪除按鈕的時候刪除的是對應的文字框,並且後面的選項序號需要再次排序。注意如果增加了選項的話,選項1 和 選項2 也是需要刪除按鈕的。直接 querySelector 改內容就好了,注意 template 的結構。
程式碼
見 ./寶貴的一票/index.html。
粒粒皆辛苦
介紹
俗話說 “民以食為天”,糧食的收成直接影響著民生問題,透過對農作物產量的統計資料也能分析出諸多實際問題。
接下來就讓我們使用 ECharts 圖表,完成 X 市近五年來的農作物產量的統計圖吧~
準備
本題已經內建了初始程式碼,開啟實驗環境,目錄結構如下:
├── data.json ├── index.html └── js ├── axios.min.js └── echarts.min.js其中:
index.html是主頁面。js/echarts.min.js是 ECharts 檔案。js/axios.min.js是 axios 檔案。data.json是對應年份的糧食產量資料,單位為萬噸。選中
index.html右鍵啟動 Web Server 服務(Open with Live Server),讓專案執行起來。接著,開啟環境右側的【Web 服務】,就可以在瀏覽器中看到如下效果:
目標
請完成
index.html檔案中的 TODO 部分。
- 完成資料請求(資料來源
./data.json)。data.json中的資料中英文對照如下:3. 在頁面的折線圖和餅形圖中正確顯示糧食產量資料。其中折線圖為五年資料,餅圖只顯示 2022 年資料。
英文名稱 中文名稱 wheat 小麥 soybean 大豆 potato 馬鈴薯 corn 玉米
思路
使用 myChart.setOption() 更新資料。EChart 會檢測 diff。這個框架可以看一看 菜鳥教程。
絕美宋詞
題目
請使用 Vue ,完成
index.html檔案中的 TODO 部分。
- 完成資料請求(資料來源
./data.json),data.json是宋詞資料,poetry_content表示詞句,title表示詞牌名,author表示詞人。- 在輸入框輸入關鍵詞時在
ul(class = suggestions)的元素中實時顯示詞牌名、詞句、詞人中包含關鍵詞的完整詞句(包含詞牌名、詞人)列表,當關鍵詞為空或者匹配不到時ul(class = suggestions)元素的子節點為空。完整詞句的 DOM 結構按照如下規定顯示:<li> <span>詞句</span> <span>詞牌名 - 詞人</span> </li>例:
<li> <span >常記溪亭日暮,沉醉不知歸路。興盡晚回舟,誤入藕花深處。爭渡,爭渡,驚起一灘鷗鷺</span > <span>如夢令 - 李清照</span> </li>
- 高亮匹配到的所有詞句中的關鍵詞。即使用
<span></span>標籤包裹所有關鍵詞。例:(關鍵詞:雨)
<li> <span >寒蟬悽切,對長亭晚,驟<span>雨</span >初歇。都門帳飲無緒,方留戀處,蘭舟催發。執手相看淚眼,竟無語凝噎。念去去千里煙波,暮靄沉沉楚天闊。多情自古傷離別,更那堪冷落清秋節。今宵酒醒何處,楊柳岸曉風殘月。此去經年,應是良辰美景虛設。便縱有千種風情,更與何人說</span > <span><span>雨</span>霖鈴 - 柳永</span> </li>注意:本題要求的是實時顯示,即輸入完成的同時顯示結果,非失去焦點顯示。
思路
這是我第一次用 Vue。在 Vue 2 中把 <input/> 的 value 繫結到變數並且在 input 更新時呼叫函式的方法:
<input
type="text"
id="search"
class="search"
placeholder="詞牌名 詞句 詞人"
+ v-model="query"
+ @input="handleInput"
/>根據文件,@input 會過濾掉 IME 的 buffer。題目給的效果圖好像並沒有這個行為,不過也過了,畢竟不知評測機制,並且沒人會寫帶 IME 的 test。
程式碼
@@ -14,8 +14,12 @@
<h1 style="text-align: center">輸入關鍵字,找一首詞</h1>
<!-- TODO:待補充程式碼 -->
<div class="search-form">
- <input type="text" id="search" class="search" placeholder="詞牌名 詞句 詞人" />
+ <input type="text" id="search" class="search" placeholder="詞牌名 詞句 詞人" v-model="query" @input="handleInput" />
<ul class="suggestions">
+ <li v-for="poem in filtered">
+ <span class="poet" v-html="poem.poetry_content"></span>
+ <span class="title" v-html="poem.title"></span>
+ </li>
</ul>
</div>
</div>
@@ -23,6 +27,40 @@
let vm = new Vue({
el: '#app',
// TODO:待補充程式碼
+ data: {
+ query: '',
+ poems: [],
+ filtered: []
+ },
+ created() {
+ this.queryData()
+ },
+ methods: {
+ highlight(text) {
+ return `<span class="highlight">${text}</span>`;
+ },
+ queryData() {
+ axios.get('./data.json').then(res => {
+ this.poems = res.data;
+ })
+ },
+ handleInput(e) {
+ if (this.query) this.filterData(this.query);
+ else this.filterData("哈哈哈沒有東西!!")
+ },
+ filterData(keyword) {
+ this.filtered = this.poems.filter(
+ x => x.poetry_content.includes(keyword)
+ || x.author.includes(keyword)
+ || x.title.includes(keyword)
+ ).map(x => {
+ return {
+ poetry_content: x.poetry_content.replaceAll(keyword, this.highlight(keyword)),
+ title: `${x.title} - ${x.author}`.replaceAll(keyword, this.highlight(keyword)),
+ }
+ })
+ }
+ }
})
</script>
</body>資訊介面
題目
介紹
隨著技術的發展,很多前端工程師已經不滿足於只做諸如頁面佈局和互動這些開發工作了,很多人將目光逐漸轉向了 “大前端” 範圍,其中就包括不需要依賴後端提供介面自己就可以使用 node.js 編寫一個後端介面服務。
下面就讓我們也來使用 node.js 完成一個新聞資訊介面吧。
目標
- 透過在
app.js書寫程式碼,建立一個伺服器,使服務在 8080 埠執行。- 訪問
/news返回資訊資料,訪問其他任意路徑均返回字串 404 。
Url 請求方式 引數 響應結果 news GET 空 顯示資訊資料 資料需要設定為
utf8格式,資訊資料格式如下:[ { "channelId": "5572a108b3cdc86cf39001cd", "name": "國內焦點" }, { "channelId": "5572a108b3cdc86cf39001ce", "name": "國際焦點" } ]設定
utf8格式程式碼:res.setHeader("Content-type", "text/html;charset=utf8");
- 透過
node app.js執行程式碼,使服務處於執行狀態,點選右側 【web 服務】,頁面上顯示訪問域名 +'/news' 返回資訊資料。
思路
使用 http.createServer()。注意一下設定 Content-type 的方式。
程式碼
見對應目錄。
平地起高樓
題目
相當於把 {id: number, parent_id: number: name}[] 巢狀起來返回 {id: number, parent_id: number: name, children: self[]}。
思路
維護一個 pid => id[] 的 Map,並把原陣列轉成以 id 為 key 的 Map 即可。
收快遞了
題目
相當於在 {id: number, parent_id: number: name, children: self[]} 中找到目標。
思路
遞迴即可。最後這兩道標為了「困難」的題目其實就是不會 TLE 的演算法題,沒啥難度。倒是好久沒寫 JS 老是型別錯誤,尤其是前面 寶貴的一票 parent 就沒型別了,比較討厭。
版权许可
- 本作品 采用 知识共享 署名—非商业性使用 4.0 国际许可协议(CC BY-NC 4.0 International)许可,阁下可自由地共享(复制、发行) 和演绎(修改、转换或二次创作) 这一作品,唯须遵守许可协议条款。

评论