本篇文章是接着上一篇文章的,可以先看下 上一篇文章
4.Vue常用特性
4.1 常用特性概览
- 表单操作
- 自定义指令
- 计算属性
- 过滤器
- 侦听器
- 生命周期
4.2 表单操作
1. 基于Vue的表单操作
- input 单行文本
- textarea 多行文本
- select 下拉多选
- radio 单选框
- checkbox 多选框
1、单行文本 绑定数据
<span>姓名:</span>
<span>
<input type="text" v-model='uname'>
</span>
<script>
var vm = new Vue({
el:'#app',
data:{
uname:'cookie'
},
})
</script>
禁止表单的默认行为, <input type="submit" value="提交" @click.prevent='handle'>
2、 radio 单选框
<div>
<span>性别:</span>
<span>
<!--给一个值 绑定一个属性 -->
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male">男</label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female">女</label>
</span>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
gender:1
},
})
</script>
3、checkbox 多选框
<div>
<span>爱好:</span>
<input type="checkbox" id="ball" value="1" v-model='hobby'>
<label for="ball">篮球</label>
<input type="checkbox" id="sing" value="2" v-model='hobby'>
<label for="sing">唱歌</label>
<input type="checkbox" id="code" value="3" v-model='hobby'>
<label for="code">写代码</label>
</div>
<div>
<script>
var vm = new Vue({
el:'#app',
data:{
//绑定的值 是2 和3 则页面上默认显示的 就是勾选的2和3
hobby:['2','3'],
},
})
</script>
4、select 下拉多选
<div>
<span>职业:</span>
<!--multiple 添加后可进行多选 -->
<select v-model='occupation' multiple>
<option value="0">请选择职业...</option>
<option value="1">教师</option>
<option value="2">软件工程师</option>
<option value="3">律师</option>
</select>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
//默认勾选 2、3
occupation:['2','3'],
},
})
</script>
5、 textarea 多行文本
<div>
<span>个人简介:</span>
<textarea v-model='desc'></textarea>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
//默认勾选 数据
desc:'nihao'
},
})
</script>
2.表单域修饰符(number/trim/lazy)
- number:转化为数值
- trim:去掉开始和结尾的空格
- lazy:将input 事件切换为chang事件
<input v-model.number = "age" type="number">
1、number转化为数值
<div id="app">
<!-- 将字符串转换为number 进行相加 -->
<input type="text" v-model.number="age">
<button @click="handle">点击</button>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
age:'',
},
methods:{
handle:function(){
console.log(this.age +12);
}
}
})
</script>
2、trim去掉首尾空格
<div id="app">
<!-- trim 去掉左右两边的空格 -->
<!--<input type="text" v-model.trim="info">-->
<input type="text" v-model="info">
<button @click="handle">点击</button>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
info:'',
},
methods:{
handle:function(){
//打印长度
console.log(this.info.length);
}
}
})
</script>
没有使用trim去空格 空格的长度也算进去了 打印的长度为4
使用trim 去空格
3、lazy将input转为chang事件
<div id="app">
<!-- lazy 失去焦点后才会进行显示-->
<!-- <input type="text" v-model.lazy="msg">-->
<!-- <input type="text" v-model="msg">-->
<div>{{msg}}</div>
<button @click="handle"> 点击 </button>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:''
},
methods:{
handle:function(){
}
}
})
</script>
默认情况下 在input事件中 输入框中输入内容 绑定的msg 也会发生变化
添加lazy后 是失去焦点后 才会发生变化
4.3 自定义指令
1、为何需要自定义指令?
内置指令不满足需求
2、 自定义指令的语法规则(获取元素焦点)
Vue.directive('focus'{
//el 表示指令所绑定的元素
inserted:function(el){
//获取元素的焦点
el.focus();
}
})
3、自定义指令用法
详细的自定义指令的用法可参考官方文档 自定义指令
<input type="text" v-focus >
刷新网页后自动获取到输入框的焦点
4、 带参数的自定义指令(改变元素背景颜色)
Vue.directive('color',{
inserted:function(el,binding){
el.style.backgroundColor = binding.value.color;
}
})
指令的用法
<input type="text" v-color='{color:"red"}'>
实例代码
<div id="app">
<input type="text" v-color="msg">
</div>
Vue.directive('color',{
bind:function(el,binding){
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el:'#app',
data:{
msg:{
color:'blue'
}
}
})
背景色就已经修改了 ,如果要改颜色的话,只需要修改msg里面的字段就好了
可以将全局的directive指令改成 局部的directive指令
在跟methods 同级目录下去创建
directives:{
color:{
bind:function(el,binding){
// console.log(binding);
//根据指令的参数设置背景色
el.style.backgroundColor = binding.value.color;
}
},
focus:{
inserted:function(el){
el.focus()
}
}
}
4.4 计算属性(computed)
1、为何需要计算属性?
表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容简洁。
代码示例
要求:将某个字符串反转 hello 反转为 olleh
//原生的方法 可读性较低
<div id="app">
//split将字符串以空格分开 reverse反转 join拼接
<div>{{msg.split('').reverse().join('')}}</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'hello'
},
})
</script>
2、计算属性的用法
computed:{
res:function(){
return this.msg.split('').reverse().join('')
}
}
计算属性代码示例
<div id="app">
//直接在这里调用函数名称
<div>{{res}}</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'hello'
},
computed:{
//res 函数名
res:function(){
//将方法写在函数中 return 出去
return this.msg.split('').reverse().join('')
}
}
})
</script>
3、计算属性(computed)与方法(methods)的区别
- 计算属性是基于他们的依赖进行缓存的
- 方法不存在缓存
计算属性示例代码:
渲染结果添加一个{{res}}
在原来的computed的res里面加上一个打印
<div id="app">
<div>{{res}}</div>
<div>{{res}}</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'hello'
},
computed:{
//res 函数名
res:function(){
console.log('computed')
//将方法写在函数中 return 出去
return this.msg.split('').reverse().join('')
}
}
})
</script>
可以看到我们渲染了 2次翻转的结果,但是控制台只打印了一次,第二次的渲染就是从缓存中来的,好处是节省了性能
方法 示例代码:
<div id="app">
<!--调用函数handle-->
<div>{{handle()}}</div>
<div>{{handle()}}</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'hello'
},
methods:{
handle:function(){
//打印结果
console.log('methods')
return this.msg.split('').reverse().join('')
}
},
})
</script>
同样的 我调用了2次函数渲染,控制台就打印了2次,每次都会去重新执行函数
4.5 侦听器(watch)
1、侦听器的应用场景
数据变化时执行异步开销较大的操作
默认情况下,组件在初次加载完成后 不会调用watch侦听器,如果想让watch 侦听器立即被调用,则需要使用immediate选项
示例如下
1.2 immediate选项
watch: {
username: {
// handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
handler: async function (newVal) {
// 传递的值是否为空
if (newVal === '') return
//解构赋值
const { data: res } = await axios.get('请求地址' + newVal)
console.log(res)
},
// 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
immediate: true
}
}
1.3 deep 选项
如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选项,代码示例如下:
1.4监听对象单个属性的变化
只监听单个属性的变化 则可以按照如下的方式定义
2、侦听器的用法
watch:{
firstname:function(val){
//val 表示变化的值
this.fullname = val + '' + this.lastname
},
lastname:function(val){
this.fullname = this.firstname + '' + val;
}
}
应用场景代码示例
<div id="app">
<div>
<span>名:</span>
<span>
<input type="text" v-model="firstname">
</span>
</div>
<div>
<span>姓:</span>
<span>
<input type="text" v-model="lastname">
</span>
</div>
<div>{{fullname}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
// 初始的显示值
firstname:"li",
lastname:"ming",
fullname:"liming"
},
watch:{
//firstname 这个函数名要跟上面data的一样
//val 是最新的值
firstname:function(val){
//拼接全名
this.fullname = val + '' + this.lastname
},
lastname:function(val){
this.fullname = this.firstname + '' + val;
}
}
})
</script>
监听输入框中的内容,一旦发生变化就会改变其值
在这个应用场景下 也可以使用computed计算属性来实现。当然了只是说的是当前场景,从代码层面上可以看出来computed的代码更简洁
computed:{
fullName:function(){
return this.firstname + '' + this.lastname;
}
}
3、案例:验证用户名是否可用
需求:输入框中输入姓名,失去焦点时验证是否存在,如果已经存在,提示重新输入,如果不存在,提示可以使用
流程:
- 通过v-model实现数据绑定
- 需要提供提示信息
- 需要侦听器监听输入信息的变化
- 需要修改触发的事件
代码示例:
<body>
<div id="app">
<div>
<span>用户名:</span>
<span>
<!--输入框 绑定数据uname-->
<input type="text" v-model.lazy="uname">
</span>
<!--提示信息文字-->
<span>{{tip}}</span>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
/*
侦听器
1、采用侦听器监听用户名的变化
2、调用后台接口进行验证
3、根据验证的结果,调整提示信息
*/
var vm = new Vue({
el:"#app",
data:{
uname:'',
tip:'',
},
methods:{
checkname:function(uname) {
//调用接口,但是使用定时器,来模拟接口调用
var that = this;
setTimeout(function(params) {
//模拟接口调用
if(uname == 'admin'){
that.tip = '用户名已存在'
}
else{
that.tip = '用户名可以使用'
}
},2000)
}
},
watch:{
uname:function(val){
//调用后台接口验证用户名的合法性
this.checkname(val)
//修改提示信息
this.tip = '正在验证...'
}
}
})
</script>
4.6 过滤器(filters)
1.过滤器的作用是什么?
格式化数据 比如将字符串格式化为首字母大写,将日期格式化为指定的格式
2.自定义过滤器(全局过滤器)
Vue.filter('过滤器名称',function(){
//过滤业务逻辑
})
4.过滤器的使用
<div>{{msg | aper}}</div>
<div>{{msg | aper | lower}}</div>
<div :msgd="msg | formatId"></div>
5.代码示例
<input v-model = "msg"></input>
<div>{{msg | aper}}</div>
<!--2层过滤器 先变大写在变小写 -->
<div>{{msg | aper | lower}}</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:"",
},
methods:{
handle:function(){
}
},
//这个是局部过滤器
filters:{
//params 为自定义 接收传进来的值
aper:function(params){
//将首字母变成大写
return params.charAt(0).toUpperCase() + params.slice(1)
},
//将首字母在变小
lower:function(params){
return params.charAt(0).toLowerCase() + params.slice(1)
}
},
})
</script>
6.带参数的过滤器
Vue.filter('formdate',function(value,arg){
//value 就是过滤器传递过来的参数
})
7.过滤器的使用
<div>{{data | format}}</div>
8.案例:使用过滤器格式化日期
<div id="app">
<div>{{date | formdate('yyyy-MM-dd')}}</div>
</div>
<script>
/*
过滤器
*/
Vue.filter('formdate',function(value,arg){
if(arg == 'yyyy-MM-dd'){
var ret = '';
ret = ret + value.getFullYear() + '-' + (value.getMonth() + 1) + '-'+ value.getDate();
return ret
}
})
var vm = new Vue({
el:'#app',
data:{
date:new Date()
},
})
</script>
4.7 生命周期
1.主要阶段
- 挂载(初始化相关属性)
-
beforeCreate
-
created
-
beforeMount
-
mounted
- 更新(元素或组件的变更操作)
- beforeUpdate
- updated
- 销毁(销毁相关属性) - beforeDestroy
- destroyed