vue基础-动态class
用v-bind给标签设置动态的值
语法:
- 格式1:<标签 :class="变量" />
- 格式2:<标签 :class="{类名1: 布尔值, 类名2: 布尔值}" />
-
- 如果布尔值为true,就添加对应的类名
说明:可以和静态class共存
<template>
<div id="app">
<h3>15-动态绑定class.vue</h3>
<p :class="type"> p的内容 class="变量"</p>
<p :class="['red', 'f40']"> p的内容 class="数组"</p>
<p class="abc" :class="{red:true, blue:true, f40:true}"> p的内容 class="数组"</p>
</div>
</template>
<script>
export default {
data() {
return {
type: 'blue'
}
}
}
</script>
<style>
.abc {background-color: #ccc;}
.f40 {font-size: 40px;}
.blue {color:blue}
.red {color:red}
body {
background-color: #ccc;
}
#app {
width: 400px;
margin: 20px auto;
background-color: #fff;
border: 4px solid blueviolet;
border-radius: 1em;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
padding: 1em 2em 2em;
}
</style>
vue基础-动态style
给标签动态设置style的值
语法
<标签 :style="{css属性名: 值}" />
- 可以和静态style共存
- 样式中带-属性写成小驼峰
<template>
<div id="app">
<h3>16-动态绑定style.vue</h3>
<p style="border: 1px solid red" :style="obj"> p的内容 :style="对象"</p>
<button @click="fn">设置随机设置字体大小</button>
</div>
</template>
<script>
export default {
data() {
return {
obj:{
backgroundColor: '#ccc',
color: "red",
fontSize: '40px'
}
}
},
methods: {
fn(){
const fs = Math.random() * 100
this.obj.fontSize = fs + 'px'
}
}
}
</script>
<style>
.abc {background-color: #ccc;}
.f40 {font-size: 40px;}
.blue {color:blue}
.red {color:red}
body {
background-color: #ccc;
}
#app {
width: 400px;
margin: 20px auto;
background-color: #fff;
border: 4px solid blueviolet;
border-radius: 1em;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
padding: 1em 2em 2em;
}
</style>
计算属性
使用场景 如果一个结果需要依赖data中的数据,但是需要经过一些逻辑处理,才能得到你想要的数据。此时就可以使用计算属性。 例如:要对给定的字符串做翻转处理之后再来显示
定义格式 在vue实例中,补充computed配置项。
{
data(){},
methods: {}
// 声明计算属性
computed: {
//属性名字(计算属性名称)
//属性的值(计算属性处理函数)
计算属性名1 () {
// 对依赖的数据进行处理,且进行return
return
},
计算属性名2 () {
// 对依赖的数据进行处理,且进行return
return
}
}
}
computed 是vue的配置选项,它的值是一个对象,其中可定义多个计算属性,每个计算属性就是一个函数。
- 属性名称: 计算属性的名称
- 属性的值:计算属性的素材函数
-
-
对需要依赖的数据,进行逻辑上的处理
-
处理完毕后,需要return出去,返回的值就是计算属性的值
使用格式
-
在两个地方使用:
- 模板
-
- 用插值表达式 {{计算属性名}}
- 用其它指令
- 在实例内
-
- this.计算属性名
<div id="app">
<!-- 逻辑复杂 -->
<h3>{{msg.split('').reverse().join('')}}</h3>
<!-- 计算属性 和data类似-->
<h3>{{reverseMsg}}</h3>
</div>
<script src="./vue.js"></script>
<script>
{
data () {
return { msg: 'hi vue' }
},
// 声明计算属性
computed: {
//属性名字(计算属性名称)
//属性的值(计算属性处理函数)
reverseMsg () {
// 对依赖的数据进行处理,且进行return
return this.msg.split('').reverse().join('')
}
}
})
</script>
- 在模板中使用计算属性,和使用data的方式是一样的。
-
- 虽然在计算属性中声明的是函数,但是在模板中使用,当中数据来使用,不需要加括号。
总结:
- 什么时间用:需要对数据进行复杂的逻辑加工,产生新的数据时。
- 定义: 就是一个特殊的配置项computed。其中有多个函数。
- 使用:计算属性的使用方式与data中的数据项一致;
-
- 计算属性-计算:这个值是对原数据进行计算之后得到的新的数据
- 计算属性-属性:它的使用方法与原数据一样。this.计算属性名,{{计算属性名}}
- 执行的时机: 如果计算属性中依赖的数据项变化时,它会自动调用。
其实在模板中来显示一份经过对数据项进行复杂计算之后的结果时,我们有两种解决方案:
- 计算属性
- 函数
函数: methods定义函数,如果在模板中使用,每使用一次,就相当于调用了一次,处理逻辑会重新执行。
计算属性: computed定义计算属性,如果在模板中使用,使用多次,但是如果以来的数据不发生改变,计算属性对应的函数不会重新执行。
计算属性会做缓存,提高渲染的性能
<div id="app">
<h3>计算属性</h3>
<p>计算属性:{{ reversedMsg }}</p>
<p>计算属性:{{ reversedMsg }}</p>
<p>计算属性:{{ reversedMsg }}</p>
<hr>
<p>函数:{{fReversedMsg()}}</p>
<p>函数:{{fReversedMsg()}}</p>
<p>函数:{{fReversedMsg()}}</p>
</div>
<script>
// 计算属性的特点:缓存
// - 如果计算属性所依赖的数据项并没有发生变化,则就算使用多个计算函数,其函数也只执行一次
// 因为它把结果缓存起来了。
{
data() {
return { msg: 'javascript' }
},
methods: {
updateMsg () {
this.msg = "abc"
// 由于计算属性有缓存,虽然在页面上用到三次,但它的函数体只执行一次。
// 对于普通的函数,在页面上用到了三次,它就会执行三次
},
fReversedMsg () {
console.log( '函数 fReversedMsg' )
//把msg的翻转一下
let newMsg = this.msg.split('').reverse().join('')
return newMsg
}
},
computed: {
reversedMsg () {
console.log( 'reversedMsg' )
//把msg的翻转一下
let newMsg = this.msg.split('').reverse().join('')
return newMsg
}
}
})
</script>
总结:
- 计算属性有缓存,提高渲染性能。
- 如果在页面上需要用到 对现有的数据进行加工得到新数据,则时要使用计算属性
计算属性的完整写法
计算属性也是变量, 如果想要直接赋值, 需要使用完整写法=>开启读写模式
computed: {
"属性名": {
set(值){
},
get() {
return "值"
}
}
}
- 计算属性给v-model使用
<template>
<div>
<div>
<span>名字:</span>
<input type="text" v-model="full">
</div>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'full'
}
},
computed: {
full: {
get(){ // 获取full的值
console.log("get方法触发");
return this.msg
},
set(val){ // 要给full赋值
console.log(val)
this.msg = val
}
}
}
}
</script>
过滤器filters
作用
{
data(){},
computed:{},
methods:{},
// 定义过滤器
filters: {
// 属性名称(过滤器名称):属性的值(过滤器处理函数)
myFilter:function(value,其它参数){
return 过滤后的结果
}
}
}
使用格式:
// 不带参数
{{ msg | 过滤器}}
// 带参数
{{ msg | 过滤器(参数)}}
监听属性 watch
监听复杂类型, 或者立即执行监听函数
watch: {
"要监听的属性名": {
immediate: true, // 立即执行
deep: true, // 深度监听复杂类型内变化
handler (newVal, oldVal) {
}
}
}
<template>
<div id="app">
<div class="container">
<!-- 顶部搜索框模块 -->
<div class="form-group">
<div class="input-group">
<h4>品牌管理</h4>
</div>
</div>
<!-- 数据表格 -->
<table class="table table-bordered table-hover mt-2">
<thead>
<tr>
<th>编号</th>
<th>资产名称</th>
<th>价格</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<!-- 如果价格超过100,就有red这个类 -->
<td :class="{ red: item.price > 100 }">{{ item.price }}</td>
<td>{{ item.time | fulTime }}</td>
<td><a href="#" @click="doDel(index)">删除</a></td>
</tr>
<tr style="text-align: center">
共计:{{
doFoach
}}
平均值:{{
doSum / list.length
}}
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="text-align: center" v-show="!list[0]">
暂无数据
</td>
</tr>
</tfoot>
</table>
<!-- 添加资产 -->
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<input
v-model.trim="good.name"
type="text"
class="form-control"
placeholder="资产名称"
/>
</div>
</div>
<div class="form-group">
<div class="input-group">
<input
v-model.number="good.price"
type="text"
class="form-control"
placeholder="价格"
/>
</div>
</div>
<!-- 阻止表单提交 -->
<button class="btn btn-primary" @click.prevent="doAdd">添加资产</button>
</form>
</div>
</div>
</template>
<script>
import "bootstrap/dist/css/bootstrap.css";
import moment from "moment";
export default {
data() {
return {
good: {
name: "", // 名称
price: 0, // 价格
},
list: JSON.parse(localStorage.getItem('list')) || [
{ id: 100, name: "外套", price: 199, time: new Date('2010-08-12')},
{ id: 101, name: "裤子", price: 34, time: new Date('2013-09-01') },
{ id: 102, name: "鞋", price: 25.4, time: new Date('2018-11-22') },
{ id: 103, name: "头发", price: 19900, time: new Date('2020-12-12') }
]
};
},
methods: {
//删除数组里面的对象
doDel(index) {
this.list.splice(index, 1);
},
// 添加对象
doAdd() {
// 解构
const { good, list } = this;
if (good.name == "") return;
// 1.声明id
let id = list.length ? list[list.length - 1].id + 1 : 1;
//2.创建一个对象
let obj = {
id,
name: good.name,
price: good.price,
time: new Date(),
};
// 3.将这个对象添加到数组当中
list.push(obj);
good.name = "";
good.price = "";
},
},
computed: {
doFoach() {
let sum = 0;
this.list.forEach((item) => {
sum += item.price;
});
return sum;
},
doSum() {
return this.list.reduce((sum, item) => sum + item.price, 0);
},
avg() {
return this.doSum / this.list.length;
},
},
filters:{
fulTime(value){
return moment(value).format('YYYY-MM-DD')
}
},
// 侦听器
watch:{
list:{
deep:true,
handler(newVal,oldVal){
localStorage.setItem('list',JSON.stringify(newVal))
}
}
}
};
</script>
<style >
.red {
color: red;
}
</style>
immediate立即监听, deep深度监听, handler固定方法触发