Vue computed计算和watch监听
computed计算、watch监听、类的绑定、样式绑定
目录
class样式悬停 :class=“{‘active‘:循环项==index}“ ,切换
watch,computed和methods 的关系
1. watch和computed都是以Vue的依赖追踪机制为基础 的,它们都试图处理这样一件事情:当某一个数据(称它为依赖数据)发生变化的时候,所有依赖这个数据的“相关”数据“自动”发生变化,也就是自动调用相关的函数去实现数据的变动。
2.对methods:methods里面是用来定义函数的,很显然,它需要手动调用才能执行。而不像watch和computed那样,“自动执行”预先定义的函数
watch和computed各自处理的数据关系场景不同
1. watch 擅长处理的场景: 一个数据影响多个数据
2. computed擅 长处理的场景: 一个数据受多个数据影响
watch和computed的区别
1、功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。
2、是否调用缓存:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调。
3、是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。
4、computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)
5、使用场景:computed----当一个属性受多个属性影响的时候,使用computed-----购物车商品结算。watch–当一条数据影响多条数据的时候,使用watch-----搜索框.
computed计算,从现有数据计算出新的数据
computed是计算属性,主要作用是把数据存储到内存中,减少不必要的请求,还可以利用computed给子组件的data赋值。
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理。
<body>
<div id="app">
<input type="text" v-model.number="n1">
<input type="text" v-model.number="n2">
<p>{{n3}}</p>
<p>{{rstr}}</p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
computed: {
//从现有的n1与n2计算出n3
"n3": function () {
return this.n1 + this.n2;
},
//rstr是从现有的str算出
rstr() {
return this.str.split('').reverse().join("");
}
},
data() {
return {
n1: 1,
n2: 2,
str: "明天放假15天"
}
}
})
</script>
案例:水果名称过滤
<body>
<div id="app">
<h1>搜索水果</h1>
<input type="text" v-model="keyword">
<div v-for="(item,index) in flist" :key="index">{{item}}</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
computed: {
flist() {
// 如果搜索关键字为空,返回所有的水果
if (this.keyword.trim() === "") {
return this.list;
} else {
var temp = this.list.filter(item => {
// 当fruit里面个某一项文字包含keyword文字那么就把当前数据保留
// filter过滤,遍历返回为真 保留,为false就过滤掉
// 当通过indexOf查字符串时候返回-1 代表找不到
// 不等于-1代表找到了
if (item.indexOf(this.keyword) != -1) {
return true;
} else {
return false;
}
});
return temp;
}
}
},
data() {
return {
keyword: "",
list: ["苹果", "沙果", "海棠", "野樱莓", "枇杷", "欧楂", "山楂", "香梨", "雪梨 等)", "温柏", "蔷薇果", "花楸", "杏", "樱桃", "桃", "水蜜桃", "油桃", "蟠桃", "李子", "梅子(青梅)", "西梅", "白玉樱桃 ", "黑莓", "覆盆子", "云莓", "罗甘莓", "白里叶莓", "草莓", "菠萝莓", "橘子", "砂糖桔", "橙子", "柠檬", "青柠", "柚子", "金桔", "葡萄柚", "香橼", "佛手", "指橙", "黄皮果", "哈密瓜", "香瓜", "白兰瓜", "刺角瓜"]
}
},
});
// 通过计算 keyword与list 算出flist
// 如果list中的某一项包含 keyword关键字,在flist保留该项
// includes检测是否包含某个字符串 indexOf()不等于-1
// filter过滤数组
// trim 移除字符串两端的空格
</script>
computed计算总价
<body>
<div id="app">
<table border="1">
<tr>
<th>选择</th>
<th>商品名称</th>
<th>价格</th>
<th>数量</th>
</tr>
<tr v-for="item in goods" :key="item.name">
<!-- 选项框 -->
<td><input type="checkbox" v-model="item.sel"></td>
<!-- 商品名称 -->
<td>{{item.name}}</td>
<!-- 价格 -->
<td>{{item.price}}</td>
<!-- 数量 -->
<td><button @click="item.num++">{{item.num}}</button></td>
</tr>
</table>
<p>总价:{{total}},共{{count}}件</p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
goods: [{
name: "javacript入门",
price: 20,
num: 2,
sel: true,
}, {
name: "vue实战",
price: 80,
num: 5,
sel: false,
}]
}
},
computed: {
total() {
//返回的默认总价
var n = 0;
this.goods.forEach(item => {
//累加数量 * 加载
if (item.sel)
n += item.price * item.num;
})
//返回
return n;
},
count() {
//返回默认件数
var n = 0;
this.goods.forEach(item => {
//累加数量
if (item.sel)
n += item.num;
})
//返回
return n;
}
}
});
</script>
监听
定义:监听数据的变化,执行回调函数
值类型监听
watch:{
"num":function(){
......
}
}
案例 计算
<body>
<div id="app">
<h1>watch监听-计算</h1>
<input type="text" v-model.number="obj.pre">
<select name="" id="" v-model="obj.type">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" v-model.number="obj.next">
={{obj.result}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
obj: {
pre: 1,
type: "+",
next: 1,
result: 2,
}
}
},
watch: {
//引用类型数据监听需要添加deep选项
//oval和nval都是最新的值
"obj": {
handler(nval, oval) {
// 只要obj发生变化重新计算result的值
this.obj.result = eval(`${this.obj.pre}${this.obj.type}${this.obj.next}`)
},
deep: true,
}
}
});
</script>
引用类型监听
nval 数据最新的值
oval 数据之前的值
watch:{
obj:{
handler(nval){...},
deep:true
}
}
案例
<body>
<div id="app">
<h1>watch监听</h1>
<button @click="obj.pre++">{{obj.pre}}</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
obj: {
pre: 5,
}
}
},
watch: {
//引用类型数据监听需要添加deep选项
//oval和nval都是最新的值
"obj": {
handler(nval, oval) {
console.log("数据发生变化", oval, nval);
},
deep: true,
}
}
});
</script>
案例-watch监听todolist本地存储
<body>
<div id="app">
<input type="text" @keyup.enter="addItem">
<!-- 遍历数据list -->
<h3>未完成{{undolist.length}}</h3>
<div v-for="item in undolist" :key="item.title">
<input type="checkbox" v-model="item.done">
<span>{{item.title}}</span>
<button @click="delItem(item)">x</button>
</div>
<h3>已经完成{{donelist.length}}</h3>
<div v-for="item in donelist" :key="item.title">
<input type="checkbox" v-model="item.done">
<span>{{item.title}}</span>
<button @click="delItem(item)">x</button>
</div>
</div>
<script>
new Vue({
el: "#app",
computed: {
// 通过计算list算出undolist没有完成的列表
undolist() {
// 通过list过滤 返回item.done值为false的所有元素
return this.list.filter(item => !item.done);
},
donelist() {
// 返回保留item.done值为true的元素
return this.list.filter(item => item.done);
}
},
methods: {
// 删除元素
delItem(item) {
// 查找item在list的下标
var ind = this.list.indexOf(item);
// 进行删除
this.list.splice(ind, 1);
},
// 添加元素
addItem(e) {
// e.target输入的文本框
// e.target.value 文本框的值
this.list.unshift({ done: false, title: e.target.value })
// 清空文本框的内容
e.target.value = "";
}
},
data() {
return {
//从本地localStorage获取数据,获取不到就用默认
list: JSON.parse(localStorage.getItem("done") || '[{ "done": true, "title":"学习html" }]')
}
},
watch: {
"list": {
handler() {
//监听list的变化,存储todo数据
localStorage.setItem("done", JSON.stringify(this.list))
},
deep: true,
}
},
})
// 目标:1 在文本框输入文字,按回车,文字添加到list里面
// 目标:2 单击x 删除当前行
// unshift在数组的前面添加一个元素
// splice(n,m,j) 从第n个删除m个,添加j
// indexOf(item) 查找item在列表的下标
</script>
localStorage的使用
localStorage.getItem(key):获取指定key本地存储的值
localStorage.setItem(key,value):将value存储到key字段
在A页面中先存储:
var imgs = obj_mainform.archivesId //声明个变量存储下数据
localStorage.setItem('key',imgs); //将变量imgs存储到name字段
在B页面中使用:
var naid = localStorage.getItem("key"); //获取指定key本地存储的值
类的绑定
1.给v-bind:class 设置一个对象,可以动态地切换class,例如:
<div id="app">
<div :class="{'active':isActive}"></div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isActive:true
}
})
</script>
最终渲染结果: <div class="active"></div>
2、对象中也可存在多个属性,动态切换class,:class 可以合class共存
<div id="app">
<div class="static" :class="{'active':isActive,'error':isError}"></div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isActive:true,
isError:false
}
})
</script>
最终渲染结果: <div class="static active"></div>
class样式悬停 :class=“{‘active‘:循环项==index}“ ,切换
<div class="picBtn">
<span v-for="(item, index) in listBtn" :key="index"
:class="{ active: btnActive === index }" @click="choosePic(index)">
{{ item }}
</span>
</div>
data
listBtn:['图一','图二'],
btnActive:0,//默认选中图一
methods
choosePic(index){
this.btnActive = index;//获得点击元素的index
},
数组语法
我们可以把一个数组传给 :class,以应用一个 class 列表:
<div :class="[activeClass, errorClass]"></div>
<style>
.active {
color: aqua;
background-color: blanchedalmond;
}
.big {
font-size: large;
}
.bold {
color: red;
}
</style>
<body>
<div id="app">
<button @click="flag=!flag" v-bind:class="flag?active:''">开关</button>
<button @click="flag=!flag" :class="{'active':flag,'big':isbig}">开关</button>
<!-- 数组方式 -->
<p :class="classlist" 这是行测试文本></p>
</div>
<script>
new Vue({
el: "#app",
data() {
return {
flag: true,
isbig: true,
classlist: ['bold', 'big', 'active']
}
}
})
</script>
样式绑定
<body>
<div id="app">
<input type="color" v-model="color">
<input type="range" min="1" max="200" v-model="height">
<!-- 数组方式 -->
<p :style="{'fontSize':'48px','backgroundColor':color,'lineHeight':height+'px'}">样式的绑定</p>
</div>
<script>
new Vue({
el: "#app",
data() {
return {
color: "#f00",
height: 80
}
}
})
</script>
Style内联样式
对象语法:
CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
数组语法
<div :style="[baseStyles, overridingStyles]"></div>
回顾js数组 方法
更多推荐
所有评论(0)