当前位置: 首页 > news >正文

指令补充+样式绑定+计算属性+监听器

一、指令补充

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>

总结

 


http://www.mrgr.cn/news/97121.html

相关文章:

  • 在 Android Studio 中运行安卓应用到 MuMu 模拟器
  • Leetcode 33 -- 二分查找 | 归约思想
  • PyTorch中的Flatten
  • windows如何安装wkhtmltoimage 给PHP使用根据HTML生成图片
  • Ansible Playbook 进阶探秘:Handlers、变量、循环及条件判断全解析
  • Leetcode 15 -- 双指针
  • pyTorch框架:模型的子类写法--改进版二分类问题
  • Opencv计算机视觉编程攻略-第九节 描述和匹配兴趣点
  • 【JavaScript】原型链 prototype 和 this 关键字的练习(老虎机)
  • 前端快速入门学习2-HTML
  • 【11408学习记录】英语写作黄金模板+语法全解:用FTC数据泄漏案掌握书信结构与长难句拆解(附思维导图)
  • 《AI大模型开发笔记》MCP快速入门实战(一)
  • Linux开发工具——vim
  • Linux操作系统 4.Linux实用操作
  • #SVA语法滴水穿石# (003)关于 sequence 和 property 的区别和联系
  • Ubuntu上离线安装ELK(Elasticsearch、Logstash、Kibana)
  • 卫星智能化健康管理#卫星工程系列
  • python 命名空间与作用域 可变与不可变对象 闭包
  • 明清两朝全方位对比
  • HCIP【BGP协议(详解)】