1. 天气案例-计算属性实现-computed-methods
代码语言:javascript复制<div class="box">
<h1>今天天气很 '{{get}}'</h1>
<button @click="show">切换天气</button>
<!-- @click="xxx" 绑定事件时xxx里可以写一些简单语句-->
<!-- <button @click="name = !name">切换天气</button> -->
</div>
new Vue({
el: '.box',
data: {
name: true
},
computed: {
get() {
return this.name ? '炎热' : '凉爽'
}
},
methods: {
show() {
this.name = !this.name
}
}
})
2. 天气案例-监听属性watch实现-immediate
- 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
- 监视的属性必须存在, 才能进行监视
- 监视属性的两种写法:
<div class="box">
<h1>今天天气很 '{{get}}'</h1>
<button @click="show">切换天气</button>
</div>
new Vue({
el: '.box',
data: {
name: true
},
computed: {
get() {
return this.name ? '炎热' : '凉爽'
}
},
methods: {
show() {
this.name = !this.name
}
},
watch: {
name: {
immediate: true, // 初始化时让name调用一下
// 当nams发生改变时 handler会被调用
handler(newvalue, oldvalue) {
console.log('name被修改了', newvalue, oldvalue)
}
}
}
})
// vm.$watch('name', {
// immediate: true,
// handler(newvalue, oldvalue) {
// console.log('name被修改了', newvalue, oldvalue)
// }
// })
3. 天气案例-深度监视实现-watch-deep
- Vue中的watch默认不监视对象内部值的改变(一层)
- 配置deep:true 可以监视对象内部值改变(多层)
- Vue自身可以监视对象内部值的改变, 但Vue提供的watch对象默认不可以
- 使用watch时根据数据的具体结构, 决定是否采用深度监视
<div class="box">
<h1>今天天气很 '{{get}}'</h1>
<button @click="show">切换天气</button>
<hr>
<h1>a的值是{{num.a}}</h1>
<button @click="num.a ">点我让a 1</button>
<h1>b的值是{{num.b}}</h1>
<button @click="num.b ">点我让b 1</button>
<button @click="num= {a: 666, b: 888}">点我彻底替换num</button>
</div>
new Vue({
el: '.box',
data: {
name: true,
num: {
a: 1,
b: 1
}
},
computed: {
get() {
return this.name ? '炎热' : '凉爽'
}
},
methods: {
show() {
this.name = !this.name
}
},
watch: {
name: {
handler(newvalue, oldvalue) {
console.log('name被修改了', newvalue, oldvalue)
}
},
// 监视多级结构中所有属性的变化
'num': {
deep: true,
handler() {
console.log('num被改变了')
}
}
}
})
4. 天气案例-深度监听简写
- 不用deep和immediate属性时, 监听属性$watch才能简写
<div class="box">
<h1>今天天气很 '{{get}}'</h1>
<button @click="show">切换天气</button>
</div>
new Vue({
el: '.box',
data: {
name: true
},
computed: {
get() {
return this.name ? '炎热' : '凉爽'
}
},
methods: {
show() {
this.name = !this.name
}
},
watch: {
// 1. 完整写法
// name: {
// handler(newvalue, oldvalue) {
// console.log('name被修改了', newvalue, oldvalue)
// }
// }
// 2. 简写
name(newvalue, oldvalue) {
console.log('name被修改了', newvalue, oldvalue)
}
}
})
// 3. vm.$watch 的完整写法
// vm.$watch('name', {
// handler(newvalue, oldvalue) {
// console.log('name被修改了', newvalue, oldvalue)
// }
// })
// 4. vm.$watch 的简写
// vm.$watch('name', function (newvalue, oldvalue) {
// console.log('name被修改了', newvalue, oldvalue)
// })
5. computed和watch之间的区别
- computed能完成的功能, watch都可以完成
- watch能完成的功能, computed不一定能完成, 比如: watch可以进行异步操作
- 重要原则:
- 被Vue管理的函数, 最好写成普通函数, 这样this的指向才是vm或组件实例对象
- 所有不被Vue管理的函数, 最好写成箭头函数, 这样this的指向才是vm或组件实例对象
- (定时器的回调函数, ajax的回调函数, Promise的回调函数等..)
<div class="box">
姓: <input type="text" v-model="name"> <br><br>
名: <input type="text" v-model="names"> <br><br>
全名: <span>{{all}}</span>
</div>
new Vue({
el: '.box',
data: {
name: '张',
names: '三',
all: '张-三'
},
watch: {
name(value) {
setTimeout(() => {
this.all = value '-' this.names
}, 1000)
},
names(value) {
this.all = this.name '-' value
}
}
})
6. Vue绑定class样式 :class
- :class=”xxx” xxx可以是字符串、对象、数组
<div class="box">
<!-- 1.绑定class样式: 字符串写法, 适用于 样式类名不确定, 需要动态指定 -->
<div class="basic" :class="color" @click="show">{{name}}</div> <br>
<!-- 2.数组写法, 适用于 要绑定的样式不确定, 名字也不确定 -->
<div class="basic" :class="arr">{{name}}</div> <br>
<!-- 3.对象写法, 适用于 要绑定的样式个数确定, 名字也确定 但要动态决定用不用 -->
<div class="basic" :class="all">{{name}}</div>
</div>
new Vue({
el: '.box',
data: {
name: '小城',
color: 'normal',
arr: ['n1', 'n2', 'n3'],
all: {
n1: false,
n2: true
}
},
methods: {
show() {
let arr = ['happy', 'sad', 'normal']
let index = Math.floor(Math.random()*3)
this.color = arr[index]
}
}
})
7. Vue绑定style样式 :style
- :style=”{fontSize: xxx}” 其中xxx是动态值
- :style=”[a, b]” 其中a,b是样式对象
<div class="box">
<!-- 绑定style样式: 对象写法 -->
<div class="basic" :style="{fontSize: size 'px'}">{{name}}</div> <br>
<div class="basic" :style="fsize">{{name}}</div> <br>
<!-- 绑定style样式: 数组写法 -->
<div class="basic" :style="[fsize]">{{name}}</div> <br>
</div>
new Vue({
el: '.box',
data: {
name: '小城',
size: 20,
fsize: {
fontSize: '30px',
backgroundColor: 'pink'
}
}
})
8. Vue条件渲染v-show-v-else-if-template模板
1. v-show写法: v-show=”表达式”
- 表达式可以是布尔值、表达式、对象
- 适用于: 切换频率较高的场景
- 特点: 不展示的DOM元素只是隐藏了, 并未移除
2. v-if-else写法:
- v-if=”表达式”
- v-else-if=”表达式”
- v-else=”表达式”
- v-if和template配合使用, template标签在页面是不会呈现的
- 表达式可以是布尔值、表达式、对象
- 适用于: 切换频率较低的场景
- 特点: 不展示的DOM元素直接移除
- 注意: v-if可以和v-else-if、v-else一起使用, 但要求结构不能被’打断’
<div class="box">
<!-- v-show条件渲染可以是布尔值 也可以是表达式 -->
<h1 v-show="true">{{name}}</h1>
<h1 v-show="1 == 1">{{name}}</h1>
<!-- v-show条件渲染也可以是对象 -->
<h1 v-show="a">{{name}}</h1>
<!-- v-if条件渲染可以是布尔值 也可以是表达式 -->
<h1 v-if="false">{{name}}</h1>
<h1 v-if="1 == 1">{{name}}</h1>
<!-- 使用v-if条件渲染做交互 -->
<h1>当前n的值是{{n}}</h1>
<button @click="n ">点我让n 1</button>
<div v-if="n == 1">1出来了</div>
<div v-if="n == 2">2出来了</div>
<div v-if="n == 3">3出来了</div>
<!-- v-else和v-else-if的使用 -->
<div v-if="n == 1">1出来了</div>
<div v-else-if="n == 2">2出来了</div>
<div v-else>没有了</div>
<!-- v-if和template配合使用 -->
<template v-if="n === 1">
<div>1哈哈哈</div>
<div>2哈哈哈</div>
<div>3哈哈哈</div>
</template>
</div>
new Vue({
el: '.box',
data: {
name: '小城',
a: true,
n: 0
}
})
9. Vue列表渲染v-for指令
- 用于展示列表数据
- 语法: v-for=”(value, index) in xxx” :key=”id”
- 可以遍历: 数组、对象、字符串、指定次数 后两个用的很少
<div class="box">
<!-- 遍历数组 -->
<h3>遍历数组</h3>
<ul>
<li v-for="(x, index) in arr" :key="index">{{x.name}} - {{x.age}}</li>
</ul>
<!-- 遍历对象 -->
<h3>遍历对象-汽车信息</h3>
<ul>
<li v-for="(value, key) of obj" :key="key">{{value}} - {{key}}</li>
</ul>
<!-- 遍历字符串 -->
<h3>遍历字符串</h3>
<ul>
<li v-for="(value, index) of str" :key="index">{{value}} - {{index}}</li>
</ul>
<!-- 遍历指定次数 -->
<h3>遍历指定次数</h3>
<ul>
<li v-for="(value, index) of 5" :key="index">{{value}} - {{index}}</li>
</ul>
</div>
new Vue({
el: '.box',
data: {
arr: [
{id: 1, name: '张三', age: 18},
{id: 2, name: '李四', age: 19},
{id: 3, name: '王五', age: 20}
],
obj: {
name: '奥迪',
price: '50万',
color: '黑色'
},
str: 'hello'
}
})
10. Vue列表渲染v-for的key作用与原理
1. 虚拟DOM中key的作用
key是虚拟DOM对象的标识, 当数据发生变化时, Vue会根据新数据生成新的虚拟DOM 随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较(Diff算法)
2. 对比规则
(1) 旧虚拟DOM中找到了与新虚拟DOM相同的key: 若虚拟DOM中内容没变, 直接使用之前的真实DOM 若虚拟DOM中内容变了, 则生成新的真实DOM, 随后替换掉页面中之前的真实DOM (2) 旧虚拟DOM中未找到与新虚拟DOM相同的key: 创建新的真实DOM, 随后渲染到页面
3. 用index作为key可能会引发的问题
1. 若对数据进行: 逆序添加、删除等破环顺序操作: 会产生没有必要的真实DOM ==> 界面效果没问题, 但效率低 2. 如果结构中还包含输入流的DOM: 会产生错误DOM更新 ==> 界面有问题
4. 开发中如何选择key?
1.最好使用每条数据的唯一标识作为key, 比如id、手机号、学号等唯一值 2.如果不存在对数据的逆序添加、删除等破坏顺序的操作, 仅用于渲染列表、展示, 使用index作为key是没有问题的
5. 面试题: React、Vue中的key有什么作用? (key内部原理)
代码语言:javascript复制1. 虚拟DOM中key的作用: key是虚拟DOM对象的标识, 当数据发生变化时, Vue会根据新数据生成新的虚拟DOM 随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较(Diff算法)
<div class="box">
<ul>
<li v-for="(x, index) in arr" :key="index">
{{x.name}} - {{x.age}}
<input type="text">
</li>
</ul>
<button @click="add">添加一个老刘</button>
</div>
new Vue({
el: '.box',
data: {
arr: [
{id: 1, name: '张三', age: 18},
{id: 2, name: '李四', age: 19},
{id: 3, name: '王五', age: 20}
]
},
methods: {
add() {
let add = {id: 4, name: '老刘', age: 30}
this.arr.unshift(add)
}
}
})
11. Vue的列表过滤
代码语言:javascript复制<div class="box">
<ul>
<li v-for="(x, index) in words" :key="index">
{{x.name}} - {{x.age}} - {{x.sex}}
</li>
</ul>
模糊搜索: <input type="text" placeholder="请输入名字" v-model="word">
</div>
new Vue({
el: '.box',
data: {
word: '',
arr: [
{id: 1, name: '马冬梅', age: 18, sex: '女'},
{id: 2, name: '周冬雨', age: 19, sex: '女'},
{id: 3, name: '周杰伦', age: 20, sex: '男'},
{id: 3, name: '温兆伦', age: 21, sex: '男'}
]
},
computed: {
words() {
console.log(this.word)
return this.arr.filter((index) => {
return index.name.indexOf(this.word) !== -1
})
}
}
})
// new Vue({
// el: '.box',
// data: {
// word: '',
// words: [],
// arr: [
// {id: 1, name: '马冬梅', age: 18, sex: '女'},
// {id: 2, name: '周冬雨', age: 19, sex: '女'},
// {id: 3, name: '周杰伦', age: 20, sex: '男'},
// {id: 3, name: '温兆伦', age: 21, sex: '男'}
// ]
// },
// watch: {
// // 1. watch的简写实现, 但有bug: 页面打开数据没有, 搜索正常
// // word(value) {
// // console.log('word被改了', value)
// // this.words = this.arr.filter((index) => {
// // return index.name.indexOf(value) !== -1
// // })
// // }
// // 2. 使用watch的完整写法实现, immediate可以默认调用一次
// word: {
// immediate: true,
// handler(value) {
// console.log('word被调用了', value)
// this.words = this.arr.filter((index) => {
// return index.name.indexOf(value) !== -1
// })
// }
// }
// }
// })
12. Vue的列表过滤与列表排序
代码语言:javascript复制// 使用computed计算属性实现
<div class="box">
<ul>
<li v-for="(x, index) in words" :key="index">
{{x.name}} - {{x.age}} - {{x.sex}}
</li>
</ul>
模糊搜索: <input type="text" placeholder="请输入名字" v-model="word">
<button @click="type = 2">年龄升序</button>
<button @click="type = 1">年龄降序</button>
<button @click="type = 0">原顺序</button>
</div>
new Vue({
el: '.box',
data: {
word: '',
type: 0, // 0原顺序 1降序 2升序
arr: [
{id: 1, name: '马冬梅', age: 31, sex: '女'},
{id: 2, name: '周冬雨', age: 30, sex: '女'},
{id: 3, name: '周杰伦', age: 20, sex: '男'},
{id: 3, name: '温兆伦', age: 21, sex: '男'}
]
},
computed: {
words() {
console.log(this.word)
let arr = this.arr.filter((index) => {
return index.name.indexOf(this.word) !== -1
})
// 判断是否需要排序 使用.sort方法操作
if (this.type) {
arr.sort((a, b) => {
return this.type == 1 ? b.age-a.age : a.age-b.age
})
}
return arr
}
}
})
13. data数据里的数组更新时的一个问题
代码语言:javascript复制// Vue数据层面变了, 但未检测到数据改变
<div class="box">
<ul>
<li v-for="(x, index) in arr" :key="index">
{{x.name}} - {{x.age}} - {{x.sex}}
</li>
</ul>
<button @click="news">更新马冬梅的信息</button>
</div>
new Vue({
el: '.box',
data: {
arr: [
{id: 1, name: '马冬梅', age: 31, sex: '女'},
{id: 2, name: '周冬雨', age: 30, sex: '女'},
{id: 3, name: '周杰伦', age: 20, sex: '男'},
{id: 3, name: '温兆伦', age: 21, sex: '男'}
]
},
methods: {
news() {
// this.arr[0].name = '马老师'
// this.arr[0].age = 50
// this.arr[0].sex = '男'
// 通过数组下标直接赋值是不行的
// this.arr[0] = {id: 1, name: '马老师', age: 50, sex: '男'}
// 这里使用数组.splice方法替换
this.arr.splice(0, 1, {id: 1, name: '马老师', age: 50, sex: '男'})
}
}
})
14. Vue检测数据改变原理
- Vue利用递归会一直在data属性里创建get/set
<div class="box">
<h1>{{name}}</h1>
<h1>{{names}}</h1>
</div>
new Vue({
el: '.box',
data: {
name: '小城',
names: '冲冲冲',
a: {
b: 'ok'
},
c: [1, 2]
}
})
15. 模拟Vue对象数据监测
代码语言:javascript复制let data = {
name: '尚硅谷',
age: '北京'
}
console.log(data)
function Observer(obj) {
// 汇总对象所有属性形成一个数组
let keys = Object.keys(obj)
console.log(keys)
keys.forEach((k) => {
// 此处this指向Observer实例对象
Object.defineProperty(this,k, {
// 数据代理
get() {
return obj[k]
},
// 数据劫持
set(value) {
console.log('data属性被改了, 我去解析模板, 生成虚拟DOM了')
obj[k] = value
}
})
})
}
// 创建一个监视的实例对象, 用于监视data属性变化
let obs = new Observer(data)
// 准备一个vm实例对象 模拟Vue的_data
let vm = {}
vm._data = data = obs
console.log(obs)
console.log(vm)
// 死循环了
// Object.defineProperty(data, 'age', {
// get() {
// return data.age
// },
// set(val) {
// data.age = val
// }
// })
16. Vue.set方法的使用
- Vue.set方法: 向响应式对象添加属性
- 如果想给后期追加的属性添加响应式处理, 调用以下两个方法都可以
- 语法: Vue.set(目标对象, ‘属性名’, ‘属性值’)
- vm.$set(目标对象, 添加的属性名, 属性值)
- 注意对象不能为Vue实例 或者Vue实例的根数据对象
- 向响应式对象中添加一个property, 并确保这个新property同样是响应式的, 且触发视图更新
- 它必须用于向响应式对象上添加新property, 因为Vue无法探测普通的新增property
<div class="box">
<h2>{{name}}</h2>
<hr>
<button @click="add">点我添加一个性别属性, 默认值为男</button>
<h2>学生姓名: {{obj.name}}</h2>
<h2 v-if="obj.sex">学生性别: {{obj.sex}}</h2>
<h2>学生年龄: 真实 {{obj.ages.age1}} 对外 {{obj.ages.age2}}</h2>
<h2>朋友们</h2>
<ul>
<li v-for="(x, index) in arr" :key="index">{{x.name}} - {{x.age}}</li>
</ul>
</div>
new Vue({
el: '.box',
data: {
name: '小城',
obj: {
name: '小明',
// sex: '男', // undefined不显示页面
ages: {
age1: 10,
age2: 20
}
},
arr: [
{name: '张三', age: 30},
{name: '李四', age: 40}
]
},
methods: {
add() {
// Vue.set(this.obj, 'sex', '男')
this.$set(this.obj, 'sex', '男')
}
}
})
17. 模拟Vue数组数据监测与原理
- 通过数组下标修改数组中的元素, 默认情况是没有添加响应式处理的, 怎么解决?
1. 第一种方案
- 通过 Vue.set(数组对象, 下标, 值)
- 通过 vm.$set(数组对象, 下标, 值)
2. 第二种方案
代码语言:javascript复制通过这7个方法给数组添加响应式处理: push、pop、shift、unshift、splice、sort、reverse Vue将被侦听的数组的变更方法进行了包裹, 所以它们也将会触发视图更新
<div class="box">
<h2>{{name}}</h2>
<hr>
<button @click="add">点我添加一个性别属性, 默认值为男</button>
<h2>学生姓名: {{obj.name}}</h2>
<h2 v-if="obj.sex">学生性别: {{obj.sex}}</h2>
<h2>学生年龄: 真实 {{obj.ages.age1}} 对外 {{obj.ages.age2}}</h2>
<h2>朋友们</h2>
<ul>
<li v-for="(x, index) in arr" :key="index">{{x.name}} - {{x.age}}</li>
</ul>
<!-- 模拟Vue数组数据监测 -->
<h2>爱好</h2>
<ul>
<li v-for="(x, index) in like" :key="index">{{x}}</li>
</ul>
</div>
new Vue({
el: '.box',
data: {
name: '小城',
obj: {
name: '小明',
// sex: '男',
ages: {
age1: 10,
age2: 20
}
},
like: ['唱歌', '跳舞', '篮球'],
arr: [
{name: '张三', age: 30},
{name: '李四', age: 40}
]
},
methods: {
add() {
// Vue.set(this.obj, 'sex', '男')
this.$set(this.obj, 'sex', '男')
}
}
})
18. 总结Vue监测数据原理/对象/数组
1. Vue监测数据的原理: Vue会监视data中所有层次的数据
2. 如何监测对象中的数据?
通过setter实现监视, 且要在new Vue时就传入要监测的数据 (1) 对象中 后追加的属性, Vue默认不做响应式处理 (2) 如果给 后添加的属性做响应式, 请使用以下API: Vue.set(目标对象, 添加的属性名, 属性值) 或 vm.$set(目标对象, 添加的属性名, 属性
3. 如何监测数组中的数据?
通过包裹数组更新元素的方法实现, 本质就是做了两件事: (1) 调用原生对应的JS方法对数组进行更新 (2) 重新解析模板, 进而更新页面
4. 在Vue修改数组中的某个元素一定要用以下方法:
代码语言:javascript复制使用这些API: push、pop、shift、unshift、splice、sort、reverse Vue.set() 或 vm.$set() 注意: Vue.set 和 vm.$set 不能给vm或vm的根数据对象 添加属性 !!!
<div class="box">
<h3>姓名: {{xs.name}}</h3>
<h3>年龄: {{xs.age}}</h3>
<h3 v-if="xs.sex">性别: {{xs.sex}}</h3>
<h3>爱好: </h3>
<ul>
<li v-for="(x, index) in xs.like" :key="index">{{x}}</li>
</ul>
<h3>朋友们: </h3>
<ul>
<li v-for="(x, index) in xs.arr" :key="index">{{x.name}} - {{x.age}}</li>
</ul>
<button @click="xs.age ">年龄 1岁</button> <br>
<button @click="addName">添加性别属性: 默认值: 男</button> <br>
<button @click="xs.sex = '女'">修改性别属性: 女</button> <br>
<button @click="addArr">在列表首位添加一个朋友</button> <br>
<button @click="addArrs">修改第一个朋友名字为: 爱坤</button> <br>
<button @click="addLike">添加一个爱好</button> <br>
<button @click="addLikes">修改第一个爱好为: 开车</button> <br>
<button @click="addFilter">过滤掉爱好中的篮球</button>
</div>
new Vue({
el: '.box',
data: {
xs: {
name: '小城',
age: 18,
like: ['唱歌', '跳舞', '篮球'],
arr: [
{ name: '张三', age: 30 },
{ name: '李四', age: 40 }
]
}
},
methods: {
addName() {
Vue.set(this.xs, 'sex', '男')
},
addArr() {
this.xs.arr.unshift({name: '蔡徐坤', age: 20})
},
addArrs() {
// Vue.set(this.xs.arr[0], 'name', '爱坤')
this.xs.arr[0].name = '爱坤'
this.xs.arr[0].age = 10
},
addLike() {
this.xs.like.push('学习')
},
addLikes() {
// this.xs.like.splice(0, 1, '开车')
// Vue.set(this.xs.like, 0, '开车')
this.$set(this.xs.like, 0, '开车')
},
addFilter() {
this.xs.like = this.xs.like.filter((x) => {
return x !== '篮球'
})
}
}
})
19. Vue的收集表单数据-v-model-lazy-number-trim
- 若: input type=”text” 则v-model收集的是value值, 用户输入的就是value值
- 若: input type=”radio” 则v-model收集的是value值, 且要给标签配置value值
- 若: input type=”checked”
- (1) 没有配置input的value属性, 那么收集的就是checked(勾选true/未勾选false)
- (2) 配置input的value属性
- v-model的初始值是非数组, 那么收集的就是checked(勾选true/未勾选false)
- v-model的初始值是数组, 那么收集的就是value组成的数组
代码语言:javascript复制备注: v-model的三个修饰符: lazy: 失去焦点再收集数据 number: 输入字符串转换为number类型 trim: 空格过滤
<div class="box">
<form action="" @submit.prevent="arr">
账号: <input type="text" v-model.trim="obj.user"> <br><br>
密码: <input type="password" v-model="obj.pass"> <br><br>
年龄: <input type="number" v-model.number="obj.age"> <br><br>
性别:
男: <input type="radio" name="sex" v-model="obj.sex" value="nan">
女: <input type="radio" name="sex" v-model="obj.sex" value="nv"> <br><br>
爱好:
学习<input type="checkbox" v-model="obj.like" value="xx">
唱歌<input type="checkbox" v-model="obj.like" value="cg">
篮球<input type="checkbox" v-model="obj.like" value="lq"> <br><br>
所属校区:
<select v-model="obj.city">
<option value="">请选择校区</option>
<option value="bj">北京</option>
<option value="ss">上海</option>
<option value="sz">深圳</option>
<option value="wh">武汉</option>
</select> <br><br>
其他信息: <textarea v-model.lazy="obj.text"></textarea> <br><br>
<input type="checkbox" v-model="obj.check">阅读并接受<a href="">《用户协议》</a>
<button>提交</button>
</form>
</div>
new Vue({
el: '.box',
data: {
obj: {
user: '',
pass: '',
age: '',
sex: 'nan',
like: [],
city: 'ss',
text: '',
check: ''
}
},
methods: {
arr() {
console.log(this._data.obj)
console.log(JSON.stringify(this._data.obj))
}
}
})
20. Vue的过滤器-filter-dayjs库
过滤器定义: 对要显示的数据进行特殊格式化后再显示(适应于一些简单逻辑处理)
过滤器语法:
- 注册过滤器: Vue.filter(name, function) 或 new Vue{filters: {}}
- 使用过滤器: {xxx | 过滤器名} 或 v-bind:属性 = ‘xxx’ | 过滤器名
备注:
- 过滤器也可以接收额外参数, 多个过滤器也可以串联
- 并没有改变原本的数据, 是产生新的对应数据
- 分全局过滤器、局部过滤器
<script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.7/dayjs.min.js"></script>
<div class="box">
<h2>显示格式化后的时间</h2>
<h2>{{time}}</h2>
<!-- 计算属性实现 -->
<h2>计算后的时间: {{times}}</h2>
<!-- methods方法实现 -->
<h2>计算后的时间: {{times1()}}</h2>
<!-- Vue过滤器实现 -->
<h2>计算后的时间: {{time | formater}}</h2>
<!-- Vue过滤器实现(传参) -->
<h2>计算后的时间: {{time | formater('YYYY-MM-DD')}}</h2>
<!-- Vue过滤器实现(传参 过滤器串联) -->
<h2>计算后的时间: {{time | formater('YYYY-MM-DD') | myslice}}</h2>
<!-- Vue过滤器 应用在v-bind上(很少) -->
<h2 :value="name | myslice">尚硅谷</h2>
</div>
<div class="box1">
<!-- Vue全局过滤器实现 (传参 过滤器串联) -->
<h2>计算后的时间: {{name | myslices}}</h2>
</div>
// 配置全局过滤器
Vue.filter('myslices', function (value) {
return value.slice(0, 4)
})
new Vue({
el: '.box',
data: {
time: 1687892086472,
name: '你好, 尚硅谷'
},
computed: {
times() {
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
methods: {
times1() {
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
filters: {
formater(value, str = 'YYYY年MM月DD日 HH:mm:ss') {
console.log(value)
return dayjs(value).format(str)
},
myslice(value) {
return value.slice(0, 4)
}
}
})
new Vue({
el: '.box1',
data: {
name: '小城故事, 你好'
}
})