vue-v-model指令&绑定事件&深度式响应

一、v-model指令

1、基础用法

v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。
(1)绑定单行文本
v-model指令,绑定文本框的内容,实现双向数据绑定。

<div id="app">
        <div>
            <!-- v-model指令默认触发的是input事件,当文本框的值发生变化时,离开同步给数据 -->
            姓名:<input type="text" v-model="name">{{name}}
        </div>
</div>
   <script>
       new Vue({
           el:'#app',
           data:{
               name:' 张三 ',
           }
       })
   </script>

(2)绑定多行文本
通过v-model指令,绑定多行文本框的内容,实现双向数据绑定。

<div id="app">
        <div>
            地址:<textarea cols="40" rows="3" v-model="address"></textarea>{{address}}
        </div>
</div>
<script>
       new Vue({
           el:'#app',
           data:{
               address:'江苏省.南京市.雨花台区.赛虹桥街道',
           }
       })
   </script>

(3)绑定单选框
绑定一组单选按钮,每个单选按钮通过v-model绑定相同的属性。

<div id="app">
      <div>
           <!-- v-model绑定一组单选框,每个单选框指定相同的属性(sex) -->
            性别:
            <input type="radio" value="男" v-model="sex" name="sex">男
            <input type="radio" value="女" v-model="sex" name="sex">女
            <span style="color: red;">{{sex}}</span>
      </div>
</div>
   <script>
        new Vue({
            el:'#app',
            data:{
                sex:'男',
            }
        })
    </script>

(4)复选框
① 绑定单个复选框(返回布尔值)
单个复选框,绑定到布尔值

<div id="app">
       <div>
            <!-- v-model绑定单个复选框,绑定一个boolean值 -->
            是否同意:<input type="checkbox" v-model="isOk">{{isOk}}
        </div>
</div>
    <script>
        new Vue({
            el:'#app',
            data:{
                isOk:false,
            }
        })
    </script>

② 绑定多个复选框(返回数组)
绑定多个复选框,通过v-model绑定同一个数组

   <div id="app">
        <div>
            <!-- v-model绑定多个复选框,绑定同一个数组 -->
            爱好:
            <input v-model="hobbies"  type="checkbox" value="吃饭">吃饭
            <input v-model="hobbies" type="checkbox" value="睡觉">睡觉
            <input v-model="hobbies" type="checkbox" value="打豆豆">打豆豆
            <input v-model="hobbies" type="checkbox" value="学习">学习
            <input v-model="hobbies" type="checkbox" value="追剧">追剧
            <input v-model="hobbies" type="checkbox" value="逛街">逛街
            <span style="color: red;">{{hobbies}}</span>
        </div>
   </div>
   <script>
        new Vue({
            el:'#app',
            data:{
               hobbies:['运动','旅游','健身'],
            }
        })
    </script>

(5)选择框
① 绑定单项选择框

<div id="app" >
<div>
            <!-- 绑定一个属性 -->
            城市:
            <select v-model="city">
                <option value="北京">北京</option>
                <option value="上海">上海</option>
                <option value="天津">天津</option>
                <option value="南京">南京</option>
                <option value="昆明">昆明</option>
            </select>
            <span style="color: red;">{{city}}</span>
        </div>
</div>
    <script>
        new Vue({
            el:'#app',
            data:{
               city:'南京',
            }
        })
    </script>

② 绑定多项选择框(绑定到一个数组)
下拉框设置multiple属性后,就可以选择多个项。
按住Ctrl键实现多项选择

<div id="app">
        <div>
            <!-- 绑定一个数组 -->
            喜欢的食物:
            <select multiple v-model="foods">
                <option value="苹果">苹果</option>
                <option value="蛋糕">蛋糕</option>
                <option value="西瓜">西瓜</option>
                <option value="面包">面包</option>
                <option value="草莓">草莓</option>
                <option value="牛奶">牛奶</option>
            </select>
            <span style="color: red;">{{foods}}</span>
        </div>
</div>
    <script>
        new Vue({
            el:'#app',
            data:{
               foods:['蛋糕','面包','牛奶']
            }
        })
    </script>

效果如下所示:


image.png

2、修饰符

(1).lazy
v-model指令默认触发的是input事件,当文本框的值发生变化时,离开同步给数据。
添加.lazy修饰符,可以将input事件转为change事件

<input type="text" v-model.lazy="name">

(2).number
自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

<input type="text" v-model.number="age">{{age+10}}

(3).trim
自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符

           <input type="text" v-model.trim="name">

二、绑定事件

通过v-on:指令绑定事件,@ 是v-on的简写。

1、事件绑定方法

(1)绑定事件不传参
通过v-on:指令绑定事件,指定一个methods选项里面的定义的方法。
调用方法时,不传参数,默认会将事件对象作为参数传递

<div id="app">
        <button @click="sayHi">sayHi</button>
</div>
<script>
       new Vue({
            el:'#app',
            methods: {
                sayHi(e){
                    console.log(e);     // 事件对象
                    alert('Hi!')
                }
            }
        })
</script>

(2)绑定事件传参
调用方法时,传递的是什么参数,接的就是什么参数

<div id="app">
        <button @click="sayHello('hello')">sayHello</button>
</div>
<script>
        new Vue({
            el:'#app',
            methods: {
                sayHello(e) {
                    console.log(e);   //Hello
                    alert('Hello')
                },
            }
        })
</script>

(3)绑定事件传参+事件对象
如果我们传递了一个参数,还想再传递事件对象参数,就要通过$event关键字设置参数,该参数就是事件对象。

<div id="app">
        <button @click="sayNice('Nice',$event)">sayNice</button>
</div>
<script>
        new Vue({
            el:'#app',
            methods: {
                sayNice(msg, e) {
                    console.log(e);
                    alert(msg)
                },
            }
        })
</script>

2、行内编写

如果当前事件处理的代码比较简单,就可以将代码直接写在行内。
注意:只能操作Vue管理的数据

<div id="app">
        <button @click="age++">年龄++</button>
</div>
<script>
        new Vue({
            el:'#app',
            data: {
                age: 20
            },
        })
</script>

3、事件修饰符

(1).prevent
在事件处理程序中调用 event.preventDefault() 阻止默认行为。
Vue中可以通过.prevent事件修饰符,阻止默认行为。

<div id="app">
<div class="box" @contextmenu.prevent="showbox">
</div>
</div>
<script>
new Vue({
            el:'#app',
            methods: {
                showbox(e) {
                    // 阻止默认行为
                    // event.preventDefault()
                    console.log('我是box');
                },
            },
        })
</script>

(2).stop
在事件处理程序中调用 event.stopPropagation() 阻止事件冒泡。
Vue中可以通过.stop事件修饰符,阻止事件冒泡。(绑定给子元素)

<div class="app" >
<div class="one" @click="one">
            <div class="two" @click.stop="two"></div>
        </div>
</div>
<script>
       new Vue({
            el:'#app',
            methods: {
                 one() {
                    console.log('我是one');
                },
                two(e) {
                    // 阻止事件冒泡
                    // e.stopPropagation();
                    console.log('我是two');
                },
            },
        })
</script>

(3).once
表示点击事件将只会触发一次。
.once 修饰符还能被用到自定义的组件事件上。

<div class="one" @click.once="one">
    <div class="two" @click.stop="two"></div>
</div>

(4).self
只能在自身元素上触发,不能在子元素上触发

<div class="app" >
       <div class="box2" @click.self="showbox2">
            <div class="box3"></div>
        </div>
</div>
<script>
        new Vue({
            el:'#app',
            methods: {
                  showbox2() {
                    console.log('我是box2');
                }
            },
        })
</script>

3、按键修饰符

Vue针对键盘事件,提供了按键修饰符。按键修饰符也可以用按键码(keyCode)代替,例如.enter可以用.13代替。(注意:Vue3中取消了按键码)
一共有9个按键修饰符,分别是:
.enter 是回车键
.tab 是tab键
.delete 是删除键和退格键
.esc 是退出键
.space 是空格键
.up 是上箭头
.down 是下箭头
.left 是左箭头
.right 是右箭头

<div class="app" >
       <div>
           <!-- 每次键盘弹起都会调用事件方法 -->
            请输入搜索关键字:<input type="text" @keyup="keyup">
        </div>
        <div>
            <!-- 只在回车时,才会调用事件方法 -->
            请输入搜索关键字:<input type="text" @keyup.enter="keyup1">
        </div>
        </div>
</div>
<script>
        new Vue({
            el:'#app',
            methods: {
                  keyup(e) {
                       let { keyCode } = e
                       if (keyCode === 13) {
                             alert('搜索成功')
                       }
                  },
                  keyup1(e) {
                      alert('搜索指定的商品')
                  }
            },
        })
</script>

三、深度式响应

Vue实例在初始化的时候,会将obj对象身上的所有数据,采用Object.defineProperty去封装,做响应式处理。所谓响应式,指的是数据发生变化后,页面自动更新。
但是给对象后添加的数据不会采用Object.defineProperty去封装,所以就不再具备响应式能力了。

实现后添加的数据也具备响应式能力,有以下两种方式:
① 通过Vue的set方法,更新指定的对象属性或数组成员;delete方法,删除指定对象的属性或数组的成员。
② 通过Vue实例的set方法,更新指定的对象属性或数组成员;delete方法,删除指定对象的属性或数组的成员。

1、更新对象

set方法的参数分别是:指定的对象,对象的属性,属性值。
delete方法的参数分别是:指定的对象,对象的属性。

    <div id="app">
        <div>
            学生信息:
            <input type="text" v-model="obj.name">
            <input type="text" v-model.number="obj.age">
            <button @click="addSex">添加性别</button>
            <button @click="delAge">删除年龄</button>
            <br>
            {{obj}}
        </div>
    </div>
        let vm = new Vue({
            el:'#app',
            data:{
                obj:{
                    name:'张三',
                    age:20,
                }
            },
            methods: {
                // 添加性别
                addSex(){
                    // 使用普通方法给对象后添加的属性,失去了响应式
                    // this.obj.sex = '男'

                    // vue通过set方法,给对象添加响应式属性
                    // Vue.set(this.obj,'sex','男')

                    // vue实例通过$set方法,给对象添加响应式属性
                    this.$set(this.obj,'sex','男')
                },
                // 删除年龄
                delAge(){
                    // 采用delete关键字删除对象的属性后,没有触发页面更新
                    // delete this.obj.age

                    // Vue的delete方法,删除对象的属性,并触发响应式
                    // Vue.delete(this.obj,'age')

                    // vue实例通过$delete方法,删除对象的属性,并触发响应式
                    this.$delete(this.obj,'age')
                }
            },
        })

2、更新数组

在vue中,操作数组只能通过以下方法,才能实现响应式:push()、pop()、unshift() 、shift()、splice()、reverse()、sort()。
如果想通过下标直接操作数组,也必须要使用Vue的sett和delete方法或者Vue实例的set和delete方法。
set方法的参数分别是:指定的数组,数组的下标,对应的数据。
delete方法的参数分别是:指定的数组,数组的下标。

    <div id="app">
        <div>
            数组:{{arr}}
            <button @click="updateArr">修改数据</button>
            <button @click="addArr">添加数据</button>
            <button @click="delArr">删除数据</button>
        </div>
    </div>
        let vm = new Vue({
            el:'#app',
            data:{
                arr:[11,22,33,44,55]
            },
            methods: {
                // 修改数组身上的成员
                updateArr(){
                    // 注意:直接利用索引设置数组项,不会触发页面更新
                    // this.arr[1] = 32

                    // vue通过set方法,可以利用索引直接设置一个数组项
                    // Vue.set(this.arr,1,32)

                    // vue实例通过$set方法,可以利用索引直接设置一个数组项
                    this.$set(this.arr,1,32)
                },
                // 添加数组的数据
                addArr(){
                    // this.arr[5] = 66    // 注意:采用这种方式,不会触发页面更新

                    // vue通过set方法,给数组添加响应式数据
                    // Vue.set(this.arr,5,66)

                    // vue实例通过$set方法,给数组添加响应式数据
                    this.$set(this.arr,5,66)
                },
                // 删除数组的数据
                delArr(){
                    // 采用delete关键字删除数组下标为2的元素后,没有触发页面更新
                    // delete this.arr[2]

                    // vue通过delete方法,给数组删除数据,并触发响应式
                    // Vue.delete(this.arr,2)

                    // vue实例通过$delete方法,给数组删除数据,并触发响应式
                    this.$delete(this.arr,2)
                }
            },
        })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容