vue 常用特性学习

表单的操作

表单的绑定都与 v-model 有关,v-model 绑定后会自动将 value, checked, selected 属性忽略,然后以 data 中的初始值为准,所以要在 data 中设置好初始值。
不同的表单 v-model 会设置不同的属性和默认事件

  1. text 和 textarea 元素使用 value 属性和 input 事件
  2. checkbox 和 radio 使用 checked 属性和 change 事件
  3. select 字段将 value 作为 prop 并将 change 作为事件

表单绑定

input 输入框

v-model 指令可以获取到输入的值
msg 如果有默认值则 placeholder 属性会被覆盖,页面中展示的内容就是表单中输入的值

<input type="text" placeholder="value" v-model="msg" /> <span>{{ msg }}</span>

单选

要设置 value 属性 v-model 就可以获取到 value 的值,v-model 的绑定值会让与带有他相同的 value 属性值的单选框处于选中状态,即 data 内 msg:'1'时才会被选中

<input type="radio" value="1" v-model="msg" />
<script>
	...
	data: {
	  msg: '1'
	}
	...
</script>

复选

v-model 起到了 name 属性的作用,需要设置 value 属性,v-model 需要绑定一个数组,数组中的项如果和 value 值一样则会使对应的选项选中

<!-- 此时只有value为a和c的复选框被选中 -->
<input type="checkbox" value="a" v-model="list" />
<input type="checkbox" value="b" v-model="list" />
<input type="checkbox" value="c" v-model="list" />
<script>
	...
	data: {
	  list: ['a', 'c']
	}
	...
</script>

如果为一个选项框,v-model 也可以绑定到选中状态 checked,值设为布尔值,也可以同单选框一样设置相同值的 value 属性,效果相同。

<input type="checkbox" value="1" v-model="check" />
<input type="checkbox" v-model="checked" />
<script>
	...
	data: {
	  checked: true,
	  check: '1'
	}
	...
</script>

文本域

和 input 输入框类似,而且无法通过{{}}来插入值

<!-- 插值表达式{{}}无效,v-text单独使用虽然有效但是设置v-model指令后也不会显示哪怕text值为空字符只有为null时才会显示 -->
<textarea v-model="text" v-text="111">{{ msg }}</textarea>

下拉表单

  • 单选
    单选时如果设置 value 属性,v-model 绑定的值为单个值,与 value 值匹配后会决定要选择的项,不设置 value 属性 v-model 会获得下拉选项中的内容,同样去匹配绑定的数据然后判断,建议设置 value 保安全。
    <select id="" v-model="select">
    	<option value="1">hi</option>
    	<option value="2">he</option>
    	<option value="3">ha</option>
    </select>
    <script>
    	...
    	data: {
    	  select:'2'
    	}
    	...
    </script>
    
  • 多选
    绑定到一个在数组,同复选
    <select multiple v-model="selects">
    	<option value="1">hi</option>
    	<option value="2">he</option>
    	<option value="3">ha</option>
    </select>
    <script>
    	...
    	data: {
    	  selects:['1', '3']
    	}
    	...
    </script>
    

表单修饰符

.number 会使用类似 parseFloat()的方法对值进行数据转换,可以识别小数点,规则大体相同,如果转换后值和之前相同则不会触发 input 事件。
.trim 会去除字符串两侧的空格字符,只保留实体部分,字符中间的不会去除。
.lazy 会将 v-model 绑定后的默认表单事件由 input 改为 change。

<input type="text" placeholder="value" v-model.number="msg" @input="handle" />
<span>{{ msg }}</span>
<input type="text" placeholder="value" v-model.trim="msg" @input="handle" />
<span>{{ msg }}</span>
<input type="text" placeholder="value" v-model.lazy="msg" />
<span>{{ msg }}</span>
<script>
	...
	data: {
	  msg: '1'
	},
	methods: {
	  handle() {
	    console.log(this.msg)
	  }
	}
	...
</script>

自定义指令

bind 是事件绑定时就调用用于初始化,只执行一次(不建议绑定 focus 会无效)
inserted 事件绑定的元素插入到父元素时才执行

定义指令的方式

调用时直接使用即可

  1. 全局指令
    可以在全局使用
<input type="text" v-focus placeholder="value" />
<script>
	...
	Vue.directive('focus', {
	  inserted: function (el) {
	    el.focus()
	  }
	})
	...
</script>
  1. 局部指令
    只能在组件中使用
<input type="text" v-focus placeholder="value" />
<script>
	let vm = new Vue({
	...
	  directives: {
	    focus: {
	      inserted(el) {
	        el.focus()
	      }
	    }
	  }
	...
	})
</script>

指令的参数使用

el 绑定的元素
binding 参数是一个对象,有如下属性

  • name 自定义方法名
  • value 绑定的值
  • arg 传给指令的参数
  1. 函数参数的使用
<input type="text" v-color="colors" />
<script>
	let vm = new Vue({
	...
	  data: {
	    colors: 'pink'
	  },
	  directives: {
	    color: {
	      bind(el, binding) {
	        el.style.color = binding.value
	      }
	    }
	  }
	...
	})
</script>
  1. 指令参数和动态指令参数的用法
    指令参数就是在指令后跟随一个参数,可以根据参数来进行判断,然后进行设置
    动态指令参数是可以变化的,所以更灵活的调整设置
    自定义指令里直接通过 binding 的属性来使用 data 的值
<p v-pink:[clo]="pinks">hi~</p>
<script>
	...
	data: {
	  col: 'deeppink',
	  pinks: {
	    color1: 'pink',
	    color2: 'deeppink'
	  }
	},
	directives: {
	  ...
	  pink: {
	    inserted(el, binding) {
	      binding.arg = 'pink'
	      if(binding.arg == 'deeppink') {
	        el.style.color = binding.value.color2
	        el.style.backgroundColor = binding.value.color1
	      } else {
	        el.style.color = binding.value.color1
	      }
	      // let color = binding.arg == 'deeppink' ? binding.value.color2 : binding.value.color1
	      // el.style.color = color
	    }
	  }
	}
	...
</script>

计算属性

一定要 return 返回值
依赖值发生改变就会调用计算方法,加载页面也会立刻触发 计算属性在依赖值不发生改变时重复使用也不会重复计算,会使用缓存,只有依赖值发生改变时才会重新计算 methods 里面的定义方法虽然也可以达到和计算属性一样的效果但是每次使用都会重新计算,如果计算量较大比较浪费性能

<!-- 计算属性 -->
<input type="text" v-model="str" />
<span>{{ bigStr }}</span>
<!-- 方法使用方式,定义就是事件的定义 -->
<span>{{ bigStr() }}</span>
<script>
	...
	data: {
	  str: 'heihei'
	},
	computed: {
	  bigStr() {
	    return this.str.toUpperCase() + 111
	  }
	}
	...
</script>

侦听器

只有依赖变化时对应的函数才是运行,加载页面不会触发,函数名称是 data 里面侦听的数据名 一般用于需要数据变化时进行异步处理或者处理开销较大的操作。可以传入两个形参,一个是改变后的值,一个是改变前的值

<div>{{ fullName }}</div>
<script>
	...
	data: {
	  firstName: 'Jim',
	  lastName: 'Green',
	  fullName: 'Jim Green'
	},
	watch: {
	  firstName: function(val) {
	    this.fullName = val + ' ' + this.lastName
	  },
	  lastName: function(newVal, oldVal) {
	    console.log(newVal, oldVal)//变化后的, 变化前的
	    this.fullName = this.firstName + ' ' + val
	  }
	}
	...
</script>

过滤器

过滤器的定义

  • 全局过滤器
Vue.filter('lower', function(val) {
	return val.charAt(0).toLowerCase() + val.slice(1)
})
  • 局部过滤器
filters: {
  upper: function(val) {
    return val.charAt(0).toUpperCase() + val.slice(1);
  }
}

过滤器的使用

一定要有 return 返回值
如果全局过滤器和局部过滤器命名冲突会默认使用局部过滤器 可用于插值表达式或者属性绑定 可以级联使用,后面的操作的值是前一个操作后的返回值 过滤器不加括号或加括号不加实参则默认传入要处理的值,定义的时候要设置形参,带括号时可以传入多个参数,但是默认会第一个传入要处理的值,所以形参要比括号内的实参多设置一个。

<!-- 不带参数 -->
<div>{{ msg | upper }}</div>
<div>{{ msg | upper | lower }}</div>
<input type="text" :value="msg | upper" />
<!-- 带参数 -->
<div>{{ msg | multiply(111) }}</div>
<script>
	Vue.filter('lower', function(val) {
	  return val.charAt(0).toLowerCase() + val.slice(1)
	})
	...
	data: {
	  msg: 'hei!'
	},
	filters: {
	  upper: function(val) {
	    return (val).charAt(0).toUpperCase() + val.slice(1)
	  },
	  // 带参数
	  multiply: function(val,val2) {
	    return val * val2
	  }
	}
	...
</script>

生命周期

<script>
	...
	beforeCreate () {
	  //在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
	},
	created () {
	  //在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来,$el不可用
	},
	beforeMount () {
	  //这个阶段data和methods都可用,$el也可以获取,在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已
	},
	mounted () {
	  //一切准备就绪。el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上在这个钩子函数里面我们可以使用一些第三方的插件
	},
	beforeUpdate () {
	  //数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的
	},
	updated () {
	  //由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的
	},
	beforeDestroy() {
	  //实例销毁之前调用
	},
	destroyed() {
	  //实例销毁后调用
	}
	...
</script>

变异方法处理数组 && 替换数组

原生处理数组的方法不能触发视图渲染,所以进行了包装

变异方法

就是处理后原数组改变的方法

  • push() 往数组最后面添加一个元素,成功返回当前数组的长度
  • pop() 删除数组的最后一个元素,成功返回删除元素的值
  • shift() 删除数组的第一个元素,成功返回删除元素的值
  • unshift() 往数组最前面添加一个元素,成功返回当前数组的长度
  • splice() 有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值
  • sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组
  • reverse() 将数组倒序,成功返回倒序后的数组

替换数组的方法

可以使用非变异方法来改变数组,然后让原数组接收改变后产生的新数组达到替换数组的目的
非变异方法有

  • filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
  • concat() 用于连接两个或多个数组。该方法不会改变现有的数组
  • slice() 可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组
this.list = this.list.slice(0, 2)

动态响应式处理数据

在已经创建好的实例中是不允许向 data 里面添加响应式的数据的,所以我们需要使用 Vue.set(object, propertyName, value)方法来更新想要修改的数据。 文档坐标