Vue学习计划-Vue2--Vue核心(六)过滤器和自定义指令
1. 过滤器
- 定义:对要显示的数据进行特定格式转换再显示(适用于一些简单逻辑的处理)
- 语法:
- 注册过滤器:
Vue.filter(name, callback)
或new Vue{filters:{}}
- 使用过滤器:
{{ xx | 过滤器名 }}
或v-bind:属性 = "xxx | 过滤器名"
- 注册过滤器:
- 备注:
- 过滤器也可以接受额外参数、多个过滤器也可以串联
- 并没有改变原本的数据,是产生新的对应的数据
示例:(局部过滤器)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<!-- 计算属性 -->
<h3>计算属性:</h3>
<p>{{ nameUpper }}</p>
<hr>
<h3>过滤器:</h3>
<!-- 过滤器 -->
<p>{{ name | nameSliceFilter | nameUpperFilter }}</p>
<p>{{ name | nameUpperFilter }}</p>
<hr>
<!-- 过滤器传参数 -->
<!-- <p>{{ longName | nameSliceFilter2(9, '测试传值') }}</p> -->
<p>{{ longName | nameSliceFilter2(9) }}</p>
<p>{{ longName | nameSliceFilter2() }}</p>
<hr>
<!-- 属性过滤器 -->
<p :name="name | nameSliceFilter | nameUpperFilter">属性过滤器文本</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
name: 'abcdefg',
longName: 'abcdefghigklmn'
},
// 计算属性
computed:{
nameSlice(){
return this.name.slice(0,3)
},
nameUpper(){
return this.nameSlice.toUpperCase()
}
},
// 过滤器
filters:{
nameSliceFilter(val){
// console.log(val);
return val.slice(0,3)
},
nameUpperFilter(val){
return val.toUpperCase()
},
// 过滤器传值
// 可以传值,传多少个参数,就接收多少参数,但是第一个参数永远是原本数据
// nameSliceFilter2(val,length, text){
// console.log(val, length,text);
// }
// nameSliceFilter2(val, length){
nameSliceFilter2(val, length = 3){
console.log(val, length);
return val.slice(0, length)
}
}
})
</script>
</body>
</html>
示例:(全局过滤器)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ name | nameSliceFilter }}</p>
<p>{{ longName | nameUpperFilter }}</p>
</div>
<div id="root">
<p>{{ rootName | nameSliceFilter }}</p>
</div>
<script>
// 必须要把全局筛选器提前配置好
Vue.filter('nameSliceFilter',(val)=>{
return val.slice(0,3)
})
// app 实例挂载
new Vue({
el: '#app',
data:{
name: 'abcdefg',
longName: 'abcdefghigklmn'
},
// 过滤器
filters:{
// vue实例内的筛选器优先级更高
// nameSliceFilter(val){
// return val.slice(0,4)
// },
nameUpperFilter(val){
return val.toUpperCase()
}
}
})
// root实例挂载
new Vue({
el: '#root',
data:{
rootName: '这是rootName的值'
},
})
</script>
</body>
</html>
2. 内置指令
-
v-bind
,v-on
,v-show
… -
v-text
指令:- 作用:向其所在的节点中渲染文本内容
- 与差值语法的区别:
v-text
会替换掉节点中的内容,{{ xx }}
不会
示例:
<body> <div id="app"> <!-- 通常 {{ }} 表较多, 更灵活 --> <p>{{ name }}</p> <p v-text="name"></p> <hr> <p>你好, {{ name }}</p> <p v-text="name">你好,</p> <hr> <p>{{ str }}</p> <p v-text="str"></p> </div> <script> new Vue({ el: "#app", data:{ name: "小红", str: '<h3>这是个标题</h3>' } }) </script> </body>
-
v-html
指令:- 作用:向指定节点中渲染包含html结构的内容
- 与插值语法的区别:
v-html
会替换掉节点中所有的内容,{{ xx }}
不会v-html
可以识别html结构
- 严重注意:
v-html
有安全问题:- 在网站上动态渲染任意HTML是非常危险的,容易收到XSS攻击
- 一定要在可信的内容上使用
v-html
,永不要在用户提交的内容上
示例:
<body> <div id="app"> <p>{{ str }}</p> <p v-text="str"></p> <p v-html="str"></p> </div> <script> new Vue({ el: "#app", data:{ str: '<h3>这是个标题</h3>' } }) </script> </body>
-
v-cloak
指令(没有值):- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉
v-cloak
属性 - 使用
css
配合v-cloak
可以解决网速慢时页面展示出{{ xx }}
的问题
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app">
<p v-cloak>{{ name }}</p>
</div>
<script>
const vm = new Vue({
// el: "#app",
data:{
name: '小红'
}
})
setTimeout(() => {
vm.$mount("#app")
}, 5000);
</script>
</body>
</html>
-
v-once
指令:v-once
所在的节点初次动态渲染后,就视为静态内容了- 以后数据的改变不会引起
v-once
所在结构的更新,可以用于优化性能
示例:
<body> <div id="app"> <!-- 需求: 显示初始值,也显示修改后的值 --> <p v-once>初始的n值是:{{ n }}</p> <p>当前的n值是:{{ n }}</p> <button @click="n++">添加</button> </div> <script> new Vue({ el: "#app", data:{ n: 8 } }) </script> </body>
-
v-pre
指令:- 跳过其所在节点的编译过程
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
示例:
<body> <div id="app"> <p v-pre>当前的n值是:</p> <p>{{ n }}</p> <button @click="n++" >添加</button> </div> <script> new Vue({ el: "#app", data:{ n: 8 } }) </script> </body>
-
Vue模板语法有2大类:
- 插值语法:
- 功能: 用于解析标签体内容
- 写法:
{{ xx }}
, xx是js表达式,且可以直接读取到data中的所有属性
- 指令语法:
- 功能:用于解析标签(包括:标签属性,标签体内容,绑定事件…)
- 举例:v-bind:href= ‘xxx’ 或简写 :href= ‘xxx’ xxx同样要写表达式,且可以直接读取到data中的属性
- 备注:Vue中有很多的指令,且形式都是:v-???,此处我们只拿v-bind举个例子
- 插值语法:
3. 自定义指令:
- 本质:是一个函数,不靠返回值获取值,靠操作收到的参数去获取值
- 作用: 操作DOM元素: 例如
v-bind
,v-show
,v-if
等都是对DOM元素进行操作 - 两种方式:
- 函数式:写法简单,不能操作一些细节
directives:{ // big函数何时会被调用? // 1. 指令与元素成功绑定时,(初始时) // 2. 指令所在的模板被重新解析时 big(element, binding){ // element:指令所绑定的元素,可以用来直接操作 DOM // binding:一个对象,包含很多属性 // value: 指令的绑定值 // name: 指令名,不包括 v- 前缀 // expression:字符串形式的指令表达式 console.log(element, binding); element.innerHTML = binding.value * 10 } }
- 对象式: 详细的表明执行到某一特定时期,调用特定函数
directives:{ fbind:{ // 指令与元素成功绑定时,(初始时) bind(element, binding){ // console.log('1',element, binding); element.value = binding.value }, // 指令所在的元素被插入页面时 inserted(element, binding){ // console.log(2,element, binding); element.focus() }, // 指令所在的模板被重新解析时 update(element, binding){ // console.log(3,element, binding) element.value = binding.value } } }
- 定义语法:
- 局部指令:
new Vue({ directives:{指令名: 配置对象} }) 或 new Vue({ directives:{指令名: 回调函数} })
- 全局指令:
Vue.directive(指令名, 配置对象) 或 Vue.directive(指令名, 回调函数)
- 配置对象中常用的3个回调:
bind
: 指令与元素成功绑定时调用inserted
: 指令所在元素被插入页面时调用update
: 指令所在模板结构被重新解析时调用
- 备注:
- 指令定义时不加
v-
, 但使用时要加v-
- 指令中的
this
指向的是window
- 指令名如果是多个单词,要使用
kebab-case
命名方式,不要用camelCase
命名
- 指令定义时不加
示例:(局部指令–对象式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<!-- 需求1:写一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍 -->
<!-- 需求2:写一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素自动获取焦点 -->
<div id="app">
<button @click="n++">操作</button>
<hr>
<input type="text" v-fbind="n"/>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
n: 1
},
directives:{
// 函数式:
// big函数何时会被调用?
// 1. 指令与元素成功绑定时,(初始时)
// 2. 指令所在的模板被重新解析时
// fbind(element, binding){
// element.value = binding.value
// element.focus()
// }
// 对象式:
fbind:{
// 指令与元素成功绑定时,(初始时)
bind(element, binding){
// console.log('1',element, binding);
element.value = binding.value
},
// 指令所在的元素被插入页面时
inserted(element, binding){
// console.log(2,element, binding);
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding){
// console.log(3,element, binding)
element.value = binding.value
}
}
}
})
</script>
</body>
</html>
示例:(局部指令–函数式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<!-- 需求1:写一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍 -->
<!-- 需求2:写一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素自动获取焦点 -->
<div id="app">
<p>{{ name }}</p>
<h3>当前的n值是:<span v-text="n"></span></h3>
<h3>放大10倍后的n值是:<span v-big="n"></span></h3>
<button @click="n++">操作</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data:{
name: '小红',
n: 1
},
directives:{
// big函数何时会被调用?
// 1. 指令与元素成功绑定时,(初始时)
// 2. 指令所在的模板被重新解析时
big(element, binding){
// console.log(element, binding);
console.log('big');
element.innerHTML = binding.value * 10
}
}
})
</script>
</body>
</html>
示例:(全局指令)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<h3>当前的n值是:<span v-text="n"></span></h3>
<!-- <h3>放大10倍后的n值是:<span v-big-number="n"></span></h3> -->
<h3>放大10倍后的n值是:<span v-big="n"></span></h3>
<button @click="n++">操作</button>
</div>
<hr>
<div id="root">
<h3>当前的n值是:<span v-text="n"></span></h3>
<h3>放大10倍后的n值是:<span v-big="n"></span></h3>
<button @click="n++">操作</button>
</div>
<script>
Vue.directive('big',(element, binding)=>{
element.innerHTML = binding.value * 20
})
new Vue({
el: '#app',
data:{
n: 1
},
directives:{
// 多个单词的话,推荐使用kebab-case命名
// 'big-number'(element, binding){
// // console.log(element, binding);
// console.log('big', this) // this指向window
// element.innerHTML = binding.value * 30
// },
// 优先级更高
big(element, binding){
// console.log(element, binding);
console.log('big', this) // this指向window
element.innerHTML = binding.value * 10
}
}
})
new Vue({
el: '#root',
data:{
n: 1
},
})
</script>
</body>
</html>
标签:
javascript
, vue.js
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!