Vue.js(二):绑定

绑定

使用 Vue.js,从命令式编程走向声明式编程。

以设置 DOM 数据为例,使用命令式的做法:找到DOM项目 ➡️设置值。
使用声明式,只需要一步:直接声明绑定

使用声明编程后,编写此类代码的好处:

  • 不必访问 DOM API 即可修改 DOM;
  • 响应式的风格:不但第一次给设置好,当绑定的数据值变化了,DOM 显示会跟着变化。

如下代码展示我提到的绑定的两个特征:

<div id="app">{{value}}</div>
<script>
new Vue({
  el: '#app',
  data(){
    return {value:42}
  },
  mounted(){
    setTimeout(this.a,1000)
  },
  methods:{
    a(){
      this.value++
      console.log(this.value)
      setTimeout(this.a,1000)
    }
  }
})
</script>

首先,在插值的地方使用形如 {{}} 的符号,声明此值绑定到一个成员变量,Vue 就会知道:需要从对应 Vue 实例中的 data 函数返回的对象内查找 value,并使用它的值来填充占位。

DOM 的标签会跟着 value 的变化而变化。

绑定包括数据绑定、事件绑定、元素绑定。

🐼 数据绑定
  • 插入值绑定

具体说来,就是把实例内的数据成员绑定到插入值指定的位置。采用Mustache 语法,即 {{}}

插入值绑定将会把数据对象上的属性值插入到 Mustache 指示的位置,且绑定的数据对象的变化会导致插值的变化。

如果不希望后续的变化修改插值,可以使用 v-once 指令。就是修改一行代码 <div id="app">{{value}}</div> 为:<div id="app" v-once>{{value}}</div>

在 Mustache 内还可以使用 JavaScript 表达式,比如:{{ value + 1 }}

但是每个绑定都只能包含单个表达式。语句或者多个表达式是不可以的。

想要绑定到属性,就得使用指令 v-bind

<input v-bind:value="value">
🥑 针对 class 的情况

针对标签属性 class,v-bind 可以直接传入一个对象作为属性值,像是这样:

<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

如果 isActive 为 true,那么 active 作为字符串拼接结果的一部分;如果 hasError 为 true,则 text-danger 为字符串拼接结果的一部分。

因此:

data: {
  isActive: true,
  hasError: false
}

得到的渲染结果为:

<div class="active"></div>

也可以传入一个数组作为 class 属性的值:

<div v-bind:class="[active,text-danger]"></div>

得到的渲染结果为:

<div class="active text-danger"></div>
🍐 针对 style 的情况

也可以如针对 class 那样,传入对象或者数组,对象就是一个 style 对象,数组则是多个 style 对象。

🌰:

<div v-bind:style="styleObject">abc</div>

data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

渲染出来的结果为:

<div style="color:red;fontSize:13px; ">abc</div>

完整演示对象和数组的代码为:

<div id="app">
  <!--方法一-->
  <div style="color:red;fontSize:13px;">abc</div> 
  <!--方法二-->
  <div v-bind:style="[s1,s2]">abc</div>
  <!--方法三-->
  <div v-bind:style="styleObject">abc</div>
</div>
<script>
  var a= new Vue({
     el: '#app',
     data: {
      styleObject: {
        color: 'red',
        fontSize: '13px'
      },
      s1: {
        color: 'red',
      },
      s2: {
        fontSize: '13px'
      }
    }
  })
</script>

🐻 事件绑定

指令 v-on 可以监听 DOM 事件。

🌰:
显示一个按钮,点击此按钮会在控制台打印 “BUTTON”:

<div id="app">
  <button v-on:click="who">who</button>
</div>
<script>
  var a= new Vue({
    el: '#app',
    methods: {
      who: function (event) {
        console.log(event.target.tagName)
      }    
    }
  })
</script>

指令 v-on 会把参数(click)指定的事件挂接到属性值指定的方法(who)上。方法 who 的参数 event 为原生的 JavaScript 事件对象。

指令 v-on 可以使用 修饰符

可以选这些修饰符:

  • .stop
  • .prevent
  • .capture
  • .self

还有一类特别的修饰符用于 键盘事件 的修饰:

  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
.keyup.enter  //表示侦听enter键的keyup事件。

也可以在 keyup 修饰符后跟着一个数字表示按键的 ASCII 码

.13 等同于.enter

🐰 元素绑定

不但可以做属性绑定,元素也可以绑定的。比如根据表达式条件的不同来绑定不同的元素,或者循环绑定元素。

🥑 v-if

指令 v-if 可以完成条件化的元素绑定。比如:

<h1 v-if="false">h1</h1>
<h2 v-else>h2</h2>

当然,如果不必要,v-else 是可以不写的。

如果需要条件化绑定的是一组元素,可以使用 <template> 来打包分组:

  <template v-if="true">
     <h1>h1</h1>
     <p>big title</p>
  </template>
  <template v-else>
     <h1>h2</h1>
     <p>second title</p>
  </template>

有一个叫做 v-show 的指令,可以根据表达式的真假值来决定是否显示元素。
但是,即使表达式是假值,元素依然会绑定到DOM中,只是并不显示:
<h1 v-show="false">h1</h1>
因此,它并不是一个元素绑定指令。

🍐 v-for

指令 v-for 基于一个数组渲染一组元素。这个指令的表达式使用特殊的语法,形式为:

  • item in items 或者 item of items,
  • 或者 (item, index) in items,如果你需要循环索引的话。

🌰:

<div id="app"><ul>
    <li v-for="(item, index) in items">{{ item }},{{ index }}</li>
</ul></div>
<script>
  var a= new Vue({
      el: '#app',
      data(){return {items :[1,2,3]} } 
    }
  )
</script>

输出:
1,0
2,1
3,2

指令 v-for 也可以对对象进行迭代,每个迭代出来的项目就是一个属性/值对:

<div id="app"><ul>
    <li v-for="(v,k) in person">{{ k }}:{{ v }}</li>
</ul></div>
<script>
  var a= new Vue({
      el: '#app',
      data(){return {
        person :{
          name:'frodo',
          group:'ring fellow'
        } 
      } 
    }}
  )
</script>

指令 v-for 也可以对整数迭代,等于循环整数次:

<div id="app"><ul>
    <li v-for="v in 3">{{ v }}</li>
</ul></div>
<script>
  var a= new Vue({
      el: '#app'
    }
  )
</script>

数组的响应化

在 v-for 的案例中我们对一个数组(items)进行迭代,创建了元素绑定。现在或许有人会怀疑:如果我修改了数组,是否也可以因此响应式地影响到 DOM 呢。答案是可能。

🌰:其中添加了一个定时器,每秒钟调用一个函数,函数内有不同的数组方法:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app"><ul>
  <li v-for="item in items">{{ item }}</li>
  </ul></div>
<script>
  var a= new Vue({
    el: '#app',
    mounted(){
      this.funcs[0] = this.b
      this.funcs[1] = this.c
      this.funcs[2] = this.d
      this.funcs[3] = this.e
      this.funcs[4] = this.f
      this.funcs[5] = this.g
      this.funcs[6] = this.h
      this.funcs[7] = this.i
      this.funcs[8] = this.j
      setTimeout(this.a,1000)
    },
    data(){return {
      items :[1,2,3],
      funcs:[],
      funcIndex : 0 
}}, 
    methods:{
      a(){ 
        this.funcs[this.funcIndex]()
        this.funcIndex++
        if (this.funcIndex < this.funcs.length)
          setTimeout(this.a,1000) 
      },
      b(){
        this.items.push(4)
      },
      c(){
        this.items.pop() 
      },
      d(){
        this.items.shift() 
      },
      e(){
        this.items.unshift(1) 
      },
      f(){
        this.items.splice(1,1)  
      },
      g(){
        this.items.reverse()  
      },
      h(){
        this.items.sort()  
      },
      i(){
        // this.items[0] = 111  
        Vue.set(this.items,0,111)
      },
      j(){
        // this.items.length = 1
        this.items.splice(1,1)  
      }
    }
  })
</script>

测试表明,对以下方法的调用,Vue 确实会做响应的修改:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

但是需要留意最后两个函数,i() , j(), 其中的 i() 函数内如果使用:

this.items[0] = 111

并不会引发响应变化。这是 vue 的一个限制,如果希望修改数组项并因此响应化的更新 DOM,那么需要这样做:

Vue.set(this.items,0,111)

另外一个是数组的 length 属性,修改它 DOM 并不会跟随变化。如果你的本意是删除一个元素,可以用:this.items.splice(1,1) 来做替代。

绑定控件

控件绑定常常涉及到双向绑定,此时使用 v-model 让它更加简单。

<div id="app">
  <label><input type="checkbox" v-model="checked">v-model</label><br/>
  <label for="checkbox">{{ checked }}</label>
</div>
<script>
  var a= new Vue({
      el: '#app',
      data(){return {checked : true} }
    }
  )
</script>

正如我们已经看到的:v-model 是 v-bind 和 v-on 的语法糖。但是这个语法糖确实很甜。

具体的控件的绑定

🍵 text
<input type="text" v-model="message">
🥛 checkbox
  • 单个 checkbox 的情况下:
<input type="checkbox" v-model="checked">
  • 多个 checkbox 的情况下:
<input type="checkbox" value="1" v-model="checks">
<input type="checkbox" value="2" v-model="checks">
<input type="checkbox" value="3" v-model="checks">
🍹 radio

此控件可以成组使用,组内互斥选择,最后只能选择一项目:

<div id="app">
   <input type="radio" value="1" v-model="which">
   <input type="radio" value="2" v-model="which">
   <span>{{ which }}</span>
</div>
<script>
  var a= new Vue({
      el: '#app',
      data(){return {which :"2"} }
    }
  )
</script>
☕️ select

此控件允许多选和单选。

  • 单选 的情况下,v-model 指向到单项数据:
<div id="app">
    <select v-model="which" >
      <option which>1</option>
      <option>2</option>
      <option>3</option>
    </select>
    <span>which: {{ which }}</span>
</div>
<script>
  var a= new Vue({
      el: '#app',
      data(){return {which :"2"} }
    }
  )
</script>
  • 多选 情况下,v-model 对应的是一个数组:
<div id="app">
    <select v-model="which" multiple>
      <option>1</option>
      <option>2</option>
      <option>3</option>
    </select>
    <span>which: {{ which }}</span>
</div>
<script>
  var a= new Vue({
      el: '#app',
      data(){return {which :["2","3"] } } 
   }
  )
</script>
🥤 textarea

作为多行文本区的 textarea,可以这样绑定:

<textarea v-model="msg"></textarea>

🌰:

<div id="app">
  <textarea v-model="msg" placeholder="input some lines"></textarea>
  <p style="white-space: pre">message:<br>{{ msg }}</p>
</div>
 <script>
    new Vue({
      el:'#app',
      data:{msg:''}
    })
</script>

可以在文本区内输入多行文本,内容会照搬到 p 标签内。




🔗:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值