Vue第二天笔记

108 阅读5分钟

1.回顾-数组的reduce求和方法

<!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>
  <script>
    let arr = [3, 5, 2, 7]
    // 语法一:不带初始值(一般只有两个形参(累加的和,数组元素)常用)
    let sum1 = arr.reduce(function (pre, cur, index, arr) {
      return pre + cur
    })
    console.log(sum1)

    //语法一的 箭头函数写法:
    let sum2 = arr.reduce((pre, cur, index, arr) => pre + cur)
    console.log(sum2)


    
    // 语法二:带初始值
    let sum3 = arr.reduce(function (pre, cur, index, arr) {
      return pre + cur
    }, 3)
    console.log(sum3)
  </script>
</body>

</html>

结果:

image.png

1.1 案例——计算总数量

<!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>
  <script>
    <!-- 计算总数量例子 -->
    let list = [
      { id: 1, name: '篮球', num: 3 },
      { id: 2, name: '网球', num: 2 },
      { id: 3, name: '乒乓球', num: 6 }]

    let sum = list.reduce((total, cur) => {
      return total + cur.num
    }, 0)
    console.log(sum)
  </script>
</body>

</html>

image.png

2. 指令修饰符

image.png

2.1 按键修饰符

<!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">
    <h3>监听键盘事件</h3>
    <!-- 1.按键修饰符只能用于键盘事件。keyup和keydown事件。
    2.@keyup.enter='' 表示按回车键才会执行操作
    3.@keyup.esc=''   表示按esc键才会执行操作
    4.@keyup.49=''    表示按keyCode值为49的键才会执行操作,这里的49表示1键(即keyCode值) -->
    <input type="text" @keyup.enter="fn">
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      methods: {
        fn() {
          console.log('回车事件触发')
        }
      }

    })
  </script>
</body>

</html>

结果:

image.png

2.2 事件修饰符

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 200px;
      height: 200px;
      background-color: pink;
    }

    .son {
      width: 100px;
      height: 100px;
      background-color: skyblue;
    }
  </style>
</head>

<body>
  <div id="app">

    <div class="father" @click="fn1">
      <!-- 给son绑定阻止默认行为的指令 -->
      <div class="son" @click.stop="fn2">儿子</div>
    </div>
    <h3>@事件名.prevernt=>阻止默认行为</h3>
    <a href="http://www.baidu.com" @click.prevent="fn3">阻止默认行为</a>


  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      methods: {
        fn1() {
          console.log('父元素被点击了')
        },
        fn2() {
          console.log('子元素被点击了')
        },
        fn3() {
          console.log('阻止默认行为成功')
        }
      }


    })
  </script>
</body>

</html>

结果:

image.png

2.3 v-model修饰符

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>

  </style>
</head>

<body>
  <div id="app">
    <!-- input v-model.trim='xx'     去除字符串两边的空白
  input v-model.number ='xx'     转换输入框的字符为number类型(填数字才有效)
  input v-model.lazy='xx'      输入框change时,才更新数据-->
    <h3>v-model修饰符,trim.number.lazy</h3>
    姓名:<input type="text" v-model.trim="uname"><br>
    年纪:<input type="text" v-model.number="age"><br>
    手机:<input type="text" v-model.change="phone"><br>
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        uname: '',
        age: 20,
        phone: ''
      }
    })
  </script>
</body>

</html>

2.4 v-model应用于其他表单元素

image.png

2.5 v-bind对class的控制

image.png

2.6 v-bind对于样式控制的增强-操作style

(与2.4的区别是只控制样式) image.png

<!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">
    <!-- v-model可以让数字和视图形成双向数据绑定 
     1.数据变化,视图自动更新
     2.视图变化,数据自动更新
     可以快速获取或者设置表单元素的内容
-->
    姓名: <input type="text" v-model="uname" /><br />
    性别: <input type="radio" v-model="sex" value="男" /><input type="radio" v-model="sex" value="女" />女

    爱好:
    <input type="checkbox" v-model="hobby" value="看电影">看电影">
    <input type="checkbox" v-model="hobby" value="睡觉">睡觉">
    <input type="checkbox" v-model="hobby" value="吃饭">吃饭"><br>

    籍贯:
    <select>
      <option value="北京">北京</option>
      <option value="上海">上海</option>
      <option value="广州">广州</option>
    </select><br>

    记住我:<input type="checkbox">


  </div>
  <!-- <script src="./vue.js"></script> -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        uname: '张三',
        age: 18,
        sex: '男',
        hobby: ['睡觉', '吃饭'],
        city: '北京'
      }
    })
  </script>
</body>

</html>

结果:

image.png

2.7 computed计算属性

image.png

2.7.1 通过属性实现

<!DOCTYPE html>
<html lang="en">

实现
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    table {
      border: 1px solid #000;
      text-align: center;
      width: 300px;
    }

    th,
    td {
      border: 1px solid #000;
    }

    h3 {
      position: relative;
    }

    span {
      position: absolute;
      left: 145px;
      top: -4px;
      width: 16px;
      height: 16px;
      color: white;
      font-size: 12px;
      text-align: center;
      border-radius: 50%;
      background-color: #e63f32;
    }
  </style>
</head>

<body>

  <div id="app">
    <h3>小黑的礼物清单🛒<span>?</span></h3>
    <table>
      <tr>
        <th>名字</th>
        <th>数量</th>
      </tr>
      <tr v-for="item in list" :key="item.id">
        <td>{{item.name}}</td>
        <td>{{item.num}}</td>
      </tr>
    </table>

    <p>礼物总数:{{total}} 个</p>
  </div>
  <!-- Vue 2.x 版本 -->
  <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> -->

  <!-- Vue 3.x 版本 -->
  <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        // 现有的数据
        list: [
          { id: 1, name: '篮球', num: 3 },
          { id: 2, name: '玩具', num: 2 },
          { id: 3, name: '铅笔', num: 5 },
        ]
      },
      computed: {
        total() {
          let t = 0
          this.list.forEach(item => {
            t += item.num
          });
          return t
        },



      }
    })
  </script>
</body>

</html>

结果:

image.png

2.7.2 通过方法实现


<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    table {
      border: 1px solid #000;
      text-align: center;
      width: 300px;
    }

    th,
    td {
      border: 1px solid #000;
    }

    h3 {
      position: relative;
    }

    span {
      position: absolute;
      left: 145px;
      top: -4px;
      width: 16px;
      height: 16px;
      color: white;
      font-size: 12px;
      text-align: center;
      border-radius: 50%;
      background-color: #e63f32;
    }
  </style>
</head>

<body>

  <div id="app">

    <!-- 注意:调用computed属性无需加小括号,但是调用methods方法需要加小括号 -->
    <!-- 例如: -->
    <!-- <h3>小黑的礼物清单🛒<span>{{total}}</span></h3> -->
    <h3>小黑的礼物清单🛒<span>{{test()}}</span></h3>
    <table>
      <tr>
        <th>名字</th>
        <th>数量</th>
      </tr>
      <tr v-for="item in list" :key="item.id">
        <td>{{item.name}}</td>
        <td>{{item.num}}</td>
      </tr>
    </table>

    <!-- 注意:调用computed属性无需加小括号,但是调用methods方法需要加小括号 -->
    <!-- 例如: -->
    <p>礼物总数:{{test()}} 个</p>
    <!-- <p>礼物总数:{{total}} 个</p> -->
  </div>
  <!-- Vue 2.x 版本 -->
  <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> -->

  <!-- Vue 3.x 版本 -->
  <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        // 现有的数据
        list: [
          { id: 1, name: '篮球', num: 3 },
          { id: 2, name: '玩具', num: 2 },
          { id: 3, name: '铅笔', num: 5 },
        ]
      },
      methods: {
        test() {
          return this.list.reduce((total, curr) => total + curr.num, 0)
        }
      },
      computed: {
        total() {
          console.log('计算属性方法执行了')
          return this.list.reduce((total, curr) => total + curr.num, 0)
        },



      }
    })
  </script>
</body>

</html>

结果:

image.png

2.7.3 计算属性的完整写法

<!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">
    <span>姓:</span><input type="text" v-model="firstName"><br>
    <span>名:</span><input type="text" v-model="lastName"><br>
    <!-- <span>姓名:</span><input type="text" value="fullName"><br> -->
    <!-- 也可使用v-model,双向绑定(但是计算属性不能改变)-->
    <span>姓名:</span><input type="text" v-model="fullName"><br>
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        firstName: 'Bob',
        lastName: 'Alex',
      },
      computed: {
        fullName: {
          get() {
            return this.firstName + ' ' + this.lastName
          },
          set(val) {
            // 直接修改计算属性的结果,set就会执行,并且形参表示修改后的结果
            let arr = val.split(' ')
            // 即可实现fullname的值变动,姓称和名成也同时修改
            this.firstName = arr[0]
            this.lastName = arr[1]
          }
        }
      }

    })
  </script>
</body>

</html>

结果:

image.png

2.8 watch监听器

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-size: 18px;
    }

    #app {
      padding: 10px 20px;
    }

    .query {
      margin: 10px 0;
    }

    .box {
      display: flex;
    }

    textarea {
      width: 300px;
      height: 160px;
      font-size: 18px;
      border: 1px solid #dedede;
      outline: none;
      resize: none;
      padding: 10px;
    }

    textarea:hover {
      border: 1px solid #1589f5;
    }

    .transbox {
      width: 300px;
      height: 160px;
      background-color: #f0f0f0;
      padding: 10px;
      border: none;
    }

    .tip-box {
      width: 300px;
      height: 25px;
      line-height: 25px;
      display: flex;
    }

    .tip-box span {
      flex: 1;
      text-align: center;
    }

    .query span {
      font-size: 18px;
    }

    .input-wrap {
      position: relative;
    }

    .input-wrap span {
      position: absolute;
      right: 15px;
      bottom: 15px;
      font-size: 12px;
    }

    .input-wrap i {
      font-size: 20px;
      font-style: normal;
    }

    .query {
      display: inline-block;
      margin: 10px;
    }

    select {
      width: 100px;
    }
  </style>
</head>

<body>
  <div id="app">
    <!-- 条件选择框 -->
    <div class="query">
      <span>源语言:</span>
      <select>
        <option value="en">英语</option>
        <option value="zh">简体中文</option>
        <option value="jp">日语</option>
        <option value="fra">法语</option>
      </select>
    </div>
    <div class="query">
      <span>目标语言:</span>
      <select v-model="obj.to">
        <option value="zh">简体中文</option>
        <option value="en">英语</option>
        <option value="jp">日语</option>
        <option value="fra">法语</option>
      </select>
    </div>

    <!-- 翻译框 -->
    <div class="box">
      <div class="input-wrap">
        <textarea v-model="obj.q"></textarea>
        <span><i>⌨️</i>文档翻译</span>
      </div>
      <div class="output-wrap">

      </div>
    </div>
  </div>
  <script src="./vue.js"></script>
  <!-- <script src="./js/axios.js"></script> -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script>
    // 接口地址:http://www.itcbc.com:3006/api/translate
    // 请求方式:get
    // 请求参数:
    // (1)q:   需要被翻译的文本(必传)
    // (2)from:源语言(可选),默认-英语
    // (3)to:  需要被翻译成的语言(可选)默认值-中文
    // -----------------------------------------------

    const app = new Vue({
      el: '#app',
      data: {
        words: '',
        obj: {
          q: 'good',   //输入框双向绑定
          from: 'en', //源语言
          to: 'zh'    //翻译语言
        },
        result: '' //翻译结果
      },
      watch: {
        obj: {
          async handler(val) {
            // console.log(val);
            // 翻译操作
            const { data: res } = await axios({
              url: 'http://www.itcbc.com:3006/api/translate',
              // 将val作为参数传递
              params: val
            })
            console.log(res)
            this.result = res.data.trans_result.dst
          },
          deep: true, //深度监听
          immediate: true //初始化时执行handler
        }
      }
    })
  </script>
</body>

</html>