这里写目录标题
一、表单
1. 表单输入绑定
文档说明:表单输入绑定 — Vue.js (vuejs.org)
你可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model
会忽略所有表单元素的 value
、checked
、selected
attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data
选项中声明初始值。
v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
例:
<div id="root">
<h2>表单数据</h2>
<form>
<!-- .trim去除首尾空格 -->
账号 <input type="text" v-model.trim="obj.text"> <br />
密码 <input type="password" v-model="obj.pass"> <br />
性别:
男<input type="radio" name="sex" value="男" v-model="obj.sexRadioText">
女<input type="radio" name="sex" value="女" v-model="obj.sexRadioText">
<br />
爱好:
摄影<input type="checkbox" value="摄影" v-model="obj.hobbyArr">
骑行<input type="checkbox" value="骑行" v-model="obj.hobbyArr">
旅行<input type="checkbox" value="旅行" v-model="obj.hobbyArr">
阅读<input type="checkbox" value="阅读" v-model="obj.hobbyArr">
次元<input type="checkbox" value="次元" v-model="obj.hobbyArr">
<br />
<select v-model="obj.selectValue">
<!-- value="" 默认选中 -->
<option value="">选择角色</option>
<option value="Lixy">李逍遥</option>
<option value="Baicq">徐长卿</option>
<option value="Xiejx">邪剑仙</option>
<option value="Zhaole">赵灵儿</option>
<option value="Tangxj">唐雪见</option>
<option value="Linyr">林月如</option>
</select>
<br />
<!-- 文本域 -->
<!-- .lazy失去焦点再收集数据 -->
<textarea v-model.lazy="obj.textarea"></textarea>
<br />
<!-- .number 输入字符串转为有效的数字 -->
<input type="number" v-model.number="age">
<br />
</form>
<button @click="fun">点击</button>
</div>
let vm = new Vue({
el: "#root",
data() {
return {
obj: {
text: "",
pass: "",
sexRadioText: "",
hobbyArr: [],
selectValue: "",
textarea: ""
},
age: 24,
}
},
methods: {
fun() {
console.log(this.obj);
},
}
})
总结:
除了有多个选项的input有点区别外,其他都可以使用单个属性名绑定:
比如:正常的文本 input=text 单个属性名就可以绑定获取到数据(用户输入的value);
input = radio 单选按钮的,绑定单个属性名,收集的也是value。
没有设置value 则获取就是null;设置value 获取对应的value值。
input = checkbox 单个获取的是 true 或者 false,绑定单个属性;
input = checkbox 多个复选框的时候需要绑定数组并且配置value值,收集到value值。
.lazy 失去焦点在收集数据
.number 输入字符串转为有效的数字
.trim 过滤用户输入的首尾空白字符
二、配置对象
1. 计算属性
vue模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。
计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。
例:
<!-- 原生js写法 -->
<p>{{"我" + msg.split("")[0] + msg.split("")[1] + "女" }}</p>
<!-- 首字母大写 -->
<p>{{
name.split(" ").map(item=>{
return item[0].toUpperCase() + item.slice(1)
}).join(" ")
}}</p>
<hr>
<!-- vue使用计算属性 -->
<p>fun:{{fun}}</p>
data() {
return {
msg: "爱美", // 后端发送的
name: "i love you",
}
},
// 计算属性:存储函数名, 里面函数会挂载到vm上,使用{{函数名}}直接使用
computed: {
// 需要有return 返回值配合, 数据会返回函数名使用位置 简写版
fun() {
// this 指向 vue实例对象
// console.log(this.msg);
return "我" + this.msg.split("")[0] + this.msg.split("")[1] + "女";
},
//初始写法
// 属性名,会挂载到vm上
start: {
// get 什么时候触发 ?
// get() 所依赖属性数据发生变化时也会触发
get() {
// this 是vue底层配置好的vue实例对象
// console.log(this);
return "我"+this.msg.split("")[0] + this.msg.split("")[1] + "女";
return this.msg;
},
//设置start属性时触发
set(value) {
console.log(123, value);
this.msg = value;
}
},
}
总结:
配置对象:
data 存储数据位置
el 挂载对象
methods 存储事件函数 自定函数位置
computed 计算属性
vue模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。
理解计算属性:
对于vue来说 data数据就是属性名和属性值;
计算属性 => 就是拿着已写完的属性进行加工进行计算,从而不在模板中写上复杂代码逻辑。
computed 计算属性存储函数名,里面函数会挂载到vm上,直接使用**{{函数名}}使用;
里面的函数需要有return 返回值**配合,数据会返回函数名使用位置 。
this 指向 vue实例对象
不要使用箭头函数
优点:
- 复用性好;
- 维护方便。
计算属性总结:
通过已有属性计算得来;
原理: 底层借助Object.defineProperty方法提供的 getter 和 setter;
get 什么时候触发 ? 当调用conputed中函数或者属性名时,对应函数或属性名中get函数就会被触发,并且返回值作为函数或属性名的值;所依赖属性数据发生变化时也会触发。
函数或者属性名挂载到vue实例上;
计算属性一般只读 => 若不需要改计算属性使用简写方法。
2. computed 和 methods 的区别
computed和methods的区别:
-
计算属性不能在 {{ fun() }} 中加 ( ) 使用,即不能传参。
-
computed 和 methods 都支持复杂的表达式;但对于同一表达式重复在页面渲染,computed只在控制台打印一次,methods每次都会打印。所以computed的复用性较高。
-
computed 依赖的属性名不发生变化,则计算属性的结果会被缓存, 依赖的属性名发生变化,那就重新计算。可以在调试工具中查看到数据。而 methods 每次都是重新计算数据拿到结果,调试工具看不到数据。
例:
<p>{{funComp}}--compted</p>
<p>{{funComp}}--compted</p>
<p>{{funComp}}--compted</p>
<p>{{funComp}}--compted</p>
<p>{{funComp}}--compted</p>
<p>{{funComp}}--compted</p>
<p>{{funComp}}--compted</p>
<hr>
<p>{{funMeth()}}--methods</p>
<p>{{funMeth()}}--methods</p>
<p>{{funMeth()}}--methods</p>
<p>{{funMeth()}}--methods</p>
<p>{{funMeth()}}--methods</p>
<p>{{funMeth()}}--methods</p>
<p>{{funMeth()}}--methods</p>
data() {
return {
name:"i love you",
}
},
// 计算属性:存储函数名, 里面函数会挂载到vm上,使用{{函数名}}直接使用
computed: {
funComp() {
console.log("computed");
return this.name.split(" ").map(item => {
return item[0].toUpperCase() + item.slice(1)
}).join(" ")
},
},
methods: {
funMeth() {
console.log("methods");
return this.name.split(" ").map(item => {
return item[0].toUpperCase() + item.slice(1)
}).join(" ")
}
}
3. watch监听
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch()
,遍历 watch 对象的每一个 property。
a. 单一属性监听
例: 数据被修改时,触犯监听事件,修改数组。
<p>{{name}}</p>
<ul>
<li v-for="item of arr">{{item}}</li>
</ul>
data() {
return {
name: "Evan You",
arr: [1, 2, 3, 4]
}
},
// 监听配置对象
watch: {
// data中的属性
name: {
// 监听数据发生变化时触发handler函数
// 参数第一个为新数据,第二个为修改之前的数据
handler(newVal, oldval) {
this.arr.push("数据name被修改");
console.log(newVal, oldval);
},
// 回调函数立即触发
// immediate:true,
}
}
// 第二种写法:写在vue实例对象vm外面
// 使用vue原型上的方法$watch
vm.$watch("name", {
handler(newVal, oldval) {
this.arr.push("数据name被修改");
console.log(newVal, oldval);
},
})
b. 监听对象中的属性
对象中的每一个属性只能重写一个监听函数进行监听,过于麻烦,可以使用深度监听。
...
obj:{
name:"尤雨溪",
sex:"男",
age:"36"
}
// 监听配置对象
watch: {
"obj.age":{
handler(newVal, oldval) {
this.arr.push("对象obj被修改");
console.log(newVal, oldval);
},
}
}
c. 深度监听
为了发现对象内部值的变化,可以在选项参数中指定 deep: true
。注意监听数组的变更不需要这么做。
// 深度监听
obj: {
// handler 什么会被触发 ? 监听数据发生变化时触发函数
handler(newVal, oldval) {
this.arr.push("对象obj中的某一属性被修改");
console.log(newVal, oldval);
},
deep: true
},
总结:
深度监听 deep:true 是监听对象中的所有的属性名。
Vue中的watch默认不监听对象内部值的改变,watch配置deep:true 可以监听对象内部值的变化(多层),使用watch的时候根据结构来,决定是否采用深度监听,同时监听数组是无意义的。
handler 函数监听数据发生变化时被触发,简写时属性名或属性值变化的时候,函数会自动触发。
4. 计算属性与监听属性的区别
文档说明:计算属性和侦听器 — Vue.js (vuejs.org)
计算属性也可以用来监听数据:
<div id="app">
{{definePro}} // 中华有为
<br />
<p v-for="item in arr">{{item}}</p>
</div>
...
let vm = new Vue({
el: "#app",
data() {
return {
flag:"中华有为",
arr:["终", "见", "曙"]
}
},
// 依赖属性发生变化
computed: {
definePro(){
this.arr.push("光");
return this.flag;
}
}
})
那么,计算属性与监听属性的区别是什么呢?
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。
例:
<h2>开始 1秒钟之后 才能显示</h2>
<input type="text" v-model="firstName">
<input type="text" v-model="lastname">
<p>{{comFun}}-----计算属性</p>
<hr>
<p>{{ fileName }}-----监听属性</p>
let vm = new Vue({
el: "#app",
data() {
return {
firstName: "胡",
lastname: "歌",
fileName: "胡歌"
}
},
// 依赖属性发生变化
computed: {
comFun() {
setTimeout(() => {
// this已改变,返回值不能返回到外部函数comFun()
return this.firstName + "|" + this.lastname
}, 1000)
return this.firstName + "|" + this.lastname;
}
},
watch: {
firstName(val) {
setTimeout(() => {
this.fileName = val + "|" + this.lastname;
}, 1000)
},
lastname(val) {
setTimeout(() => {
this.fileName = this.fileName + val;
}, 1000)
}
}
})
总结:
computed能完成的功能,watch都可以完成,watch能完成的功能computed不一定能完成;
且 watch可以进行异步操作而computed不能。