目录
过滤器
(vue2有vue3没有)
1.定义过滤器
<div id="app">
<!-- 管道符 | -->
<p>message 的值是:{{ message | capi }}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue.js'
},
// 过滤器函数,必须被定义到 filters 节点之下
// 过滤器本质上是函数
filters: {
// 注意:过滤器函数形参中的 val,永远都是“管道符”前面的那个值
capi(val) {
// 字符串有 charAt 方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来
// val.charAt(0)
const first = val.charAt(0).toUpperCase()
// 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
const other = val.slice(1)
// 强调:过滤器中,一定要有一个返回值
return first + other
}
}
})
</script>
2.私有过滤器和全局过滤器
在 filters 节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前 vm 实例所控制的 el 区域内使用。
<body>
<div id="app">
<p>message 的值是:{{ message | capi }}</p>
</div>
<div id="app2">
<p>message 的值是:{{ message | capi }}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
/* 如果全局过滤器和私有过滤器名字一致,
此时按照“就近原则”,调用的是”私有过滤器“ */
/* 全局过滤器 */
/* Vue.filter()方法接收两个参数
第一个参数是过滤器的“名字
第二个参数,是全局过滤器的处理函数”*/
Vue.filter('capi', function(str) {
const first = str.charAt(0).toUpperCase()
const other = str.slice(1)
return first + other + '----'
})
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue.js'
},
// 过滤器函数,必须被定义到 filters 节点之下
// 过滤器本质上是函数
filters: {
// 注意:过滤器函数形参中的 val,永远都是“管道符”前面的那个值
capi(val) {
// 字符串有 charAt 方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来
// val.charAt(0)
const first = val.charAt(0).toUpperCase()
// 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
const other = val.slice(1)
// 强调:过滤器中,一定要有一个返回值
return first + other
}
}
})
// ----------------------------------
/* 私有过滤器 */
const vm2 = new Vue({
el: '#app2',
data: {
message: 'dilreba迪丽热巴'
}
})
</script>
</body>
3.连续调用多个过滤器
4.过滤器传参
兼容性:
过滤器仅在 vue 2.x 和 1.x 中受支持,在 vue 3.x 的版本中剔除了过滤器相关的功能。
- 如果使用的是 2.x 版本的 vue,则依然可以使用过滤器相关的功能
- 如果项目已经升级到了 3.x 版本的 vue,官方建议使用计算属性或方法代替被剔除的过滤器功能
5.过滤器的注意点
-
要定义到 filters 节点下,本质是一个函数
-
在过滤器函数中,一定要有 return 值
-
在过滤器的形参中,可以获取到“管道符”前面待处理的那个值
-
如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是”私有过滤器“
watch 侦听器(监视数据的变化)
1.使用 watch 检测用户名是否可用
<body>
<!-- watch 侦听器允许开发者监视数据的变化,
从而针对数据的变化做特定的操作。 -->
<div id="app">
<input type="text" v-model="username">
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script src="./lib/axios.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: ''
},
/* 所有侦听器都应该被定义在watch节点下 */
watch: {
/* 侦听器本质上是个函数,要监视哪个数据的变化,就把数据名作为方法名即可 */
/* 新值在前,旧值在后 */
async username(newVal, oldVal) {
if (newVal === '') return
/* 调用axios发起Ajax请求 */
const {
data: result
} = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
console.log(result)
}
}
})
</script>
</body>
2.immediate 选项
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'admin'
},
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
// 定义对象格式的侦听器
username: {
// 侦听器的处理函数
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
// immediate 选项的默认值是 false
// immediate 的作用是:控制侦听器是否自动触发一次!
immediate: true
}
}
})
</script>
3.deep 选项(深度侦听)
<script>
const vm = new Vue({
el: '#app',
data: {
// 用户的信息对象
info: {
username: 'admin',
address: {
city: '北京'
}
}
},
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
info: {
handler(newVal) {
console.log(newVal)
},
// 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”
deep: true
}
}
})
</script>
4.监听对象单个属性的变化
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
/* 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号 */
'info.username' (newVal) {
console.log(newVal)
}
}
-
方法格式的侦听器
-
缺点1:无法在刚进入页面的时候,自动触发!!!
-
缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器!!!
-
-
对象格式的侦听器
-
好处1:可以通过 immediate 选项,让侦听器自动触发!!!
-
好处2:可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化!!!
-
计算属性
特点:
-
定义的时候,要被定义为“方法”
-
在使用计算属性的时候,当普通的属性使用即可
好处:
-
实现了代码的复用
-
只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值!
所有的计算属性都写在computed节点之下,计算属性在定义的时候,要定义成方法格式
<div class="box" :style="{ backgroundColor: rgb }">
{{ rgb }}
</div>
<button @click="show">按钮</button>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0
},
methods: {
// 点击按钮,在终端显示最新的颜色
show() {
console.log(this.rgb)
}
},
/* 所有的计算属性都写在computed节点之下
计算属性在定义的时候,要定义成方法格式,
最终在这个方法返回一个生成的rgb(x,x,x)的字符串*/
computed: {
rgb: function() {
return `rgb(${this.r},${this.g},${this.b})`
}
}
});
1. 计算属性的特点
- ① 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性
- ② 计算属性会缓存计算的结果,只有计算属性依赖的数据变化时,才会重新进行运算
2.计算属性原理
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
3.购物车案例
<!-- Header头部区域 -->
<Header title="购物车"></Header>
<!-- 循环渲染每一个商品的信息 -->
<!-- 用v-bind动态绑定title属性这样就可以动态改变title的值,不然就是传了一个字符串 -->
<Goods v-for="item in list" :key="item.id"
:id="item.id"
:title="item.goods_name"
:pic="item.goods_img"
:price="item.goods_price"
:state="item.goods_state"
:count="item.goods_count"
@state-change="getNewState"></Goods>
<!-- Footer区域 -->
<Footer
:isfull="fullState"
:amount="amt"
:all="total"
@full-change="getFullState" ></Footer>
================================================================
/* 计算属性 */
computed:{
/* 动态计算出全选状态是true还是false */
fullState(){
return this.list.every(item => item.goods_state === true)
},
/* 已勾选商品的总价格 */
amt(){
/* 先filter过滤,再reduce累加 */
return this.list.filter(item => item.goods_state).reduce((total,item)=>{
return total+=item.goods_price * item.goods_count
},0)
},
/* 已勾选商品的总数量 */
total(){
return this.list.filter(item =>item.goods_state).reduce((t,item) =>{
return t+=item.goods_count
},0)
}
},