一、指令補充
1. 指令修飾符
1. 作用: 借助指令修飾符, 可以讓指令更加強大
2. 分類:
1> 按鍵修飾符: 用來檢測用戶的按鍵, 配合鍵盤事件使用. keydown 和 keyup
語法:
@keydown.enter/v-on:keydown.enter 表示當enter按下的時候觸發
@keyup.enter/v-on:keyup.enter 表示當enter抬起的時候觸發
2> 事件修飾符: 簡化程序對于阻止冒泡(子元素和上級元素有相同的事件,子元素事件的觸發會向上傳遞會觸發上級元素的同名事件),阻止默認行為的操作(比如a標簽的默認行為就是,點擊鏈接會跳轉)
語法:
@事件名.stop/v-on:事件名.stop -> 阻止冒泡
@事件名.prevent/v-on:事件名.prevent -> 阻止默認行為
@事件名.stop.prevent -> 可以連用 即阻止事件冒泡也阻止默認行為
3> 雙向綁定修飾符: 可以讓v-model的功能更加強大
語法: v-model = "數據"
v-model.trim="數據": 把輸入框的首位空格去掉再同步給數據
v-model.number="數據": 嘗試把輸入框的值轉成數字再同步給數據
v-model.lazy="數據": 當失焦的時候再同步給數據, 而不是實時同步
?關于冒泡
總體代碼
按鍵修飾符和事件修飾符
<script setup>
// 處理按鍵函數
const onkeyDown = () => {console.log('onKeyDown')
}
// p標簽的點擊事件
const onPClick = () => {console.log('onPClick')
}
const onDivclick = () => {console.log('onDivclick')
}
const onAClick = () =>{console.log('onAClick')
}</script>
<template><div @click="onDivclick"><!-- 按鍵修飾符 --><!-- 檢測用戶按的是不是回車鍵,是回車鍵就觸發搜索 --><!-- 可以配合鍵盤來使用 keydown.enter keyup.enter --><input type="text" v-on:keydown.enter="onkeyDown"><!-- 事件修飾符 --><!-- 阻止a的默認行為 --><!-- .prevent: 阻止默認行為 --><a href="https://baidu.com" @click.prevent="onAClick">百度一下</a><!-- .stop: 阻止冒泡,同名事件不會向上傳遞--><p @click.stop="onPClick"></p><!-- 一起使用,阻止默認行為,阻止向上冒泡 --><!-- 既不跳轉,也不冒泡 修飾符的鏈式調用,倆個同時阻止--><a href="https://baidu.com" @click.prevent.stop="onAClick">百度一下</a></div>
</template><style scoped>
div {width: 400px;height: 200px;background: plum;
}div a {display: block;width: 100px;text-decoration: none;background: tomato;text-align: center;color: #fff;
}div p {width: 200px;height: 100px;background: rebeccapurple;
}
</style>
雙向綁定修飾符
<script setup>
import { ref, reactive } from 'vue'
const goods = reactive({name: '',price: ''
})
</script><template><div><!-- .lazy修飾符 -->名稱: <input type="text" v-model.lazy="goods.name"><br/><br/>價格: <input type="text" v-model="goods.price"><br/><br/><!-- .trim修飾符 --><!-- 去除首位空格 -->名稱: <input type="text" v-model.trim="goods.name"><br/><br/>價格: <input type="text" v-model="goods.price"><br/><br/><!-- .number -->名稱: <input type="text" v-model.trim="goods.name"><br/><br/>價格: <input type="text" v-model.number="goods.price"></div>
</template><style scoped></style>
結果
2. v-model作用在其他元素上
v-model雙向綁定指令: 可以快速設置或獲取表單控件的值, 比如: 輸入框, 文本域,下拉菜單, 單選框,復選框. 用在不同的表單控件上, v-model都能夠正確設置或獲取相應的值, 但內部采用的方式和關聯的屬性有所不同.
輸入框: v-model -> input[type=text/search] -> value? ? ? ? ? ? ? ??
文本域: v-model -> textarea -> value? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
下拉框: v-model -> select -> value? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
單選框: v-model -> radio -> value (需要手動添加value屬性)? ?
復選框: v-model -> checkbox ->? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
1. 只有一個復選框: v-model綁定布爾值, 關聯的是復選框的checked屬性(當前復選框是否選中)
2. 有多個復選框: v-model綁定數組, 關聯的是復選框的 value 屬性, 需要手動給復選框添加 value 屬性
?具體代碼
<script setup>
import { ref } from 'vue'
// 自我介紹
const info = ref('')
// 收集城市
//里面寫選擇下拉框的 value
const city = ref('SH')
// 血型
//里面寫單選框的 value
const blood = ref('ab')
// 是否選中
const isAgree = ref(false)
// 收集愛好
const hobby = ref(['lq','ppq'])
</script>
<template><div><!-- 文本域 --><!-- 文本域里面默認有value 無需添加 --><textarea cols="30" rows="4" placeholder="請輸入自我介紹" v-model="info"></textarea><br /><br /><br /><!-- 下拉菜單 --><!-- 每次選擇就會把value放在city里面 --><!-- v-model 綁定的是下拉框的 value值 --><!-- select 里面默認有value無需手動添加 --><select v-model="city"><option value="BJ">北京</option><option value="SH">上海</option><option value="SZ">深圳</option><option value="HZ">杭州</option></select><br /><br /><br /><!-- 單選框 多個當中只能選擇一個, 需要單選框手動添加value--><input type="radio" value="a" v-model="blood">A<input type="radio" value='b' v-model="blood">B<input type="radio" value='ab' v-model="blood">AB<input type="radio" value='o' v-model="blood">O<br><br><!-- 復選框 --><!-- 只有一個復選框的情況 --><input type="checkbox" v-model="isAgree">是否同意用戶協<br><br><br><!-- 有多個復選框的情況 --><!-- 此時收集結果, 需要用到數組 --><input type="checkbox" value="lq" v-model="hobby">籃球<input type="checkbox" value="ymq" v-model="hobby">羽毛球<input type="checkbox" value="ppq" v-model="hobby">乒乓球<input type="checkbox" value="zq" v-model="hobby">足球<br><input type="checkbox" value="cf" v-model="hobby">吃飯<input type="checkbox" value="sj" v-model="hobby">睡覺<input type="checkbox" value="ddd" v-model="hobby">打豆豆<input type="checkbox" value="xx" v-model="hobby">學習</div></template><style scoped></style>
運行結果?
三、樣式綁定
概念
1. 為了方便程序員給元素動態的設置樣式, Vue擴展了 v-bind 語法(綁定屬性)允許我們通過綁定class或者style屬性, 通過數據控制元素的樣式.
2. 分類: 1>綁定 class 2> 綁定style
1. class樣式綁定
class的綁定語法:? ?v-bind:class="三元表達式或對象"/ :class="三元表達式或對象"
1>?三元綁定: :class=" 條件 ? '類名1' : '類名2' "
2> 對象綁定: :class="{類名1:布爾值1,類名2:布爾值2,...", 布爾值為true,添加類名; 否則移除類名
具體代碼
<script setup>
import { ref } from 'vue'
// 是否激活
const isActive = ref(true)
</script>
<template><div><!-- 1.三元綁定 --><!-- 滿足條件則類選擇器指向的標簽為紅色 --><p v-bind:class="isActive ? 'active' : ''">Active1</p><!-- 2. 對象綁定(用的多) --><p :class="{ active: isActive }">Active2</p><!-- 3. 靜態class和動態class可以共存, 二者會合并 --><!-- 此時有倆個類一般多個類會通過空格來進行分割 active item --><p class="item" :class="{ active: isActive }">Active3</p></div>
</template><style scoped>
/* 類名為active */
.active {color: red;
}
</style>
案例一: 京東秒殺-tab欄切換導航高亮
需求:
當我們點擊哪個tab頁簽時,哪個tab標簽就?亮
步驟:
1> 靜態布局+樣式
2> 列表渲染 綁定給背景變成紅色,字體變成黑色的類v-bind:class{}
3> 點誰誰亮?添加點擊事件,點擊誰就把誰的下標賦值給激活下標
具體代碼?
<script setup>
import { ref } from 'vue';// 1> 靜態布局+樣式// 2> 列表渲染
// 如果是要對數組進行動態操作: 刪除, 添加此時才用ref(響應式)
// tabs 欄數組
const tabs = [{ id: 1, name: "京東秒殺" },{ id: 2, name: "每日特價" },{ id: 3, name: "品牌秒殺" }]
// 3> 點誰誰亮
//激活的下標, 默認第一個高亮
const activeIndex = ref(0)
</script><template><div><ul><!-- index和activeIndex的值一樣就把設置顯示紅色的類加上去 --><li v-for="(item, index) in tabs" :key="item.id"><!-- 把點擊的下標值賦值給控制激活的下標 --><a @click="activeIndex = index" href="#" :class="{ active: activeIndex === index }">{{ item.name }}</a></li></ul></div>
</template><style>
* {margin: 0;padding: 0;
}ul {/* 去除小黑點 */list-style: none;display: flex;border-bottom: 2px solid #e01222;padding: 0 10px;
}ul li {width: 100px;height: 50px;line-height: 50px;text-align: center;
}ul li a {display: block;text-decoration: none;color: #333;font-weight: bold;
}ul li a.active {/* 背景為紅色 */background: #e01222;/* 字體顏色為白色 */color: #fff;
}
</style>
2. style樣式綁定
使用介紹
style樣式綁定:?
1. 語法:? :style="{css屬性名1:表達式1,css屬性名2:表達式2,...}"
具體代碼
<script setup>
import { reactive, ref } from 'vue';
// 字體顏色
const colorStr = ref('red')
// 響應式樣式對象
const styleObj = reactive({color: 'green',background: 'yellow'
})
</script>
<template><div><p v-bind:style="{ color: colorStr }">Style1</p><p :style="styleObj">Style2</p></div>
</template>
<style></style>
?案例二: 進度條
需求: 點擊哪個按鈕,上面進度條就跑到多少
核心: 修改inner盒子里面的寬度即可完成進度條的顯示, 此時它這個數字會跟隨點擊按鈕而改變
完整代碼:
<script setup>
import { ref } from 'vue'
// 份數: 一共四份
const x = ref(0)
</script>
<template><div class="progress"><!-- 拼接為百分數 --><div class="inner" v-bind:style="{ width: (x / 4) * 100 + '%' }"><span>{{ (x / 4) * 100 + '%' }}</span></div></div><!-- 每次點擊把x賦值 --><button @click="x = 1">設置25%</button><button @click="x = 2">設置50%</button><button @click="x = 3">設置75%</button><button @click="x = 4">設置100%</button>
</template>
<style>
.progress {height: 25px;width: 400px;border-radius: 15px;background-color: #272425;border: 3px solid #272425;box-sizing: border-box;margin-bottom: 30px;
}.inner {height: 20px;border-radius: 10px;text-align: right;position: relative;background-color: #409eff;background-size: 20px 20px;box-sizing: border-box;transition: all 1s;
}.inner span {position: absolute;right: -25px;bottom: -25px;
}
</style>
四、計算屬性?
1. 基本使用
1. 定義: 基于現有的數據, 計算得到新數據; 當現有的數據發生變化了, 計算屬性會重新計算得到新結果.(購物車, 基于商品的數組大小統計出商品數,后續數組發生變化, 商品數也會發生變化)
2. 語法:
? ? ? ? ? ? ?import {computed} form 'vue'
? ? ? ? ? ? ?const 計算屬性 = computed(()=>{
? ? ? ? ? ? ? ? //編寫計算代碼
? ? ? ? ? ? ? ? return 計算結果
???????????????})? ?
案例:? 求商品的總數
?const goodList = [
{ id: 1, name: '籃球', num: 1 },
{ id: 2, name: '玩具', num: 3 },
{ id: 3, name: '書籍', num: 2 }
]//我們可以使用computed計算把每個商品的數量進行累加
具體代碼:
<script setup>
import { ref, computed } from 'vue'
// 商品列表(原始數據)
const goodsList = ref([{ id: 1, name: '籃球', num: 1 },{ id: 2, name: '玩具', num: 3 },{ id: 3, name: '書籍', num: 2 }
])
// 計算屬性
// 總數是依賴于這個對象數組得到的,因此goodList是totalNum的依賴
const totalNum = computed(() => {// 求和return goodsList.value.reduce((prev, item) => prev + item.num, 0)
})
// 訪問對象的計算屬性
console.log(totalNum.value)
</script>
<!-- 基于現有的原始數據 goodsList 計算得到總數量 -->
<!-- 此時推薦把總數量聲明為 計算屬性 -->
<template><div><h3>商品清單</h3><table><thead><tr><th>名字</th><th>數量</th></tr></thead><tbody><tr v-for="(item) in goodsList" :key="item.id"><td>{{ item.name }}</td><td>{{ item.num }}</td></tr><p>商品總數: {{ totalNum }} 個</p><!-- 復習v-text --><p>商品總數: <span v-text="totalNum"></span>個</p></tbody></table></div>
</template><style scoped>
table {width: 350px;border: 1px solid #333;
}table th,
table td {border: 1px solid #333;
}table td {text-align: center;
}
</style>
4. 什么時候使用計算屬性?
當需要基于原始/已知數據計算求得新結果
5. 計算屬性的使用
1> computed和ref/reactive一致, 既可以配合插值, 也可以配合指令使用
2> 在js中要獲取計算屬性, 需要通過 計算屬性.value
6. 注意:
1> 計算屬性必須有返回值, 該返回值就是計算屬性的返回結果
2> 當依賴發生變化, 計算屬性會重新計算
2. 計算屬性 VS 普通函數
計算屬性和普通函數的區別
計算屬性:
1. 概念: 封裝一段計算求值的代碼
2. 語法:?
1> 配合插值或指令
2> js操縱的時候, 需要 .value
普通函數:
1.?概念: 封裝一段任意的js代碼
2. 語法:
1> 配合插值或指令使用: 函數名(實參列表)
2> 配合事件使用, @click="函數名(實參列表)"
計算屬性的優勢
帶緩存
1. 當依賴不變, 多次調用同一個計算屬性, 函數體只會執行一次, 因為第一次函數體執行完畢后會緩存計算結果
2. 當依賴發生變化的時候, 計算屬性才會重新計算, 并緩存新的結果.
3. 普通函數不帶緩存, 調用一次, 會執行一次.
什么時候用函數, 什么時候用計算屬性
1. 當要搭配事件的時候使用函數
2. 基于已有屬性計算新值使用計算屬性
3. 計算屬性完整寫法
什么時候使用完整寫法?
需要修改計算屬性的時候(給計算屬性賦值)
問題
默認是的簡易寫法, 計算屬性是只讀的(只能展示, 不能賦值),如果賦值就會報警.
我們可以看出, 我們computed的簡寫計算出來的值是不能修改的(只讀)
解決方法
需要用到計算屬性的完整寫法: get + set
完整寫法的語法
1> 簡易寫法: const 計算屬性 = computed(()=>{return 計算結果})
2> 完整寫法:
?const 計算屬性 = computed({
// 使用計算屬性的時候, 自動觸發get, get 內部必須返回計算結果
get(){
return 計算結果
},
//修改計算屬性自動觸發 set, val 參數表示要給計算屬性賦予的值
set(val){
}
})
代碼演示?
<script setup>
import { computed } from 'vue';
//簡易寫法只能讀不能寫
const username = computed(()=>{return "小黑子"
})
//完整寫法
const username2 = computed({// get: function(){// return "小白子"// },get(){return "小白子"},// value是給計算屬性賦予的新值// 只要給計算屬性賦值, 就會觸發 set 函數的執行set(value){console.log(value)}
})
</script>
<template><div><input type="text"v-model="username"></div><div><input type="text"v-model="username2"></div>
</template><style scoped></style>
結果解析
五 案例三: 全選反選
需求:?
1> 點擊選項 對應的字會變成 灰色
2> 點擊全選 對應的全部的字變成 灰色
3> 點擊反選 對應的選項取反
具體代碼
<script setup>
import { ref, computed } from 'vue'
// 計劃列表
const planList = ref([// 默認是false{ id: 12, name: '跑步', done: false },{ id: 76, name: '看書', done: false },{ id: 31, name: '擼碼', done: false },{ id: 49, name: '追劇', done: false }
])
//是否全選
const isAll = computed({// 使用計算屬性自動觸發 getget() {// 檢測每一個return planList.value.every((item) => item.done)},//修改計算屬性自動觸發 setset(val) {//value 給計算屬性賦予的新值, 此時就是全選復選框的狀態// 點擊全不選, 然后小選的就被全選的值所賦值console.log(val)//遍歷 planList 數組, 把每個小選的 done 屬性和 val 保持一致即可planList.value.forEach((item) => item.done = val)}
})
//點擊反選, 直接遍歷當前數組對象, 然后對里面的done屬性進行取反即可
const onTouch = () => {//遍歷 planList數組, 對每個對象的 done 屬性取反即可planList.value.forEach(item => item.done = !item.done)}</script>
<template><div class="container"><P><span><input type="checkbox" id="all" v-model="isAll"><!-- label 和input的id保持一致,點擊文字可以控制復選框選不選中--><label for="all">全選</label></span><button @click="onTouch">反選</button></P><ul><li v-for="item in planList"><input type="checkbox" v-model="item.done"><!-- 根據對象里面的值來控制 --><span :class="{ completed: item.done }">{{ item.name }}</span></li></ul></div></template><style lang="scss">
* {margin: 0;padding: 0;
}ul {list-style: none;li {display: flex;justify-content: space-between;align-items: center;padding-left: 5px;height: 40px;border-bottom: 1px solid #ccc;span.completed {// 如果加上這個類就會把字體變成灰色并且有一條線color: #ddd;text-decoration: line-through;}}
}.container {width: 400px;margin: 100px auto;padding: 15px 18px;background: plum;p {display: flex;justify-content: space-between;align-items: center;height: 40px;border-bottom: 1px solid #ccc;padding: 3px 6px;}input {margin-left: 8px;}}
</style>
六、偵聽器
偵聽器: 監視 == 盯著看
1. 作用: 監視響應式數據(ref/reactive數據)變化, 當數據變了, 可以更改DOM或異步操作. 比如監視搜索框關鍵字的變化, 比如監視搜索框關鍵字的變化, 變了之后, 可以用最新的關鍵字發送請求, 拿到最新的聯想建議列表.
2. 語法: 需要使用到 watch 函數進行聲明
import {watch} from 'vue'
watch(響應式數據,(newVal,oldVal) => {
//newVal: 新值
//oldVal: 舊值
}
具體代碼
<script setup>
import { ref, watch, reactive } from 'vue'
//搜索關鍵字
const keyword = ref('')
//監視 keyword 這個 ref 響應式數據
//只要 keyword 變了, 每次都會執行 watch 的回調函數
watch(keyword, (newVal, oldVal) => {//先打印新值, 再打印舊值console.log(newVal, oldVal)
})
// 響應式對象
const obj = reactive({username: '',password: ''
})
watch(obj, (newVal, oldVal) => {// 對象的新和就值一樣,因為指向的是同一塊地址console.log(newVal, oldVal)console.log(newVal === oldVal)console.log(newVal === obj)
})
</script>
<template><div><input type="text" v-model="keyword" placeholder="請輸入關鍵字"><br><input type="text" v-model="obj.username" placeholder="請輸入用戶名"><br><input type="text" v-model="obj.password" placeholder="請輸入密碼"></div>
</template><style scoped></style>
七、案例成績管理
需求
1> 輸入科目和分數,點擊添加,這個數據就會加到表格中去.
2> 點擊刪除按鈕, 就可以刪除這個數據.
3> 每次操作完都會重新計算總分和平均分.
4> 如果沒有數據, 就會顯示(暫無數據)
主要功能實現:
添加
1> 收集表單的值: v-model指令 + 修飾符trim和number
2> 點擊添加按鈕: 做非空校驗 + 阻止默認行為
3> 通過校驗后, 需要給 scoreList 數組里面新增一個對象(數據驅動視圖的思想) 使用了 對象的...進行展開
4> 清空表單
刪除
1> 綁定點擊事件, 傳入下標作為實參
2> 刪除確定的提示
3> 調用 splice() 進行刪除
4> 當數據刪除完畢, 需要展示 暫無數據 的提示
底部統計:?
1> 總分: 計算屬性 + reduce()求和
2> 平均分: 總分/數組的長度 + 三元判斷
數據持久化:? 點擊瀏覽器的刷新, 我們表單里面的值會保持上一次的狀態
1> 監視 scoreList 的變化, 當它變了之后, 只需要把最新的只存儲到本地, 通過 localStorage 進行存儲
2> 當頁面刷新的時候, 從本地中取出上次存儲 scoreList, 基于整個值進行 table 的列表渲染即可
具體代碼
<script setup>
import { ref, reactive, computed, watch } from 'vue'
//本地存儲的鍵名
const SCORE_LIST_KEY = 'score-list-key';
//從前端本地取值,而不是用我們這里對象數組里面寫的值
// 取的時候需要反序列化
// console.log(localStorage.getItem('score-list-key'))
// console.log(JSON.parse(localStorage.getItem('score-list-key')))
// 成績列表
const scoreList = ref(//第一次進來,locastorage里面沒有值, 默認為null, 那么就返回默認值JSON.parse(localStorage.getItem(SCORE_LIST_KEY)) || [{ id: 19, subject: '語?', score: 94 },{ id: 27, subject: '數學', score: 57 },{ id: 12, subject: '英語', score: 92 }]
)
//成績表單
const scoreForm = reactive({subject: '',//科目score: ''//科目的分數
})
//添加
const onAdd = () => {//非空校驗if (!scoreForm.subject || !scoreForm.score) {return alert("科目名稱或分數不能為空")}//給數組新增對象scoreList.value.push({// 把對象的鍵值對放進去...scoreForm,//展開 scoreform, 把 scoreform 中的鍵值對全部拿過來,放到新對象中id: Date.now()// 時間戳// 就相當于下面的代碼// subject: '',//科目// score: ''//科目的分數})//清空表單scoreForm.score = ''scoreForm.subject = ''
}
//刪除
const onDel = (i) => {// console.log(i)if (window.confirm("確認刪除嗎?")) {scoreList.value.splice(i, 1)}
}
//計算得到總分數
const totalScore = computed(() => {return scoreList.value.reduce((prev, item) => prev + item.score, 0)
})
//計算得到平均分
const avgScore = computed(() => {//0/0=NaNreturn scoreList.value.length > 0? totalScore.value / scoreList.value.length: 0;
})
//監視
//watch 里面監視的是響應式數據
watch(scoreList, (newVal) => {//監視 scoreList 的變化, 當 scoreList 變了,將最新的值進行序列化后, 存儲到本地localStorage.setItem(SCORE_LIST_KEY, JSON.stringify(newVal))
},{deep: true}//開啟深度監聽
)</script>
<template><div class="score-case"><div class="table"><table><thead><tr><th>編號</th><th>科?</th><th>成績</th><th>操作</th></tr></thead><tbody><!-- 列表渲染 --><!-- 使用 v-for 循環生成每一行 --><tr v-for="(item, index) in scoreList" :key="item.id"><td>{{ index + 1 }}</td><td>{{ item.subject }}</td><!-- v-bind 綁定熟悉值,小于60綁定red這個類 --><td v-bind:class="{ red: item.score < 60 }">{{ item.score }}</td><!-- 綁定點擊事件, 把下標作為參數傳進去 --><td><a href="#" @click="onDel(index)">刪除</a></td></tr></tbody><!-- 添加條件渲染,數組長度為0再展示 --><tbody v-if="scoreList.length === 0"><tr><td colspan="5"><span class="none">暫?數據</span></td></tr></tbody><tfoot><tr><td colspan="5"><span>總分: {{ totalScore }}</span><span style="margin-left: 50px">平均分: {{ avgScore }}</span></td></tr></tfoot></table></div><form class="form"><div class="form-item"><div class="label">科?:</div><div class="input"><!-- 收集表單的值 --><!-- 和v-model進行雙向數據綁定 并且去除首尾空格--><input type="text" placeholder="請輸?科?" v-model.trim="scoreForm.subject" /></div></div><div class="form-item"><div class="label">分數:</div><div class="input"><!-- 雙向數據綁定, 只能輸入數字 --><input type="number" placeholder="請輸?分數" v-model.number="scoreForm.score" /></div></div><div class="form-item"><div class="label"></div><div class="input"><!-- 綁定添加函數 --><!-- 消除表單的默認刷新行為 --><button class="submit" @click.prevent="onAdd">添加</button></div></div></form></div>
</template>
<style>
.score-case {width: 1000px;margin: 50px auto;display: flex;
}.score-case .table {flex: 4;
}.score-case .table table {width: 100%;border-spacing: 0;border-top: 1px solid #ccc;border-left: 1px solid #ccc;
}.score-case .table table th {background: #f5f5f5;
}.score-case .table table tr:hover td {background: #f5f5f5;
}.score-case .table table td,
.score-case .table table th {border-bottom: 1px solid #ccc;border-right: 1px solid #ccc;text-align: center;padding: 10px;
}.score-case .table table td.red,
.score-case .table table th.red {color: red;
}.score-case .table .none {height: 100px;line-height: 100px;color: #999;
}.score-case .form {flex: 1;padding: 20px;
}.score-case .form .form-item {display: flex;margin-bottom: 20px;align-items: center;
}.score-case .form .form-item .label {width: 60px;text-align: right;font-size: 14px;
}.score-case .form .form-item .input {flex: 1;
}.score-case .form .form-item input,
.score-case .form .form-item select {appearance: none;outline: none;border: 1px solid #ccc;width: 200px;height: 40px;box-sizing: border-box;padding: 10px;color: #666;
}.score-case .form .form-item input::placeholder {color: #666;
}.score-case .form .form-item .cancel,
.score-case .form .form-item .submit {appearance: none;outline: none;border: 1px solid #ccc;border-radius: 4px;padding: 4px 10px;margin-right: 10px;font-size: 12px;background: #ccc;
}.score-case .form .form-item .submit {border-color: #069;background: #069;color: #fff;
}
</style>