Vue----class与style绑定,事件的绑定,事件相关的处理

class与style绑定

  • class 绑定

对象

<!DOCTYPE html><html lang="en"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>class绑定</title>
  <style>
    .coloractive {
      color: red;
    }
    .bgactive {
      background-color: green;
    }
    .box {
      width: 150px;
      height: 150px;
      background-color: #f66;
      position: relative;
    }
    .active {
      position: absolute;
      top: 3px;
      left: 3px;
    }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body>
  <div id="app">
    <div class="coloractive bgactive">样式的写法</div>
    <div class="coloractive" :class="{ bgactive: flag}">class对象的绑定</div>
    <div class="box" v-for="item of list">
      <div :class="{ active: item.flag }">{{ item.msg }}</div>
    </div>
  </div></body><script>
  // 如果样式的名称是后端给你提供的class的名字,前端不能直接写,此时就可以使用class绑定
  // 场景: 产品列表中的 hot 、 秒杀、....,后端会给你传递一个标识,前端可以依据这个标识搞事情
  // class 绑定有两种形式
  // 对象
  new Vue({
    el: '#app',
    data: {
      list: [{
        flag: true,
        msg: '秒杀'
      },
      {
        flag: false,
        msg: ''
      },
      {
        flag: true,
        msg: '热推'
      }]
    }
  })
</script></html>

76b1c821bd9fa6ebe7ca1b49ae1038a9.png

数组

<!DOCTYPE html><html lang="en"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>class绑定</title>
  <style>
    .class1 {
      font-size: 32px;
      color: #f66;
    }
    .class2 {
      background-color: #ccc;
    }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body>
  <div id="app">
    <div class="class1 class2">class数组写法</div>
    <div :class="[classa, classb]">class数组写法</div>
  </div></body><script>
 
  new Vue({
    el: '#app',
    data: {
      classa: 'class1',
      classb: 'class2'
    }
  })
</script></html>

32d65a2e7acbce73f0e50a7ac62e6610.png

  • 作业:查看api 熟练使用style绑定对象形式和数组形式

条件判断

v-if v-else-if v-else

v-show

注意审查元素查看效果

<body>
  <div id="app">
    <div v-if="flag">如果为真我就显示</div>
    <div v-if="Math.random() < 0.2"> 0.2 </div>
    <div v-else-if="Math.random() < 0.8"> 0.8 </div>
    <div v-else="Math.random() < 1"> 1 </div>

    <div v-show="flag">如过为真我就显示</div>
  </div></body><script>
  new Vue({
    el: '#app',
    data: {
      flag: false
    }
  })
</script>

a7c93e489583bbc14ab4e73d51962da5.png

作业: 什么时候使用v-if,什么时候使用v-show

列表渲染

v-for
key ********************************************

key 不可以重复、key可以为 用户id、产品id,**id,因为id具有唯一性

node项目中使用uuid确保id是不重复的

4006a661c82a06e9a624cf544ed3cb6e.png

? 思考, js中 数组可以遍历,对象能不能遍历,字符串能不能遍历

key

<body>
  <div id="app">
    <ul>
      <li v-for="item in arr1">{{ item }}</li>
    </ul>
    <ul>
      <li v-for="(item, index) in arr1" :key="index">{{ item }}</li>
    </ul>
    <ul>
      <li v-for="(item, index) of arr1" :key="item">{{ item }}</li>
    </ul>
  </div></body><script>
  var app = new Vue({
    el: '#app',
    data: {
      arr1: ['a', 'b', 'c']
    }
  })
</script>

多层遍历

<body>
  <div id="app">
      <h1>遍历数组  无key值</h1>
    <ul>
      <li v-for="item in arr1">{{ item }}</li>
    </ul>
    <h1>遍历数组  key值为索引值</h1>
    <ul>
      <li v-for="(item, index) in arr1" :key="index">{{ item }}</li>
    </ul>
    <h1>遍历数组  key值为唯一值</h1>
    <ul>
      <li v-for="(item, index) of arr1" :key="item">{{ item }}</li>
    </ul>
    <h1>遍历对象数组</h1>
    <ul>
      <li v-for="item of arr2" :key="item.bannerid">
        <img :src="item.img" alt="">
      </li>
    </ul>
    <h1>多层遍历,内层循环换个变量名和索引值是为了区分</h1>
    <ul>
      <li v-for="(item, index) of arr3" :key="index">
        <h1>{{ item.brand }}</h1>
        <ol>
          <li v-for="(itm, idx) of item.list" :key="idx">
            {{ itm }} - {{ item.brand }}
          </li>
        </ol>
      </li>
    </ul>
  </div></body><script>
  var app = new Vue({
    el: '#app',
    data: {
      arr1: ['a', 'b', 'c'],
      arr2: [{ bannerid: 'banner_1', img: 'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/89951/22/13835/67854/5e64a4b8E84c207d9/7367dad332fe905b.jpg!cr_1125x445_0_171!q70.jpg.dpg', href: '', alt: '' }, { bannerid: 'banner_2', img: 'https://imgcps.jd.com/ling4/1670651/6Z2i6Iac55yB5b-D55yB5Yqb/5ZOB6LSo5rqQ5LqO5Y2T6LaK/p-5c13869682acdd181deeff08/2d409b2d/cr_1125x445_0_171/s1125x690/q70.jpg', href: '', alt: '' }, { bannerid: 'banner_3', img: 'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/88149/40/14147/100076/5e6229a8Ef51e1321/54e2c5dd2c357e1e.jpg!cr_1125x445_0_171!q70.jpg.dpg', href: '', alt: '' }, { bannerid: 'banner_4', img: 'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/93827/39/13300/60640/5e561c60Edd0d8e34/73428f511893f63e.jpg!cr_1125x445_0_171!q70.jpg.dpg', href: '', alt: '' }],
      arr3: [{
        brand: '宝马',
        list: ['X5', 'X6']
      },{
        brand: '奥迪',
        list: ['Q7', 'A8']
      }]
    }
  })
</script>

事件处理

  • 事件处理-行内
<body>
  <div id="app">
    <h3>计数器</h3>
    <div>
      <button v-on:click="count += 1">点击</button> {{ count }} 次
    </div>
    <h3>案例 ---  简单业务逻辑可以考虑使用 行内的事件处理</h3>
    <ul>
      <li v-for="(item, index) of list" :key="index">
        {{ item.name }} - 
        <button :disabled="item.num === 1" @click="item.num > 1 ? item.num -= 1: item.num = 1">-</button> 
        {{ item.num }}
        <button @click="item.num += 1">+</button>
      </li>
    </ul>
  </div></body><script>
  new Vue({
    el: '#app',
    data: {
      count: 0,
      list: [
        {
          name:'aaa',
          num:1
        },
        {
          name:'bbb',
          num:2
        }
      ]
    }
  })
</script>

总结:这也就是玩一玩而已,项目中一般不要使用,比如上一个案例,如果点击 加 ,先向服务器发起更新数据库的操作,得到回应后采取改变视图

  • 事件处理-方法

不传参可以不写(),要传参就传对象

<body>
  <div id="app">
    <h3>计数器</h3>
    <div>
      <button v-on:click="countfn">点击</button> {{ count }} 次
    </div>
    <h3>案例 --  传对象</h3>
    <ul>
      <li v-for="(item, index) of list" :key="index">
        {{ item.name }} - 
        <button :disabled="item.num === 1" @click=" reduce(item)">-</button> 
        {{ item.num }}
        <button @click="add(item)">+</button>
      </li>
    </ul>
  </div></body><script>
  new Vue({
    el: '#app',
    data: {
      count: 0,
      list: [
        {
          name:'aaa',
          num:1
        },
        {
          name:'bbb',
          num:2
        }
      ]
    },
    methods: { // vue自定义的事件
      countfn () {
        this.count += 1
      },
      reduce (item) {
        // 服务器发起请求  --- 成功
        item.num > 1 ? item.num -= 1 : item.num = 1
      },
      add (item) {
        // 服务器发起请求  --- 成功
        item.num += 1
      }
    }
  })
</script>
  • 事件处理 - 事件对象
    不传参,方法默认参数为事件对象
    36456e3ee6080eeb2f94e98ce5863afb.png
    7df39443f7bf53f7f99ce2b8e70e7a11.png

传递参数,并且获取事件对象 - $event
5d57a49ac29eee8319f77089d7a34be8.png
2183ab69f8ba9f915ea56cecfa330ca1.png

? 思考:一般使用事件对象解决什么问题? ---- 复习js中的事件对象

阻止默认事件、阻止冒泡、获取鼠标位置、获取事件源、获取DOM节点,传递数据,确定按键.........

利用事件对象阻止冒泡
b8df2328019d31fa86b87cfb6c45eabb.png

虽然可以利用事件对象解决冒泡问题,但是你还使用了 event事件对象

事件修饰符
07ffff76499a76d4819b3c69e88ce45e.png

常用的事件修饰符

<!-- 阻止单击事件继续传播 --> 
<a v-on:click.stop="doThis"></a> 
<!-- 提交事件不再重载页面 --> 
<form v-on:submit.prevent="onSubmit"></form> 
<!-- 修饰符可以串联 --><a v-on:click.stop.prevent="doThat"></a><!-- 只有修饰符 --><form v-on:submit.prevent></form> 
<!-- 添加事件监听器时使用事件捕获模式 --> 
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 --> 
<div v-on:click.capture="doThis">...</div> 
<!-- 只当在 event.target 是当前元素自身时触发处理函数 --><!-- 即事件不是从内部元素触发的 --> 
<div v-on:click.self="doThat">...</div>

<!-- 点击事件将只会触发一次 --> 
<a v-on:click.once="doThis"></a>

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --><!-- 而不会等待 `onScroll` 完成 --> 
<!-- 这其中包含 `event.preventDefault()` 的情况 --> 
<!-- 这个 .passive 修饰符尤其能够提升移动端的性能。 --><div v-on:scroll.passive="onScroll">...</div>

591e2e49285a73c82427dd5c8545d190.png

不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

按键修饰符

efad1de26a3103a3d2a7883f61440f51.png
e5c40a99c537d4985d067b26079072db.png
image.png

72298df17dde00508691c8359566f3b4.png

表单的数据绑定

v-model

如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。

<body>
  <div id="app">
    <div>
      用户名:
      <input type="text" v-mode="username" /> {{ username }}
    </div>
    <div>
      密码:
      <input type="password" v-model="password" /> {{ password }}
    </div>
    <div>
      性别:
      <input type="radio" name="sex" value="1" v-model="sex">男
      <input type="radio" name="sex" value="0" v-model="sex">女
    </div>
    <div>
      爱好:
      <input type="checkbox" value="篮球" v-model="hobby">篮球
      <input type="checkbox" value="排球" v-model="hobby">排球
      <input type="checkbox" value="足球" v-model="hobby">足球
      <input type="checkbox" value="乒乓球" v-model="hobby">乒乓球
    </div>
    <div>
      阶段
      <select v-model="lesson">
        <option disabled value="">请选择</option>
        <option value="一阶段">一阶段</option>
        <option value="二阶段">二阶段</option>
        <option value="三阶段">三阶段</option>
      </select>
    </div>
    <div>
      备注:
      <textarea v-model="note"></textarea>
    </div>
    <div>
      <input type="checkbox" v-model='flag'>同意***协议
      {{ flag }}
    </div>
    <button @click="login">登陆</button>
  </div></body><script>
  var app = new Vue({
    el: '#app',
    data: { // Vue 实例也代理了 data 对象上所有的属性
      username: '大勋勋',
      password: '123456',
      sex: '1',
      hobby: [], // 多选  ---  初始化数据为 数组
      lesson: '',
      note: '',
      flag: false // 选中还是未选中 - 单选 -- 初始化为boolean
    },
    methods: {
      login () {
        this.flag ? console.log({
          username: this.username,
          password: this.password,
          sex: this.sex === '1' ? '男' : '女',
          hobby: this.hobby,
          lesson: this.lesson,
          note: this.note
        }) : console.log('请先勾选同意此协议')
      }
    }
  })
  console.log(app.username)
  console.log(app.$data.username)
</script>

追加修饰符 lazy / number / trim
746c032dcd2cc8e2d0df7685b015f1a8.png

一般使用 trim 为居多

玩表单 不忘 v-model

v-model 有特殊

特殊1 checkbox 数组表多选 bool表单选

特殊2 select 不选第一项

计算属性

任何复杂的业务逻辑,我们都应当使用计算属性

计算属性具有依赖性,只有依赖的那个值发生了改变,计算属性才会重新计算,原数据不变,计算属性就不会执行 --- 缓存

所有的计算属性被包含在computed选项中

计算属性其实就是一个函数,必须得返回一个值,使用形式形如data中的数据

<!DOCTYPE html><html lang="en"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>表单输入绑定</title>
  <style>
    .error {
      color: #f00
    }
    .success {
      color: #0f0
    }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body>
  <div id="app">
    <div>
      用户名:
      <input type="text" v-model.trim="username" /> {{ username }} - <span v-html="usernametip"></span>
    </div>
    <div>
      密码:
      <input type="password" v-model="password" /> {{ password }}
    </div>
    <div>
      性别:
      <input type="radio" name="sex" value="1" v-model="sex">男
      <input type="radio" name="sex" value="0" v-model="sex">女
    </div>
    <div>
      爱好:
      <input type="checkbox" value="篮球" v-model="hobby">篮球
      <input type="checkbox" value="排球" v-model="hobby">排球
      <input type="checkbox" value="足球" v-model="hobby">足球
      <input type="checkbox" value="乒乓球" v-model="hobby">乒乓球
    </div>
    <div>
      阶段
      <select v-model="lesson">
        <option disabled value="">请选择</option>
        <option value="一阶段">一阶段</option>
        <option value="二阶段">二阶段</option>
        <option value="三阶段">三阶段</option>
      </select>
    </div>
    <div>
      备注:
      <textarea v-model="note"></textarea>
    </div>
    <div>
      <input type="checkbox" v-model='flag'>同意***协议
      {{ flag }}
    </div>
    <button @click="login">登陆</button>
  </div></body><script>
  var app = new Vue({
    el: '#app',
    data: { // Vue 实例也代理了 data 对象上所有的属性
      username: '',
      password: '',
      sex: '1',
      hobby: [], // 多选  ---  初始化数据为 数组
      lesson: '',
      note: '',
      flag: false // 选中还是未选中 - 单选 -- 初始化为boolean
    },
    computed: { // 计算属性
      usernametip () {
        if (this.username === '') {
          return '<span>请输入用户名</span>'
        }
        if (this.username.length < 6) {
          return '<span class="error">用户名格式错误</span>'
        } else {
          return '<span class="success">ok</span>'
        }
      }
    },
    methods: {
      login () {
        this.flag ? console.log({
          username: this.username,
          password: this.password,
          sex: this.sex === '1' ? '男' : '女',
          hobby: this.hobby,
          lesson: this.lesson,
          note: this.note
        }) : console.log('请先勾选同意此协议')
      }
    }
  })
  console.log(app.username)
  console.log(app.$data.username)
</script></html>

 

-------------------------------------------------------文章来自吴大勋(大勋说

posted @ 2020-04-20 23:28  haccer  阅读(925)  评论(0编辑  收藏  举报