一.vue- 收集表单数据
使vue可以发现表单中的变化
1.若<input type="text">
,则v-model收集的是value值,用户输入的就是value值。
<label for="acccount">账号:</label>
<input type="text" v-model="userinfo.account" id="account"><br>
<label for="mima">密码:</label>
<input type="password" v-model="userinfo.pwd" id="mima"><br>
2.若<input type="radio">
,是单选框,必须要有相同的name,v-model也相同,并需要给标签分别添加不同的value值。
性别:男<input type="radio" name="sex" v-model="userinfo.sex" value="male">
女<input type="radio" name="sex" v-model="userinfo.sex" value="female">
3.若```,是复选框,必须要有相同的name,v-model,并给标签分别添加不同的value值。(check="checked"表示默认勾选)。
**注意:v-model的初始值必须为数组
爱好:学习<input type="checkbox" name="hobby" v-model="userinfo.hobby" value="study">
打游戏<input type="checkbox" name="hobby" v-model="userinfo.hobby" value="game">
吃饭<input type="checkbox" name="hobby" v-model="userinfo.hobby" value="eat">
4.下拉列表
<select v-model="userinfo.city">
<option>请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="guangzhou">广州</option>
</select>
5.文本域
<textarea v-model="userinfo.other"></textarea>
6.同意及提交
<input type="checkbox" v-model="userinfo.agree">阅读并接受<a href="http://www.baidu.com">《用户协议》</a><br>
<button>提交</button>
7.收集信息
//想要实现点击按钮之后收集表单的信息:首先给form绑定事件,然后用methods来调用方法,输出表单信息
<div id="root">
<form @submit="demo">
<!--省略1-6的内容-->
</form>
<script>
const vm=new Vue({
data:{
userinfo:{
account:'',
pwd:'',
sex:'',
hobby:[], //这里是数组
city:"",
other:"",
agree:""
}
},
methods:{
demo(){
console.log(JSON.stringify(this.userinfo))
}
}
})
vm.$mount("#root")
</script>
二.v-model修饰符
基本上和事件修饰符一样
1.lazy
开发者工具不同步手机用户输入的信息,当光标不再显示在所输入的内容区域时,统一呈现在开发者工具对应位置,而不是输一个呈现一个。
2.number
年龄必须以数字呈现,如下代码:
年龄:<input type="number" v-model.number="age">
这个地方有两个number,input type="number
表示文本框只能输入数字,但在开发者工具中输入的字母还能被呈现。
所以,需要用到v-model.number="age"
,表示开发者工具对应位置也只能输入数字,不能出现字母。两处缺一不可。
3.trim
对于用户输入的首尾空格进行过滤,使开发者工具中不会显示空格。
三.过滤器
过滤器就是对要显示的数据进行特定格式化后再显示。
Date.now()可以获取当前时间的时间戳,时间戳展示出来并不能看懂,需要对其格式化以达到所要求的某种格式。
如图所要达到的效果:
在进行操作之前,需要引入一个第三方库:day.js,可以对日期进行处理等操作以及显示日期。
day.js提供了对时间格式化操作的代码,如下:
dayjs([时间戳]).format("YYYY-MM-DD HH:mm:ss")
1.使用computed方法对时间进行格式化处理
如下vue模板:
<div id="root">
<h2>当前时间是:{{time}}</h2>
</div>
computed方法:
//用computed方法实现格式转换
const vm=new Vue({
data:{
time:1621561377603
},
computed:{
timeFormat(){
return dayjs(this.time).format("YYYY-MM-DD HH:mm:ss") //格式化
}
}
})
vm.$mount("#root")
2.使用methods方法对时间进行格式化处理
vue模板:
<div id="root">
<h2>当前时间是:{{getTimeFormat()}}</h2> <!-- 注意:要加括号,methods调用的是一个方法 -->
</div>
methods调用
methods:{
getTimeFormat(){
return dayjs(this.time).format("YYYY-MM-DD HH:mm:ss")
}
}
3.用过滤器实现
time:时间戳
timeFormat:自定义一个过滤器的名字
格式:time+空格+管道符+空格+自定义名字
filters:过滤器的配置项
实现原理:time作为一个参数传递给timeFormat,调用timeFormat函数,得到的返回值给{{time | timeFormat}}
<body>
<div id="root">
<h2>当前时间是:{{time | timeFormat}}</h2>
</div>
</body>
<script>
const vm=new Vue({
data:{
time:1621561377603
},
filters:{
timeFormat(value){ //注意,这里有一个参数
return dayjs(this.time).format("YYYY-MM-DD HH:mm:ss")
}
}
})
vm.$mount("#root")
</script>
3-1过滤器的参数问题
效果图:
若想要达成这种效果,两种方式:一是直接返回return dayjs(this.time).format(“YYYY年MM月DD日”) ,这里用另一种方式来更好地了解过滤器中的参数传递问题。
<div id="root">
<h2>当前时间是:{{time | timeFormat("YYYY年MM月DD日")}}</h2>
</div>
</body>
<script>
const vm=new Vue({
data:{
time:1621561377603
},
filters:{
timeFormat(value,str){
return dayjs(this.time).format(str)
}
}
})
vm.$mount("#root")
但是,当想要3.和3-1两种效果都实现时,用3-1的方法就会导致3.错误,原因是3.中并没有str,它并不能格式化str。
因此,可以给str一个值,若传参数就用所传参数,否则就用str的值
<div id="root">
<h2>当前时间是:{{time | timeFormat}}</h2>
<h2>当前时间是(用年月日表示):{{time | timeFormat("YYYY年MM月DD日")}}</h2>
</div>
</body>
<script>
const vm=new Vue({
data:{
time:1621561377603
},
filters:{
timeFormat(value,str="YYYY-MM-DD HH:mm:ss"){ //这里给str传递了一个值
return dayjs(this.time).format(str)
}
}
})
vm.$mount("#root")
效果展示:
3-2过滤器串联
要求实现YYYY年MM月DD日中只保留YYYY年,有多种方式,但这里使用能体现过滤器串联的方式。
串联过滤器实现原理:time作为一个参数传递给timeFormat,调用timeFormat函数,得到的返回值给myslice
<div id="root">
<h2>当前时间是:{{time | timeFormat("YYYY年MM月DD日") | myslice}}</h2>
</div>
</body>
<script>
const vm=new Vue({
data:{
time:1621561377603
},
filters:{
timeFormat(value,str){
return dayjs(this.time).format(str)
},
myslice(value){
return value.slice(0,5)
}
}
})
vm.$mount("#root")
3-3全局过滤器
过滤器串联的两个过滤器只有所在的Vue实例可以用,属于局部过滤器,当再创建一个Vue实例,这两个过滤器就不能使用。因此,这种情况下,把它转化为全局过滤器。
vue模板部分
<div id="root">
<h2>当前时间是:{{time | timeFormat("YYYY年MM月DD日") | myslice}}</h2>
</div>
<div id="root2">
<h2>{{msg | myslice}}</h2>
</div>
script部分,注意创建全局过滤器的语法
//需要在创建实例之前配置全局过滤器
//把myslice过滤器创建为全局过滤器
Vue.filter("myslice",function(value){
return value.slice(0,5)
})
const vm=new Vue({
data:{
time:1621561377603
},
filters:{
timeFormat(value,str){
return dayjs(this.time).format(str)
}
}
})
vm.$mount("#root")
//创建第二个实例
new Vue({
el:"#root2",
data:{
msg:"你好,同学,欢迎光临"
}
})
4.总结
- 过滤器可以接受额外参数,多个过滤器可串联
- 过滤器不改变原数据,只产生相对应的新数据
- 过滤器支持插值语法和指令语法,但对v-model不支持
四.Vue内置指令
1.v-text指令
作用:向其所在的节点中渲染文本内容。
v-text不会解析标签,且会覆盖标签中的内容
<div id="root">
<h2>{{name}}</h2>
<h2 v-text="name">你好</h2>
<h2 v-text="hobby"></h2>
</div>
<script>
const vm=new Vue({
data:{
name:"百度",
hobby:"<h2>拍照</h2>"
}
})
vm.$mount("#root")
</script>
2.v-html指令
作用:向指定节点中渲染包含html结构的内容。
和v-text一样会覆盖标签中的内容,但v-html会解析标签
注意:v-html有安全性问题,不要用在用户提交的内容上,或在网站上动态渲染任意html
<div id="root">
<h2>{{name}}</h2>
<h2 v-html="name">你好</h2>
<h2 v-html="hobby"></h2>
</div>
<script>
const vm=new Vue({
data:{
name:"百度",
hobby:"<h2>拍照</h2>"
}
})
vm.$mount("#root")
</script>
3.v-cloak指令
v-cloak无值
1. 特殊属性,vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2. 使用css配合v-cloak可解决网速慢时页面出现的{{xxx}}的问题。
<div id="root">
<h2 v-cloak>{{name}}</h2>
</div>
<script type="text/javascript" src=""></script>
<script>
const vm=new Vue({
data:{
name:"百度",
}
})
vm.$mount("#root")
</script>
解读:首先页面会显示容器内的内容“{{name}}”,等待一定时间执行<script type="text/javascript" src=""></script>
的代码(src=""是要访问的网址),然后在执行下边的代码并对页面进行渲染。
为了防止网速慢页面出现的内容引起用户不好的观感,需要使用以下代码对出现在页面的内容进行隐藏:
<style>
[v-cloak] {
display:none; /* 内容不显示 */
}
</style>
4.v-once指令
v-once所在节点在初次动态渲染之后,就视为静态内容了。以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<div id="root">
<h2 v-once>初始化值是:{{n}}</h2>
<h2>当前n的值是:{{n}}</h2>
<button @click="n++">点击n+1</button>
</div>
<script>
const vm=new Vue({
data:{
n:"1"
}
})
vm.$mount("#root")
</script>
不管点击按钮n值怎么变,但是添加v-once指令的初始化值始终是1
5.v-pre指令
跳过所在节点的编译过程(简单说:就是添加了这个节点的地方程序员怎么写就怎么呈现)
<div id="root">
<h2 v-pre>Vue其实很简单</h2>
<h2 v-pre>{{n}}</h2>
</div>
<script>
const vm=new Vue({
data:{
n:"1"
}
})
vm.$mount("#root")
</script>
{{n}}不会被解读,因为v-pre跳过了这行程序。所以可以为没有插值语法、指令语法的节点添加v-pre指令,可以加快编译。
6.自定义指令
6-1需求:定义一个v-big指令,和v-text功能相似,但是他会把绑定的数据放大10倍。
用到一个新的配置项:directives
<div id="root">
<h2>n原来的值是:{{n}}</h2>
<h2>n放大10倍后的值是:<span v-big="n"></span></h2>
<button @click="n++">点击n+1</button>
</div>
<script>
const vm=new Vue({
data:{
n:1
},
directives:{
big(element,binding){ //element指向span,binding是绑定
element.innerText=binding.value*10
}
}
})
vm.$mount("#root")
</script>
big函数何时被调用:指令与元素成功绑定时(一上来);指令所在的模板被重新解析时。
6-2定义一个v-fbind指令,和v-bindt功能相似,但可以让其所绑定的input表单元素默认获取焦点。
首先,明确获取焦点的方法是element.focus()
如果按照6-1的方法来写,打开页面并不能显示光标,所以不能这样写。
原因是:要在表单出现在页面上之后再添加光标才能获取到,而上述代码表单并没有出现在页面上就已经添加了光标。
处理方法:使用对象,(在原本方法上细分)。代码示例如下:
<div id="root">
<input type="text" v-fbind="n">
</div>
const vm=new Vue({
data:{
n:''
},
directives:{
fbind:{
// 指令与元素重新绑定时:
bind(element,binding){ //element指向input,binding是绑定
element.value=binding.value
},
// 指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
// 指令所在的模板被重新解析时
update(element,binding){
element.value=binding.value
},
}
}
})
vm.$mount("#root")
这样,刚打开页面表单就会显示光标。(要记住这三个函数,以及分别代表的含义)
注意:这三个函数中的this都指向window
6-3全局指令
和过滤器类似,如果必要,可以转换为全局指令。
以6-1为例:
Vue.directive("big",function(element,binding){
element.innerText=binding.value*10
})
补充:
自定义指令命名最好不写成v-bigNumber,而写成v-big-number
在后面定义时,应这样写:
‘big-number’:{ }