1、视图更新注意事项
直接修改数组中的某个值是不会出发视图更新的。比如:
this.books[0] = ‘Python’;
这种情况应该改成用splice或者是用Vue.set方法来实现:
Vue.set(this.books,0,‘Python’);
如果动态的给对象添加属性,也不会触发视图更新。只能通过Vue.set来添加。比如:
<div id="app">
<ul>
<li v-for="(value,name) in person">{{name}}:{{value}}</li>
</ul>
<script>
let vm = new Vue({
el: "#app",
data: {
person: {"username": '逻辑教育'}
},
methods: {
changePerson: function(event){
Vue.set(this.person,'age',18)
}
}
});
</script>
</div>
2、事件绑定
事件绑定就是在HTML元素中,通过v-on绑定事件的。事件代码可以直接放到v-on后面,也可以写成一个函数。
<div id="app">
<p>{{count}}</p>
<button v-on:click="count+=1">加</button>
<button v-on:click="subtract(10)">减10</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
count: 0
},
methods: {
subtract: function(value){
this.count -= value;
}
}
});
</script>
传入event参数
如果在事件处理函数中,想要获取原生的DOM事件,那么在html代码中,调用的时候,可以传递一个$event参数。
<button v-on:click="subtract(10,$event)">减10</button>
...
<script>
...
methods: {
subtract: function(value,event){
this.count -= value;
console.log(event); //相当于打印输出
//alert(123) 弹出窗口显示123
}
}
...
</script>
3、计算属性和监听器
一般情况下属性都是放到data中的,但是有些属性可能是需要经过一些逻辑计算后才能得出来,那么我们可以把这类属性变成计算属性。比如以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id ="app">
<label>长:</label>
<!-- type="number" 只能输入数字 -->
<!-- v-model 双向绑定 不能省略 -->
<input type="number" name="length" v-model:value="length">
<label>宽:</label>
<input type="number" name="width" v-model:value="width">
<label>面积:</label>
<input type="number" readonly v-bind:value="area">
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
length:0, //和上面的v-model:value 双向绑定,为了获取当前值
width:0,
},
//计算属性
computed:{
area:function(){
console.log(this.length, this.width)
return this.length*this.width
}
}
})
</script>
计算属性更加智能,他是基于它们的响应式依赖进行缓存的。也就是说只要相关依赖(比如以上例子中的area)没有发生改变,那么这个计算属性的函数不会重新执行,而是直接返回之前的值。这个缓存功能让计算属性访问更加高效。(即之前运行过的结果会被缓存下来,后面如果继续计算,可以直接返回缓存的值)
计算属性的set:
计算属性默认只有get,不过在需要时你也可以提供一个set,但是提供了set就必须要提供get方法。
示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id ="app">
<div>
<label>省:</label>
<input type="text" v-model:value="province">
<label>市:</label>
<input type="text" v-model:value="city">
<label>区:</label>
<input type="text" v-model:value="area">
<label>详细地址:</label>
<input type="text" v-model:value="address">
</div>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
length:0, //和上面的v-model:value 双向绑定,为了获取当前值
width:0,
province:'',
city:'',
area:'',
//address:'', 这里不能设置
},
//计算属性
computed:{
address:{
get:function(){
var result = ""
if(this.province){
result =this.province + "省"
}
if(this.city){
result +=this.city + "市"
}
if(this.area){
result +=this.area + "区"
}
return result
},
set:function(value){
//console.log(value)
var result = value.split(/省|市|区/) //正则表达
if(result && result.length > 0){
this.province=result[0]
}
if(result && result.length > 1){
this.city=result[1]
}
if(result && result.length > 2){
this.area=result[2]
}
}
}
}
})
</script>
4、监听属性
监听属性可以针对某个属性进行监听,只要这个属性的值发生改变了,那么就会执行相应的函数。示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<label>搜索:</label>
<input type="text" name="keyword" v-model:value="keyword">
<p>结果:</p>
<p>{{answer}}</p>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
keyword:"", //注意这里是:,不是=
answer:'',
},
//监听属性
watch:{
keyword:function(new_value, value){
console.log(value)
console.log(new_value)
this.answer="加载中。。。"
//定时器
setTimeout(() => {
this.answer="搜索结果" + new_value
}, 1000); //延迟1000ms之后执行
}
}
})
</script>
5、表单输入绑定
v-model指定可以实现表单值与属性的双向绑定。即表单元素中更改了值会自动的更新属性中的值,属性中的值更新了会自动更新表单中的值。
绑定的属性和事件:
v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:
- text和textarea元素使用value属性和input事件。
- checkbox和radio使用checked属性和change事件。
- select字段将value作为prop并将change作为事件。
表单元素绑定
- input绑定
- textarea绑定
- checkbox绑定
- radio绑定
- select绑定
实例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- input绑定 -->
<input type="text" v-model:value="message" placeholder="请输入...">
<!-- textarea绑定 -->
<textarea name="" v-model:value="message" cols="30" rows="10"></textarea>
<p>输入的内容是:{{message}}</p>
<!-- checkbox绑定 -->
<input type="checkbox" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
<!-- radio绑定 -->
<input type="radio" value="男" v-model="gender">
<label>男</label>
<br>
<input type="radio" value="女" v-model="gender">
<label>女</label>
<br>
<span>Picked: {{ gender }}</span>
<!-- select绑定 -->
<select v-model="selected">
<option disabled value="">请选择</option>
<!-- 如果有value值 选择的就是value值 -->
<option value="1">A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
message:'',
checkedNames:[],
gender:'',
selected:'',
}
})
</script>
6、修饰符
-
.lazy
在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加lazy修饰符,从而转变为使用change事件进行同步: -
.number
如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符
这通常很有用,因为即使在type="number"时,HTML输入元素的值也总会返回字符串。如果这个值无法被parseFloat()解析,则会返回原始的值。
<input v-model.number="age" type="number">
- .trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符
<input v-model.trim="msg">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- .lazy修饰符 -->
<input type="text" v-model:value.lazy="message" placeholder="请输入...">
<!-- 下面的语句时常用的 -->
<input type="text" v-model.lazy="message" placeholder="请输入...">
<!-- .number 如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符 -->
<input v-model.number="age" type="number">
<p>输入内容是:{{message}}</p>
<!-- .trim 如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符 -->
<input type='text' v-model.trim="msg">
<p>{msg}</p>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:"#app",
data:{
message:"",
age:"",
msg:"",
}
})
</script>
7、自定义组件
有时候有一组html结构的代码,并且这个上面可能还绑定了事件。然后这段代码可能有多个地方都被使用到了,如果都是拷贝来拷贝去,很多代码都是重复的,包括事件部分的代码都是重复的。那么这时候我们就可以把这些代码封装成一个组件,以后在使用的时候就跟使用普通的html元素一样,拿过来用就可以了。
基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button_count> </button_count>
<!-- 可以多次调用,代码已经封装,代码简化 -->
<button_count> </button_count>
<button_count> </button_count>
<button_count> </button_count>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//自定义组件 button_count标签名字
Vue.component('button_count',{
template:'<button @click="count += 1">点击了{{count}}次</button>', //button_count中封装的内容模板就是这句
data:function(){ //这里的data写法不同于new vue中的,需要是函数
return { //这里需要{}
count:0
}
}
})
new Vue({
el:"#app",
data:{
}
})
</script>
以上我们创建了一个叫做button-count的组件,这个组件实现了能够记录点击了多少次按钮的功能。后期如果我们想要使用,就直接通过button-count使用就可以了。然后因为组件是可复用的Vue实例,所以它们与new Vue接收相同的选项,例如data、computed、watch、methods以及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。另外需要注意的是:组件中的data必须为一个函数!