#持續划水中#
本文章僅用作於個人學習筆記複製程式碼
劃重點 —— 個人筆記!(◔◡◔)
參考文章:(牆)Vuejs transition on table rows
最終效果圖:
今天在學習 Vue的過渡&動畫 的時候遇到了一個困擾了一下午的問題。
在根據官方文件提供的 列表過渡 中嘗試給之前寫的一個表格demo中的<tbody>下的<tr>行新增過渡效果的時候發現,過渡並沒有出現。看著列表過渡的介紹彷彿程式碼也沒有錯啊(๑òᆺó๑)。程式碼如下:
/* 過渡的自定義的類名 */
.demo-enter,
.demo-leave-to {
opacity: 0;
transform: translateY(20px);
}
.demo-enter-active,
.demo-leave-active {
transition: all 0.5s ease;
}
.demo-move {
transition: all 0.5s ease;
}
<!-- HTML table部分 -->
<table class="table table-striped table-inverse table-bordered">
<thead class="thead-inverse">
<tr>
<th>ID</th>
<th>品牌名稱</th>
<th>新增時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<transition-group name="demo" appear>
<tr v-for="item in getFilter(key)" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.mTime}}</td>
<td><a href="javascript:;" @click="handleDelect(item.id)">刪除</a></td>
</tr>
</transition-group>
</tbody>
</table>複製程式碼
對比官方文件仍沒找到錯誤,於是開啟審查元素,發現......
這個空的span標籤(紅框位置)是哪來的???
<tbody>下不是應該有一個由transition-group預設生成的<span>標籤包著的嗎?咋不見了??難道是渲染到了上面莫名其妙出來的那個<span>標籤那裡了???
為了驗證這個<span>元素是否飄了,於是給transition-group預設生成的<span>元素通過tag屬性改了個起名很隨便的元素<testdiv>並重新開啟了審查元素:
<transition-group name="demo" appear tag="testdiv">
...
</transition-group>
複製程式碼
還真是你飄了。。。
官方文件的解釋:
原來,在table裡使用<transition-group>的時候,生成的真實元素<testdiv>之所以 會脫離table標籤,並插到了table標籤前,是因為 這個 <transition-group> 元件會被作為無效的內容提升到外部,並導致最終渲染結果出錯。
這裡官方文件給出了一個解決辦法:
於是我給<tbody>中新增這個 is 特性。由於是在<tbody>中用 is 新增的 transition-group ,因此也不會再預設生成一個<span>元素。
<tbody is="transition-group" name="demo" appear>
<tr v-for="item in getFilter(key)" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.mTime}}</td>
<td><a href="javascript:;" @click="handleDelect(item.id)">刪除</a></td>
</tr>
</tbody>複製程式碼
檢視效果:
完整程式碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
[v-cloak] {
display: none;
}
#app {
width: 700px;
}
.demo-enter,
.demo-leave-to {
opacity: 0;
transform: translateY(20px);
}
.demo-enter-active,
.demo-leave-active {
transition: all 0.5s ease;
}
.demo-move {
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<div class="input-group">
<input v-model="id" type="text" class="form-control" placeholder="請輸入品牌ID" aria-label="Recipient's username"
aria-describedby="basic-addon2">
<input v-model="name" @keyup.enter="handleSubmit" type="text" class="form-control" placeholder="請輸入品牌名稱"
aria-label="Recipient's username" aria-describedby="basic-addon2">
<div class="input-group-append">
<button @click="handleSubmit" class="btn btn-outline-secondary" type="button">新增</button>
</div>
<input v-model.trim="keywords" @keyup.enter="search" type="text" class="form-control" placeholder="搜尋品牌"
aria-label="Recipient's username" aria-describedby="basic-addon2">
<div class="input-group-append">
<button @click="search" class="btn btn-outline-secondary" type="button">搜尋</button>
</div>
</div>
<table class="table table-striped table-inverse table-bordered">
<thead class="thead-inverse">
<tr>
<th>ID</th>
<th>品牌名稱</th>
<th>新增時間</th>
<th>功能</th>
</tr>
</thead>
<tbody is="transition-group" name="demo" appear>
<tr v-for="item in getFilter(key)" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.mTime}}</td>
<td><a href="javascript:;" @click="handleDelect(item.id)">刪除</a></td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
id: "",
name: "",
mTime: "",
key: "",
keywords: "",
list: [
{
id: "1",
name: "MEIZU",
mTime: new Date().toLocaleString()
},
{
id: "2",
name: "MI",
mTime: new Date().toLocaleString()
},
{
id: "3",
name: "VIVO",
mTime: new Date().toLocaleString()
}
],
},
methods: {
handleSubmit() {
var phone = {
id: this.id,
name: this.name,
mTime: new Date().toLocaleString()
};
this.id = this.name = "";
this.list.push(phone);
// 每次點選均更新list的值
this.search();
},
handleDelect(id) {
this.list.some((item, i) => {
if (item.id == id) {
this.list.splice(i, 1);
return true;
}
})
// 每次點選均更新list的值
this.search();
},
getFilter(key) {
if (this.keywords == "") {
this.key = this.keywords;
}
return this.list.filter(item => item.name.includes(this.key));
},
search() {
this.key = this.keywords;
}
}
})
</script>
</body>
</html>複製程式碼
----------------END
剛開始遇到這個問題,百度關鍵詞 使用transition-group的注意事項 時一直找不到有效的方法。思考是不是 bootstrap 的 table (我也不知道為什麼會覺得時bs的問題,但也算是誤打誤撞找到方法了◔◡◔)有問題的時候,百度以 table transition-group 為關鍵詞進行搜尋,翻了幾頁也沒有找到解決方法(現在搜尋第一頁第一個就是解決的方法了,有點神奇。傳送門)。實在沒找到方法後開啟了google,搜尋 table transition-group 。emmm,一頁下來點開前三個,都是能解決的方法(這裡得批評一下百度,要說第三個搜尋結果連線被牆了百度搜不到還好說,但前兩個都是gayhub裡的,咋百度的時候就沒出這兩個連線呢 ´◔‸◔` )。
也因此才知道,早在2016年,尤雨溪大神已經在vuejs的Issuse中有回答了。。。並且官方文件中也有 特殊特性 is 這個API的說明。。。API文件還是得多翻翻 - -
果然還是我太水了(||๐_๐)