Vue _ 舒适版 01

news/2024/7/10 1:59:57 标签: 前端, Vue

目录

Vue%20%E6%A1%86%E6%9E%B6-toc" style="margin-left:0px;">一、认识 Vue 框架

Vue%20%E7%9A%84%E5%BC%80%E5%A7%8B-toc" style="margin-left:0px;">二、Vue 的开始

Vue%20%E7%9A%84%E6%96%B9%E6%B3%95%E4%B9%A6%E5%86%99-toc" style="margin-left:0px;">三、Vue 的方法书写

Vue%20%E7%9A%84%E5%86%85%E7%BD%AE%E6%8C%87%E4%BB%A4-toc" style="margin-left:0px;">四、Vue 的内置指令

1. 渲染

Vue%20%E7%9A%84%E7%B1%BB%E5%90%8D%E6%B8%B2%E6%9F%93-toc" style="margin-left:80px;">( 1 ) Vue 的类名渲染

Vue%20%E7%9A%84%E6%A0%B7%E5%BC%8F%E6%B8%B2%E6%9F%93-toc" style="margin-left:80px;">( 2 ) Vue 的样式渲染

2. 绑定属性

3. 条件渲染

4. 循环渲染

Vue%20%E4%B8%AD%20key%20%E7%9A%84%20%E9%97%AE%E9%A2%98%20%3A-toc" style="margin-left:80px;">Vue 中 key 的 问题 :

5. 绑定事件

6. 双向数据绑定

Vue%20%E6%A1%88%E4%BE%8B%20-%20%E5%8A%A8%E6%80%81%E8%A1%A8%E6%A0%BC%20%3A-toc" style="margin-left:0px;">Vue 案例 - 动态表格 :


跳转链接  =>  Vue _ 舒适版 02

跳转链接  =>  Vue _ 舒适版 03

跳转链接  =>  Vue _ 舒适版 04


Vue%20%E6%A1%86%E6%9E%B6">一、认识 Vue 框架

Vue 是一个渐进式框架
+ 因为框架一整套完整的生态系统
  => 把所有功能分开
  => 可以单独使用某一个功能
  => 随着你的需求逐渐增加内容
+ 特点: 学习成本低
+ 例子:
  => 有一个文件叫做 vue.js, 包含基础语法部分
  => 有一个文件叫做 vue-router.js, vue 里面扩展的部分
  => 根据你的需求, 引入不同的文件来实现

开始 Vue
+ 就是一个第三方
+ 使用套路, 下载, 引入, 使用
+ 使用 npm 下载 ( 指令 $  npm i vue )
  => 下载以后, 有一个叫做 vue.js 和 vue.min.js 的文件
  => 引入以后就可以直接使用了
  => 在学习阶段, 推荐使用 vue.js

 

如何使用 Vue
+ Vue 的开始, 就是引入文件以后
+ 会提供给我们一个叫做 Vue构造函数
+ 当你 创建实例 的时候, 表示你开始使用 Vue

数据驱动视图
+ 框架帮我们把渲染页面的事情做完了
+ 我们只要准备好数据, 框架会帮我们把数据渲染到页面上
+ 对于开发人员来说, 只要专注于数据的操作即可


Vue%20%E7%9A%84%E5%BC%80%E5%A7%8B">二、Vue 的开始

<div id="app" class="box">
    <!-- 这里可以识别 Vue 的语法 -->
    <!--
      插值表达式
        + 向某一个部分插入一个值
        + 语法: {{ 简单的表达式 }}
        + 在 Vue 的根节点内, 可以直接使用 data 中的成员名称
    -->
    <p>
      <!-- 在 Vue 渲染页面的时候, 会捕获到 data 配置项中的 message 成员 -->
      <!-- 把 message 成员的值, 完整替换 {{ message }} -->
      {{ message }}
    </p>
    <p>
      {{ count }}
    </p>
  </div>
  <!-- 这里没有办法识别 Vue 的语法 -->
  {{ message }}

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的开始
      1. 引入一个 js 文件
        => vue.js
      2. 通过 Vue 提供的构造函数来创建实例
        => new Vue({})
        => 对象数据类型, 就是对本次实例的所有配置项
    */
    // 2. 创建 Vue 实例
    const app = new Vue({
      // el 属性, 表示关联一个页面上的元素, 需要填写的值是一个选择器
      // 因为涉及到帮你渲染页面这个行为, 那么总要有一个标签来接受渲染的所有内容
      // 我们管 Vue 实例关联的元素叫做 Vue 的根节点
      // 你所有和 Vue 相关的语法, 以及渲染操作, 只有在这个元素内好使
      el: '#app',
      // data 属性, 表示你需要使用的数据
      // 你所有书写在 data 内的成员, 都可以在 Vue 的根节点内直接使用 Vue 语法进行渲染
      // 注意: 当你的 data 内的数据改变得时候, 只要你的数据发生变化, Vue 会实时进行页面的从新渲染
      data: {
        message: 'hello Vue',
        count: 1,
        arr: [100, 200, 300, 400, 500]
      }
    })
    console.log(app)

    /*
      vue-tools 工具
        + 是一个浏览器插件
        + 帮助我们快速学习 Vue 的工具
        + 帮我们查看一些内容
    */
  </script>

Vue%20%E7%9A%84%E6%96%B9%E6%B3%95%E4%B9%A6%E5%86%99">三、Vue 的方法书写

<div id="app">
    <!--
      插值表达式可以书写一个简单的表达式
        + 一句话都可以
    -->
    <p> {{ message }} </p>
    <p> {{ reverseStr() }} </p>
    <p>
      {{ age >= 18 ? '成年' : '未成年' }}
    </p>
    <!-- 需求: 在这里出现一个 30 ~ 60 之间的随机数字 -->
    <p>
      {{ randomNum(30, 60) }}
    </p>
    <!-- 需求: 在这里出现一个 50 ~ 80 之间的随机数字 -->
    <p>
      {{ randomNum(50, 80) }}
    </p>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的方法书写
        + 在 Vue 内, 有的时候需要用到一些函数
        + 我们可以在 data 内书写一个属性, 值是一个函数
          => Vue 不推荐这样书写
          => 因为当你把 函数 和 数据 混合在一起的时候, 不利于后期维护
          => Vue 单独给你开辟了一个配置项, 叫做 methods, 专门用来存储方法的
        + 注意:
          => 在 Vue 的所有函数内
          => this 都是指向当前 Vue 实例
    */
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello vue',
        age: 18
      },
      // methods 配置项就是专门用来书写方法的配置项
      methods: {
        randomNum: function (a, b) {
          // 这里的 this 就是 Vue 实例
          // 你想操作的所有数据, 都可以书写 this.xxx 来操作
          // 例如 你需要操作 data 内的 message 数据, 就书写 this.message

          return Math.floor(Math.random() * (b - a + 1) + a)
        },
        reverseStr () {
          // 专门来操作 data 中的 message 数据的方法
          return this.message.split('').reverse().join('')
        }
      }
    })
    console.log(app)
  </script>

Vue%20%E7%9A%84%E5%86%85%E7%BD%AE%E6%8C%87%E4%BB%A4">四、Vue 的内置指令

1. 渲染

<div id="app">
    <p> {{ message }} </p>
    <hr>
    <!-- Vue 在渲染页面的时候, 会用 innerText 的形式, 把 data 中的 s1 数据的值填充在这个 p 标签内 -->
    <p v-text="s1"></p>
    <p v-text="s2"></p>
    <hr>
    <!-- Vue 在渲染页面的时候, 会用 innerHTML 的形式, 把 data 中的 s1 数据的值填充在这个 p 标签内 -->
    <p v-html="s1"></p>
    <p v-html="s2"></p>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的渲染指令
        + 指令(私人): Vue 自己创建的一些属于元素身上的自定义属性
          => Vue 在渲染页面的时候, 就会捕获这些他自己设置的指令
          => 通过你用不同的指令来进行不同的操作
          => 所有指令的书写形式, 都是以一个属性的形式书写在标签身上

      1. v-text
        + 语法: v-text="data中的数据"
        + 意义: 等价于原生 JS 中的 innerText
          => 把 data 中这一条数据当做文本渲染在标签内

      2. v-html
        + 语法: v-html="data中的数据"
        + 意义: 等价于原生 JS 中的 innerHTML
          => 把 data 中的这一条数据当做超文本渲染在标签内
    */
    new Vue({
      el: '#app',
      data: {
        message: 'hello vue',
        s1: '我是一个数据',
        s2: '<h1>我也是一个数据</h1>'
      }
    })
  </script>

Vue%20%E7%9A%84%E7%B1%BB%E5%90%8D%E6%B8%B2%E6%9F%93">( 1 ) Vue 的类名渲染

<div id="app">
    <p hello="world"></p>
    <!--
      类名有一定的特殊性
        + 可能有多种值
        + box box2 box3
        + 可以被当做单纯的字符串看待
        + 也可以其中某一个类名动态的
    -->
    <p class="iconfont icon-play active"></p>
    <hr>
    <!--
      1. 单独渲染一个类名(常用)
        + 就是直接使用 v-bind 指令去绑定属性
      解释: 这个 p 元素的 class 的值, 就使用 s1 这个数据的值
    -->
    <p :class="s1"></p>
    <hr>
    <!--
      2. 对象形式渲染多个类名
        + 使用 v-bind 的指令给 class 绑定一个对象数据类型
        + 注意:
          => 对象的 key 就是你要绑定的类名
          => 对象的 值 需要使用一个布尔值来决定这个类名有或者没有
      解释:
        + 把 { active: true,  box: true, container: false } 对象绑定给了 p 标签的 class 属性
          => 根据对象中的数据
          => active 值是 true, 表示给 p 标签添加 active 类名
          => box 值是 true, 表示给 p 标签添加 box 类名
          => container 值是 false, 表示不给 p 添加 conatiner 类名
    -->
    <p :class="obj"></p>
    <!--
      另一种书写方式(常用)
        + 不在 data 中准备对象了, 而是直接把对象书写在标签身上
        + 在 data 内只是使用 某一个变量 来控制其中的某一个类名
      解释: 你在使用这个对象的时候, iconfont 和 icon-play 类名是始终存在的
        + 而 active 类名, 是取决于 data 中 boo 数据是 true 还是 false
    -->
    <p :class="{ iconfont: true, 'icon-play': true, active: boo }"></p>
    <hr>
    <!--
      3. 以数组的形式绑定多个类名
        + 给 class 属性直接赋值为一个数组
        + 数组内以字符串的形式书写一个一个的类名, 每一个类名都会被直接绑定上
      解释:
        + 把 [ 'box', 'box2', 'box3' ] 通过 v-bind 帮顶给 p 标签添加
        + 数组内的每一个值都是 p 标签的一个类名
    -->
    <p :class="classes"></p>
    <!--
      及其少见的形式
        + 数组内嵌套多个变量
      解释:
        + 把 [ s1, s2, s3 ] 给到了 p 标签的 class 属性
        + 因为数组内写的是三个变量
        + 会从 data 中找到 s1 s2 s3 三个变量的值, 当做类名进行赋值
    -->
    <p :class="[ s1, s2, s3 ]"></p>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的类名渲染
    */
    new Vue({
      el: '#app',
      data: {
        s1: 'active',
        s2: 'box',
        s3: 'box2',
        obj: {
          active: true,
          box: true,
          container: false
        },
        boo: true,
        classes: [ 'box', 'box2', 'box3' ],
      }
    })
  </script>

Vue%20%E7%9A%84%E6%A0%B7%E5%BC%8F%E6%B8%B2%E6%9F%93">( 2 ) Vue 的样式渲染

<div id="app">
    <p hello="world"></p>
    <!--
      style 也有一些特殊性
        1. 有可能有多个值
        2. 每一个单独的值, 都包含 样式名 和 样式值
        + color: red; font-size: 30px
    -->
    <p style="color: red; font-size: 30px;"></p>
    <hr>
    <!--
      1. 直接以对象的形式进行绑定
        + 我们在 data 内以对象的形式书写一个样式集
        + 直接把这个对象绑定在元素的 style 属性上

      解释:
        + 把 { color: red, font-size: 30px } 对象直接绑定给 p 标签的 style 属性
        + 会把对象中的两个样式直接加上
    -->
    <p :style="stylies">我是一段文本</p>
    <hr>
    <!--
      2. 以数组的形式进行绑定
        + 可以在数组内书写多个对象
        + 会把每一个对象的样式都绑定上

      解释:
        + 把 数组 给到了 p 标签的 style 属性身上
        + 因为数组内书写的是两个变量, 每一个变量都表示一个对象
        + 会把 两个 对象内的数据都渲染上
    -->
    <p :style="[ stylies, stylies2 ]">我又是一段文本</p>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的样式渲染
    */
    new Vue({
      el: '#app',
      data: {
        stylies: {
          color: 'red',
          'font-size': '30px'
        },
        stylies2: {
          'font-weight': 700,
          'background-color': 'skyblue'
        }
      }
    })
  </script>

2. 绑定属性

3. 条件渲染

<div id="app">
    <p> {{ message }} </p>
    <hr>
    <!--
      当 age >= 18 为 true 的时候, 这个 p 标签有
      当 age <= 18 为 false 的时候, 这个 p 标签没有
    -->
    <!-- <p class="box1" v-if="age >= 18"> 成年人 </p> -->
    <hr>
    <!-- 下面两个标签只会渲染一个 -->
    <!-- <p class="box1" v-if="age >= 18"> 成年人 </p>
    <p class="box2" v-else> 未成年人 </p> -->
    <hr>
<!--
    <p class="box1" v-if="age >= 18"> 大学 </p>
    <p class="box2" v-else-if="age >= 15"> 高中 </p>
    <p class="box3" v-else-if="age >= 12"> 初中 </p>
    <p class="box4" v-else> 小学 </p> -->
    <hr>
    <p v-if="age >= 18">我用的是 v-if 指令</p>
    <p v-show="age >= 18">我用的是 v-show 指令</p>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的内置指令 - 条件渲染
        + if else 语句

      1. if 语句
        + 语法: v-if="条件"
        + 意义: 如果条件为 true, 那么这个标签结构渲染出来
          => 如果条件为 false, 那么这个标签结构不渲染

      2. if else 语句
        + 语法:
          v-if="条件" 书写在一个标签身上
          v-else 书写在另一个标签身上
        + 意义:
          => 根据条件的 true 或者是 false
          => 渲染两个标签中的一个

      3. if ... else if 语句
        + 语法:
          v-if="条件" 书写在一个标签身上
          v-else-if="第二个条件" 书写在一个标签身上
          v-else-if="第三个条件" 书写在一个标签身上
          v-else-if="第四个条件" 书写在一个标签身上
          ...
        + 意义:
          => 根据条件来决定渲染哪一个标签
        + 注意:
          => 若干个标签只会渲染一个

      Vue 的内置指令 - 条件渲染
        + show
      1. v-show
        + 语法: v-show="条件"
        + 意义: 根据条件决定该标签显示不显示
          => 不管条件是 true 还是 false, 该标签都会渲染出来
          => 当条件为 true 的时候, 标签是 display: block;
          => 当条件为 false 的时候, 标签是 display: none;
    */
    new Vue({
      el: '#app',
      data: {
        message: 'hello Vue',
        age: 18
      }
    })
  </script>


4. 循环渲染

<div id="app">
    <p>{{ message }}</p>
    <hr>
    <!--
      会根据 arr 这个数组内有多少个成员, 渲染多少个 li 标签
    -->
    <!-- <ul>
      <li v-for="(item, index) in arr">
        {{ item }} ----- {{ index }}
      </li>
    </ul> -->

    <!--
      会根据 arr 这个数组内有多少个成员, 渲染多少个 li 标签
    -->
    <!-- <ul>
      <li v-for="item in arr">
        {{ item }}
      </li>
    </ul> -->
    <hr>
    <!-- <ul>
      <li v-for="(item, index) in str">
        {{ item }} --- {{ index }}
      </li>
    </ul> -->
    <hr>
    <!-- <ul>
      <li v-for="(item, index) in num">
        {{ item }} --- {{ index }}
      </li>
    </ul> -->
    <hr>
    <ul>
      <li v-for="(val, key, index) in obj">
        {{ val }} --- 对象内的每一个值 <br>
        {{ key }} --- 对象内的每一个键 <br>
        {{ index }} --- Vue 对每一个数据进行了一个编号 <br>
        -----------------------------------
      </li>
    </ul>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的内置指令 - 循环渲染
        + 就是 Vue 把 for 循环这个事情制作了一个指令
        + 在 Vue 里面叫做 万物皆可循环
,
      1. 遍历数组
        + 语法: v-for=" (item, index) in 数组 "
        + 意义: 会根据数组有多少项, 把这个标签渲染多少个个
          => 随着循环, item 分别是数组内的每一项数据
          => 随着循环, index 分别是数组内的每一个索引

      2. 遍历字符串
        + 语法: v-for=" (item, index) in 字符串 "
        + 意义: 会根据字符串有多少个字符, 把这个标签渲染多少个
          => 随着循环, item 分别是数组内的每一个字符
          => 随着循环, index 分别是数组内的每一个索引

      3. 遍历数字
        + 语法: v-for=" (item, index) in 数字 "
        + 意义: 会从 1 开始逐次 +1 向你指定的数字进行遍历
          => 随着循环, item 就是从 1 开始的每一个数字
          => 随着循环, index 分别是每一个数字所表示的索引

      4. 遍历对象
        + 语法: v-for=" (val, key, index) in 对象 "
        + 意义: 会根据对象内有多少个成员, 把这个标签循环渲染多少回
          => val 就是对象内每一个 值
          => key 就是对象内每一个 键
          => index 依旧是索引, 就是把每一个数据给了一个编号
    */
    new Vue({
      el: '#app',
      data: {
        message: 'hello Vue',
        arr: [ 100, 200, 300, 400, 500 ],
        str: 'hello world',
        num: 5,
        obj: {
          name: 'Jack',
          age: 18,
          gender: '男'
        }
      }
    })
  </script>

Vue%20%E4%B8%AD%20key%20%E7%9A%84%20%E9%97%AE%E9%A2%98%20%3A">Vue 中 key 的 问题 :

<!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>Document</title>
  <style>
    table {
      width: 550px;
      margin: 30px auto;
      text-align: center;
    }
  </style>
</head>
<body>
  <div id="app">
    <table border="1" cellspacing="0">
      <thead>
        <tr>
          <th>选中</th>
          <th>ID</th>
          <th>姓名</th>
          <th>性别</th>
          <th>年龄</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!--
          只要根据数组把 tr 标签循环渲染就可以了
            + 根据 users 内有多少个 对象, 渲染多少个 tr
            + 用什么指令: v-for
            + 指令写在哪一个标签身上: tr
        -->
        <!--
          解决 diff 算法出现的问题
            + 以 动态绑定 属性的方式, 绑定一个 key
            + 尽量使用数据唯一值, 会把每一个元素标签锁定上数据唯一值
        -->
        <tr v-for="(item, index) in users" :key="item.id">
          <!--
            item 就是 users 内的每一个对象
            需要把对象内的数据渲染在指定标签身上
          -->
          <td>
            <input type="checkbox" :checked="item.is_select">
          </td>
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.gender }}</td>
          <td>{{ item.age }}</td>
          <td>
            <button>编辑</button>
            <button>删除</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 中 key 的问题
    */
    // 准备一条数据
    const arr = [
      { id: 1, name: 'Jack', age: 18, is_select: true, gender: '男' },
      { id: 2, name: 'Rose', age: 20, is_select: false, gender: '女' },
      { id: 3, name: 'Tom', age: 22, is_select: true, gender: '男' }
    ]

    const app = new Vue({
      el: '#app',
      data: {
        users: arr
      }
    })
    /*
      key 的作用

      问题:
        + 当我的数组渲染好以后
        + 我做了一些操作, 然后发现修改的内容和我预想的不一样
        + 将来我渲染的表格某些操作不能做了

      原因:
        + 因为 Vue 在渲染页面的时候
        + 每一次修改, 其实都是从新渲染页面
        + 在渲染的时候, 有一个自己的 diff 算法
          => 为了节约性能, 会按照最少的改变去操作

      解决:
        + 给标签身上加上唯一值
        + 在 Vue 里面提供了一个 key 的属性来作为唯一值绑定
        + 有了唯一值, 就不会按照最小的变化, 而是按照不变的来操作
        + 注意: key 绝对不能使用数组的索引, 必须要使用数据唯一值, 基本上都是 id

      结论:
        + 只要有 v-for 必写 :key
    */
  </script>
</body>
</html>

5. 绑定事件

<div id="app">
    <p>{{ message }}</p>
    <hr>
    <!-- 我想给这个按钮绑定一个点击事件 -->
    <!--
      通过 v-on 指令给 button 元素绑定了一个 click 事件
        + 使用的 事件处理函数
        + 是 methods 中的 clickHandler 函数
      当你点击 button 按钮的时候
        + 就会触发 methods 中的 clickHanlder 函数
    -->
    <button v-on:click="clickHandler">按钮</button>
    <hr>
    <!--
      简单的小案例 : 计数器
    -->
    <!-- 需要一个点击事件 -->
    <button v-on:click="subHandler">-</button>
    <!-- span 内的数据, 必须要使用一个 data 中的成员 -->
    <!-- 只有这样才能保证数据变化的时候, 内容跟随变化 -->
    <span>{{ count }}</span>
    <!-- 需要一个点击事件 -->
    <button v-on:click="addHandler">+</button>
    <br>
    <!-- 把 v-on: 换成 @ -->
    <button @click="subHandler">-</button>
    <span>{{ count }}</span>
    <button @click="addHandler">+</button>
    <hr>
    <!--
      在绑定一个键盘事件的基础上, 做了一个额外的限定, 只有键盘按下, 并且按下的是 回车键 的时候
        + 才会触发 事件处理函数
    -->
    <input type="text" @keydown.enter="downHandler">
    <br>
    <!--
      esc 内应该做一个什么样的操作合理

      如何实现重置
        + 把这个 input 的 value 设置为 空字符串
      如何把这个 input 的 value 设置为 空字符串
        + ( 一定要往数据驱动视图这方面去考虑解决方案 )
    -->
    <!-- 只要 data 中的 str 变化, 这个 input 的 value 就变化了 -->
    <input type="text" @keydown.esc="escHandler" :value="str">
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的 内置指令 之 绑定事件

      1. v-on
        + 语法: v-on:事件类型="需要用到的事件处理函数"
        + 注意: 只要是在 Vue 内, 所有的 this 都是 当前实例
          => 既然是 Vue 的实例
          => 那么可以直接在事件处理函数内进行 data 中数据的操作
        + 简写形式
          => v-on: 可以简写为 @
          => 你书写 @click 就等价于 v-on:click

      2. 事件的绑定的 操作符
        + Vue 提供了对于键盘事件的 操作符
        + 可以直接锁定某些按键
          => 直接连接在事件类型后面书写
          => .enter 的连接符, 表示按下 回车键
    */
    new Vue({
      el: '#app',
      data: {
        message: 'hello Vue',
        count: 1,
        str: 'hello world'
      },
      methods: {
        clickHandler () {
          console.log('我是一个事件处理函数')
          console.log(this)
        },
        subHandler () {
          // 减号点击的事件
          // 需要操作 data 中的 count 进行数量的减少
          // 因为是 methods 内的函数, 所以 this 一定是指向当前 Vue 实例
          // 我们直接通过 this.count 来操作
          this.count--
        },
        addHandler () {
          // 加号点击事件
          this.count++
        },
        downHandler () {
          console.log('键盘按下')
        },
        escHandler () {
          console.log('esc 按下了')
          // 当我把 str 设置为 空 的时候
          // 会瞬间影响页面变化, input 就变成了 空内容
          this.str = ''
        }
      }
    })
  </script>

6. 双向数据绑定

<div id="app">
    <!--
      v-bind 是一个 单向绑定
        + 只是把 data 中的数据, 渲染在页面上
    -->
    <!--
      需求:
        + 需要把用户填写的内容放在 data 中的 username 属性上
        + 随着用户输入, 随时修改
    -->
    <!-- <input type="text" :value="username" @input="handler"> -->
    <input type="text" v-model="username">

    <!-- 使用双向数据绑定 -->
    <!--
      解释:
        把 data 内的 password 属性的值, 直接赋值给这个 input 的 value 属性
        当 这个 input 的 value 属性修改的时候, 会直接修改 data 中 password 属性的值
    -->
    <input type="text" v-model="password">

    <button @click="login">登录</button>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 的内置指令 - 双向数据绑定
        + Vue 提供给我们了一个 v-model 的指令
        + 这个指令包含了两个内容
          1. v-bind:value
          2. v-on:input=function () { 设置 data 内的值 }
    */
    new Vue({
      el: '#app',
      data: {
        username: '',
        password: ''
      },
      methods: {
        handler (e) {
          // 1. 拿到用户输入的内容
          // 获取元素, 获取 value
          // 通过事件对象, 拿到 value 值
          console.log(e.target.value) // 用户输入的内容
          // 2. 给 data 中的 username 进行赋值
          this.username = e.target.value
        },
        login () {
          // 进行提交操作
          console.log('我要发送一个 ajax 请求给到后端')
          console.log('携带的参数有两个, ', this.username , this.password)
        }
      }
    })
  </script>

Vue%20%E6%A1%88%E4%BE%8B%20-%20%E5%8A%A8%E6%80%81%E8%A1%A8%E6%A0%BC%20%3A">Vue 案例 - 动态表格 :

<div id="app">
    <form>
      <label>
        姓名: <input type="text" v-model="info.name">
      </label>
      <label>
        性别: <input type="text" v-model="info.gender">
      </label>
      <label>
        年龄: <input type="text" v-model="info.age">
      </label>
      <button type="button" @click="addHandler">添加</button>
    </form>

    <table border="1" cellspacing="0">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>性别</th>
          <th>年龄</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in users" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.gender }}</td>
          <td>{{ item.age }}</td>
          <td>
            <button @click="showEdit(item.id)">编辑</button>
            <button @click="delHandler(item.id)">删除</button>
          </td>
        </tr>
      </tbody>
    </table>

    <div :class="{ dialog: true, active: isShow }">
      <!-- 点击关闭按钮取消编辑 -->
      <span @click="cancelEdit">X</span>
      <form>
        <label>
          id: <input disabled type="text" v-model="update.id">
        </label>
        <label>
          姓名: <input type="text" v-model="update.name">
        </label>
        <label>
          性别: <input type="text" v-model="update.gender">
        </label>
        <label>
          年龄: <input type="text" v-model="update.age">
        </label>
        <button type="button" @click="edit">确认编辑</button>
      </form>
    </div>
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 案例 - 动态表格
    */
    const users = [
      { id: 1, name: 'Jack', age: 18, gender: '男' },
      { id: 2, name: 'Rose', age: 20, gender: '女' },
      { id: 3, name: 'Tom', age: 22, gender: '男' }
    ]

    new Vue({
      el: '#app',
      data: {
        // 准备渲染页面的数据
        users,
        // 准备一个数据是和 添加 文本框进行双向数据绑定
        info: {},
        // 准备一个数据是和 编辑 文本框进行双向数据绑定
        update: {},
        // 准备一个数据, 表示 dialog 对话框显示和隐藏
        isShow: false
      },
      methods: {
        delHandler (id) {
          this.users = this.users.filter(item => item.id !== id)
        },
        addHandler () {
          this.info.id = this.users[this.users.length - 1].id + 1
          this.users.push(this.info)
          this.info = {}
        },
        showEdit (id) {
          const result = this.users.find(item => item.id === id)
          this.update = { ...result }
          this.isShow = true
        },
        cancelEdit () {
          this.isShow = false
        },
        edit () {
          const result = this.users.find(item => item.id === this.update.id)
          result.name = this.update.name
          result.gender = this.update.gender
          result.age = this.update.age
          this.isShow = false
        }
      }
    })
  </script>

详解 :

<!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>Vue_案例-动态表格</title>
  <style>
    table {
      width: 550px;
      margin: 30px auto;
      text-align: center;
    }

    form {
      width: 500px;
      display: flex;
      flex-direction: column;
      margin: 0 auto;
    }

    .dialog {
      width: 500px;
      padding: 20px;
      background-color: #fff;
      border: 2px solid #ccc;
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
      height: 120px;
      display: none;
    }

    .dialog.active {
      display: block;
    }

    .dialog > span {
      position: absolute;
      right: 15px;
      top: 15px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div id="app">
    <form>
      <label>
        姓名: <input type="text" v-model="info.name">
      </label>
      <label>
        性别: <input type="text" v-model="info.gender">
      </label>
      <label>
        年龄: <input type="text" v-model="info.age">
      </label>
      <button type="button" @click="addHandler">添加</button>
    </form>

    <table border="1" cellspacing="0">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>性别</th>
          <th>年龄</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in users" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.gender }}</td>
          <td>{{ item.age }}</td>
          <td>
            <!--
              问题: 确认编辑, 还是进入编辑状态
             -->
            <button @click="showEdit(item.id)">编辑</button>

            <!-- 每一个 tr 内的 button 删除按钮都需要有一个点击事件 -->
            <!--
              当我删除的时候, 需要知道你要删除的这一条数据的 id
              在渲染页面的时候, 把 id 给渲染进去
            -->
            <button @click="delHandler(item.id)">删除</button>
          </td>
        </tr>
      </tbody>
    </table>

    <!--
      进入编辑状态, 就是让他显示出来
        + 怎么显示出来, 添加 active 类名
        + dialog 类名是始终存在的,
        + active 有时候有, 有时候没有
    -->
    <div :class="{ dialog: true, active: isShow }">
      <!-- 点击关闭按钮取消编辑 -->
      <span @click="cancelEdit">X</span>
      <form>
        <label>
          id: <input disabled type="text" v-model="update.id">
        </label>
        <label>
          姓名: <input type="text" v-model="update.name">
        </label>
        <label>
          性别: <input type="text" v-model="update.gender">
        </label>
        <label>
          年龄: <input type="text" v-model="update.age">
        </label>
        <button type="button" @click="edit">确认编辑</button>
      </form>
    </div>

    <!--
      <tr>
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.gender }}</td>
          <td>{{ item.age }}</td>
          <td>
            <button>编辑</button>
            <button @click="delHandler(1)">删除</button>
          </td>
        </tr>
        <tr>
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.gender }}</td>
          <td>{{ item.age }}</td>
          <td>
            <button>编辑</button>
            <button @click="delHandler(2)">删除</button>
          </td>
        </tr>
        <tr>
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.gender }}</td>
          <td>{{ item.age }}</td>
          <td>
            <button>编辑</button>
            <button @click="delHandler(3)">删除</button>
          </td>
        </tr>
    -->
  </div>

  <script src="./vue/vue.js"></script>
  <script>
    /*
      Vue 案例 - 动态表格
    */
    const users = [
      { id: 1, name: 'Jack', age: 18, gender: '男' },
      { id: 2, name: 'Rose', age: 20, gender: '女' },
      { id: 3, name: 'Tom', age: 22, gender: '男' }
    ]

    new Vue({
      el: '#app',
      data: {
        users,
        // 因为将来我需要向数组中添加一个对象数据类型
        // 直接使用对象来采集用户信息
        info: {},
        update: {},
        // 控制编辑框是否显示
        isShow: false
      },
      methods: {
        delHandler (id) {
          // 需要删除数组中的某一项
          // 注意: 你只要能把数组中对应的某一个删除掉, 页面会自动更新的
          // 问题: 删除数组中的哪一个 ?
          // console.log('删除点击事件')
          // console.log(`删除数组中 id 为 ${ id } 的数据`)

          // filter()
          // item 表示数组中的每一项
          // return 的形式书写筛选条件
          // 从 this.users 数组中, 筛选出所有 id 和 我接收到的 id 不一样的项
          // const result = this.users.filter(function (item) { return item.id !== id })
          // console.log(id, result)

          this.users = this.users.filter(item => item.id !== id)
        },
        addHandler () {
          // 直接使用 this.info 这个信息
          // console.log(this.info)

          // 1. 补一个 id 属性
          this.info.id = this.users[this.users.length - 1].id + 1

          // 2. 把我们的 info 插入到数组内
          this.users.push(this.info)

          // 3. 选做: 清空文本框
          this.info = {}
        },
        showEdit (id) {
          // 进入编辑状态
          // 把本条信息渲染在 dialog 内的表单内
          //   如何找到对应的信息
          //   我们有了 id, 只要从 this.users 内找到一个 id 一样
          const result = this.users.find(item => item.id === id)
          //   如何渲染
          //   dialog 的所有文本框 双向数据绑定 关联着 data 内的 update 对象
          //   只要我给 update 内的 name 赋值, 那么 name 文本框就有内容了
          this.update = { ...result }
          /*
            假设 result 就是 this.user[0]
              根据 vue 的规则, 只要 this.users[0] 的数据修改了, 页面就变
              result 和 this.users[0] 存储的是同一个对象的地址, result 改变, this.users[0] 就会变
              最好是把 result 复制一份给到 this.update
          */
          // 让 dialog 显示
          //   只要把 data 中的 isShow 设置为 true 就可以了
          this.isShow = true
        },
        cancelEdit () {
          // 直接关闭 dialog 对话框就可以了
          this.isShow = false
        },
        edit () {
          // 就是把 update 的内容在从新赋值回到 this.users 中的某一个内
          // console.log(this.update)

          // 1. 找到 this.users 内 id 一样的那一条数据
          let result = this.users.find(item => item.id === this.update.id)

          // 2. 进行替换操作
          result.name = this.update.name
          result.age = this.update.age
          result.gender = this.update.gender

          // 3. 关闭 dialog 对话框
          this.isShow = false
        }
      }
    })

    // const o1 = { name: 'Jack' }
    // const o2 = {
    //   ...o1
    // }
    // console.log(o1, o2)
    // o2.name = 'Rose'
    // console.log(o1, o2)

    // const arr = [ { id: 1, name: 'Jack' } ]

    // let result = arr[0]

    // let update = { id: 1, name: '张三' }

    // console.log(arr[0], result, update)

    // result = update
    // console.log(arr[0], result, update)
  </script>
</body>
</html>

跳转链接  =>  Vue _ 舒适版 02

跳转链接  =>  Vue _ 舒适版 03

跳转链接  =>  Vue _ 舒适版 04


http://www.niftyadmin.cn/n/1498248.html

相关文章

python函数编写_[零基础学python]传说中的函数编写条规

关于函数的事情&#xff0c;总是说不完的&#xff0c;下面就罗列一些编写函数的注意事项。特别声明&#xff0c;这些事项不是我总结的&#xff0c;我是从一本名字为《Learning Python》的书里面抄过来的&#xff0c;顺便写成了汉语&#xff0c;当然&#xff0c;是按照自己的视角…

今日总结 8/12

由于我前两天又有事情了&#xff0c;所以不在学校&#xff0c;今天才继续认真学习的。 1.今天首先看了看《明朝那些事儿》第三部的内容&#xff0c;然后将之前学的前端第7章内容自己动手复习了一遍&#xff0c;遇到两个问题&#xff0c;转载了别人的博客。另外是准备期末考试的…

列转字符串

DECLARE HuiQianHandlers NVARCHAR(100) SELECT * INTO #temp FROM dbo.Fun_TransferStrToTable(chk_valueStr) SELECT HuiQianHandlers( SELECT DISTINCT maxLeader, FROM dbo.TB_GroupLeader A JOIN #temp B ON a.GroupNameB.str2table AND LocationName上海 FOR XML PATH (…

扫雷游戏制作过程(C#描述):第四节、菜单操作

前言 这里给出教程原文地址。 该项目已经放在github上托管。 菜单操作 我们现在的程序单击菜单的时候不会有任何反应&#xff0c;这一节我们主要介绍菜单的相关代码&#xff0c;使得菜单能够正常使用。 现在我们希望在对应级别&#xff08;初级、中级、高级&#xff09;的按钮的…

python 语音转文字_《奇巧淫技》系列-Python实现 语音转文字??非也!!是文字转语音,DIY你想要的萝莉音!!!-Go语言中文社区...

本文章纯野生&#xff0c;无任何借鉴或抄袭他人文章。坚持原创前提一&#xff1a;有一篇你很喜欢的文章或者小说&#xff0c;阅读起来眼睛会很干涉之类的。 前提二&#xff1a;老人家看书不方便&#xff0c;将文字转换成语音&#xff0c;再进行播放。 前提三&#xff1a;想DIY你…

今日总结 8/13 8/14

昨天和今天都没有什么内容需要整理发博客的&#xff0c;这两天主要是复习准备开学考试的内容&#xff0c;要复习的东西比较多&#xff0c;另外晚上还上了辅导课&#xff0c;明天继续复习&#xff0c;另外抽空复习复习前端的知识以免忘记。

nsq topic和channel的区别

topic:一个可供订阅的话题。channel:属于topic的下一级&#xff0c;一个topic可以有多个channel。二者关系可以再参考下面两文章&#xff1a;http://www.cnblogs.com/forrestsun/p/3892710.htmlhttp://www.linuxeden.com/html/news/20140301/148960.html举个例子&#xff1a;to…

python的界面文字翻译_我用40行python代码写一个桌面翻译器,很nice

我们进行制作软件所需要的模板库&#xff0c;首先要进行引用。 另外大家要注意&#xff1a;不管你是为了Python就业还是兴趣爱好&#xff0c;记住&#xff1a;项目开发经验永远是核心&#xff0c;如果你没有2020最新python入门到高级实战视频教程&#xff0c;可以去小编的Pytho…