..._前端如何直接修改视图值">
赞
踩
直接修改数组中的某个值是不会出发视图更新的。比如:
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>
事件绑定就是在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>
一般情况下属性都是放到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>
监听属性可以针对某个属性进行监听,只要这个属性的值发生改变了,那么就会执行相应的函数。示例代码如下:
<!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>
v-model指定可以实现表单值与属性的双向绑定。即表单元素中更改了值会自动的更新属性中的值,属性中的值更新了会自动更新表单中的值。
绑定的属性和事件:
v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:
表单元素绑定
实例如下:
<!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>
.lazy
在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加lazy修饰符,从而转变为使用change事件进行同步:
.number
如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符
这通常很有用,因为即使在type="number"时,HTML输入元素的值也总会返回字符串。如果这个值无法被parseFloat()解析,则会返回原始的值。
<input v-model.number="age" type="number">
<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>
有时候有一组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必须为一个函数!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。