前端Vue

第一章 Vue认识和基础

安装Vue插件到浏览器。

Vue 简介

渐进式 JavaScript 框架

作者:尤雨溪 大学 科尔盖特大学

易学易用,性能出色,适用场景丰富的 Web 前端框架。

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。

渐进式框架

Vue 是一个框架,也是一个生态。其功能覆盖了大部分前端开发常见的需求。但 Web 世界是十分多样化的,不同的开发者在 Web 上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue 的设计非常注重灵活性和“可以被逐步集成”这个特点。根据你的需求场景,你可以用不同的方式使用 Vue:

  • 无需构建步骤,渐进式增强静态的 HTML

  • 在任何页面中作为 Web Components 嵌入

  • 单页应用 (SPA)

  • 全栈 / 服务端渲染 (SSR)

  • Jamstack / 静态站点生成 (SSG)

  • 开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

如果你是初学者,可能会觉得这些概念有些复杂。别担心!理解教程和指南的内容只需要具备基础的 HTML 和 JavaScript 知识。即使你不是这些方面的专家,也能够跟得上。

如果你是有经验的开发者,希望了解如何以最合适的方式在项目中引入 Vue,或者是对上述的这些概念感到好奇,我们在使用 Vue 的多种方式中讨论了有关它们的更多细节。

无论再怎么灵活,Vue 的核心知识在所有这些用例中都是通用的。即使你现在只是一个初学者,随着你的不断成长,到未来有能力实现更复杂的项目时,这一路上获得的知识依然会适用。如果你已经是一个老手,你可以根据实际场景来选择使用 Vue 的最佳方式,在各种场景下都可以保持同样的开发效率。这就是为什么我们将 Vue 称为“渐进式框架”:它是一个可以与你共同成长、适应你不同需求的框架。

Vue初次体验

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">{{username}}</div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        data: {
          username: '张三',
        },
      })
    </script>
  </body>
</html>

Vue指令语法

①插值表达式:

案例一:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">{{num1+num2}}</div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          num1: 6,
          num2: 8,
        },
      })
    </script>
  </body>
</html>

案例二:

对象插值表达式使用。

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <!-- {{num1+num2}} -->
      姓名:{{user.name}} <br />
      年龄:{{user.age}}<br />
      性别:{{user.sex}}
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          // num1: 6,
          // num2: 8,
          user: {
            name: '高启强',
            age: 48,
            sex: '男',
          },
        },
      })
    </script>
  </body>
</html>

v-text用法

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <p v-text="content"></p>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          content: '我是中国人',
        },
      })
    </script>
  </body>
</html>

③v-html用法

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <!-- 这样写就直接解析html标签属性 -->
      <div v-html="docontent"></div>
      <!-- 插值是原样输出  -->
      <div>{{docontent}}</div>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          docontent:
            '<h4 style="color: red; font-weight: bold;">欢迎大家来学习前端 vue技术</h4>',
        },
      })
    </script>
  </body>
</html>

  1. {{ }} 插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容!

  2. v-text 指令的缺点:会覆盖元素内部原有的内容!

  3. v-html 指令的作用:可以把带有标签的字符串,渲染成真正的 HTML 内容!

MVVM架构模型

属性绑定指令

属性绑定指令分单项属性绑定指令和双向数据绑定指令。

①单项数据绑定指令:v-bind

单项数据绑定指令一般开发用在非表单的标签。

案例一:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <!-- v-bind可以简写成英文的: -->
      <p :title="title">{{title}}</p>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          title: '学习Vue开发',
        },
      })
    </script>
  </body>
</html>

案例二:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <input type="text" :placeholder="tips" /><br />
      <hr />
      <img :src="photo" alt="" style="width: 680" />
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          photo:
            'https://syw.ctgu.edu.cn/__local/8/6E/DD/2F507A146723E194C2A7404B0EA_DEE66658_1D0B0.jpg',
          tips: '请您输入',
        },
      })
    </script>
  </body>
</html>

②事件绑定

v-on: 简写是 @

案例一

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      你看到的数字是{{num}}
      <hr />
      <button @click="add">点击一下加1</button>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          num: 0,
        },
        methods: {
          add() {
            this.num += 1
            console.log(this)
          },
        },
      })
    </script>
  </body>
</html>

案例二:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <h2>欢迎来到学习{{name}}技术</h2>
      <!-- <button v-on:click="showInfo">点我提示信息</button> -->
      <button @click="showInfo1">点我提示信息1(不传参)</button>
      <button @click="showInfo2($event,88)">点我提示信息2(传参)</button>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          name: 'vue',
        },
        methods: {
          showInfo1(event) {
            // console.log(event.target.innerText)
            // console.log(this) //此处的this是vm
            alert('同学你好!')
          },
          showInfo2(event, number) {
            console.log(event, number)
            // console.log(event.target.innerText)
            // console.log(this) //此处的this是vm
            alert('同学你好!!')
          },
        },
      })
    </script>
  </body>
</html>

按键修饰符

案例一:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      按键esc清空输入内容
      <input type="text" @keyup.esc="doesc" />
      <hr />
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          username: '',
        },
        methods: {
          doesc(e) {
            //e.targen.value = ''
            e.target.value = ''
            console.log('执行了esc按键操作')
          },
        },
      })
    </script>
  </body>
</html>

③双向绑定V-model

案例一:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      双向绑定
      <input type="text" v-model="username" />
      <input type="text" v-model="password" />
      <hr />
      单项绑定
      <input type="text" :value="username" />
      <input type="text" :value="password" />
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          username: '张三',
          password: '123456',
        },
      })
    </script>
  </body>
</html>

双向绑定在实际开发中用于表单元素。

V-if指令:

V-if是用来判断条件的,和java中的if语句是一样的。

案例:

<div id="root">
<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
    </div>
</body>
​
<script src="./js/vue.js"></script>
<script>
    const  vm = new Vue({
        el:'#root',
        data(){
            return{
                ok:true
            }
        }
              })

V-if 及V-else指令

相当于java中的if else 作用。

案例一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue使用</title>
</head>
<body>
​
<div id="root">
    <div>
    <template v-if="isValues">
        <h3>你今天生病了吗? 没有</h3>
        <hr>
      
    </template>
    <template v-else="isValues === false">
        <h3>你今天生病了吗?伤病了</h3>
        <hr>
       
    </template>
        <button @click="updateValue">点击事件</button>
    </div>
​
</div>
​
</body>
​
<script src="./js/vue.js"></script>
<script>
    const  vm = new Vue({
        el:'#root',
        data(){
            return{
               
                isValues:true,
            }
        },
        methods: {
            updateValue(){
                this.isValues = !this.isValues
            }
        },
      
​
    })
</script>
​
</html>

V-show指令:

另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:

  <h1 v-show="ok">Hello!</h1>
        <hr>
const  vm = new Vue({
        el:'#root',
        data(){
            return{
                ok:false,
               // isValues:true,
            }
        },

注意,v-show 不支持 <template> 元素,也不支持 v-else

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

V-for指令:

过滤器(了解学习Vue3中已经删除了。)

filter

过滤器(Filters)是 vue 为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式 和 v-bind 属性绑定。 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用。

案例一:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      先输出
      <p>{{massage}}</p>
      <hr />
      通过过滤器输出
      <p>{{massage | cap}}</p>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          massage: 'hello vue.js',
        },
        methods: {
            
        },
        //过滤器声明
        filters: {
          //过滤器是函数
          cap(vul) {
            //过滤器必须要求返回值。
            //console.log(vul)
            //return '啊啊啊啊啊啊'
            return vul.charAt(0).toUpperCase() + vul.slice(1)
          },
        },
      })
    </script>
  </body>
</html>

案例练习

实现效果:

案例代码如下:

<!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" />
    <link rel="stylesheet" href="./css/brandlist.css" />
    <link rel="stylesheet" href="./tjs/bootstrap.css" />
    <title>案例练习</title>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <div class="card">
        <div class="card-header">添加名称</div>
        <div class="card-body">
          <!-- 添加品牌的表单区域 -->
          <!-- form 表单元素有 submit 事件 -->
          <form @submit.prevent="add">
            <div class="form-row align-items-center">
              <div class="col-auto">
                <div class="input-group mb-2">
                  <div class="input-group-prepend">
                    <div class="input-group-text">用户名称</div>
                  </div>
                  <input
                    type="text"
                    class="form-control"
                    placeholder="请输入用户名称"
                    v-model.trim="brand"
                  />
                </div>
              </div>
              <div class="col-auto">
                <button type="submit" class="btn btn-primary mb-2">添加</button>
              </div>
            </div>
          </form>
        </div>
      </div>
​
      <table class="table table-bordered table-hover table-striped">
        <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">用户名称</th>
            <th scope="col">用户状态</th>
            <th scope="col">创建时间</th>
            <th scope="col">操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in list" :key="item.id">
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>
              <div class="custom-control custom-switch">
                <!-- 使用 v-model 实现双向数据绑定 -->
                <input
                  type="checkbox"
                  class="custom-control-input"
                  :id="'cb' + item.id"
                  v-model="item.status"
                />
                <!-- 使用 v-if 结合 v-else 实现按需渲染 -->
                <label
                  class="custom-control-label"
                  :for="'cb' + item.id"
                  v-if="item.status"
                  >健康</label
                >
                <label class="custom-control-label" :for="'cb' + item.id" v-else
                  >生病</label
                >
              </div>
            </td>
            <td>{{ item.time | dateFormat }}</td>
            <td>
              <a href="javascript:;" @click="remove(item.id)">删除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
​
    <!-- 导入Vue的js -->
    <script src="./tjs/dayjs.min.js"></script>
    <script src="../js/vue.js"></script>
    <script>
      Vue.filter('dateFormat', function (time) {
        // 1. 对 time 进行格式化处理,得到 YYYY-MM-DD HH:mm:ss
        // 2. 把 格式化的结果,return 出去
​
        // 直接调用 dayjs() 得到的是当前时间
        // dayjs(给定的日期时间) 得到指定的日期
        const dtStr = dayjs(time).format('YYYY-MM-DD HH:mm:ss')
        return dtStr
      })
​
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          brand: '',
          // nextId 是下一个,可用的 id
          nextId: 4,
          // 品牌的列表数据
          list: [
            { id: 1, name: '张三', status: true, time: new Date() },
            { id: 2, name: '李四', status: false, time: new Date() },
            { id: 3, name: '王五', status: true, time: new Date() },
          ],
        },
        methods: {
          // 点击链接,删除对应的品牌信息
          remove(id) {
            this.list = this.list.filter((item) => item.id !== id)
          },
          // 阻止表单的默认提交行为之后,触发 add 方法
          add() {
            // 如果判断到 brand 的值为空字符串,则 return 出去
            if (this.brand === '') return alert('必须用户名称')
​
            // 如果没有被 return 出去,应该执行添加的逻辑
            // 1. 先把要添加的品牌对象,整理出来
            const obj = {
              id: this.nextId,
              name: this.brand,
              status: true,
              time: new Date(),
            }
            // 2. 往 this.list 数组中 push 步骤 1 中得到的对象
            this.list.push(obj)
            // 3. 清空 this.brand;让 this.nextId 自增 +1
            this.brand = ''
            this.nextId++
          },
        },
      })
    </script>
  </body>
</html>

第二章Vue

axios 发送请求后端接口

axios 的基本使用

发送get请求:

axios({
  // 请求方式
  method: 'GET',
  // 请求的地址
  url: 'http://127.0.0.1:10086/api/get',//请求路径
  // URL 中的查询参数
  params: {
    id: 1
  }
}).then(function (result) {
  console.log(result)
})

发送POST请求:

document.querySelector('#btnPost').addEventListener('click', async function () {
  // 如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await!
  // await 只能用在被 async “修饰”的方法中
  const { data: res } = await axios({
    method: 'POST', 
    url: 'http://127.0.0.1:10086/api/post',
    data: {
      name: 'zs',
      age: 20
    }
  })
​
  console.log(res)
})

案例一:(请求我们之前开发的年级数据)记得在年级的controller加上跨域注解 @CrossOrigin

不加注解错误:

代码如下:

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
​
    <!-- 导入Vue的js -->
​
    <!-- <script src="js/vue.js"></script> -->
    <script src="js/axios.js"></script>
    <script>
      //调用axios返回结果是Promise 对象
      const result = axios({
        method: 'GET',
        url: 'http://127.0.0.1:10086/sms/gradeController/getGrades',
      })
      // console.log(res)
      result.then(function (list) {
        console.log(list)
      })
    </script>
  </body>
</html>

上述返回结果是:Promise 对象,如果需要后台数据,只需要在返回结果中加上list.data就可以实现。

Post 请求:

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/axios.js"></script>
​
</head>
<body>
<script>
    //调用axios返回结果是Promise 对象
    const result = axios({
        method: 'post',
        url: 'http://127.0.0.1:10086/sms/gradeController/saveOrUpdateGrade',
        data:{
            name:'大学三年级',
            manager:'赵六',
            email:'111@163.com',
            telephone:'17812345678',
            introducation:'这个班级学生学习JavaEE开发'
        }
    })
    // console.log(res)
    result.then(function (list) {
        console.log(list.data)
    })
</script>
</body>
</html>

Vue CLI(Vue 脚手架及工程化开发)

按照官网安装:

命令:在doc 命令下输入:

npm install -g @vue/cli
# OR
yarn global add @vue/cli

npm淘宝的代理:

npm config set registry https://registry.npm.taobao.org

建议用npm

安装好可以查看版本。

用dos 命令:

vue --version

如果想升级Vue CLI可以用下面命令:

npm update -g @vue/cli
​
# 或者
yarn global upgrade --latest @vue/cli

创建项目用下面命令:

vue create 项目名称

这里选择自定义选择。

先选择vue2.0版。后续我们用vue3.0

下面就可以启动项目了,我就在IDEA中启动了。

启动命令:

npm run serve

ctrl+c 

第二种创建Vue工程项目方式:

Vue ui

安装yarn 命令:

npm install -g yarn 

②查看版本:

yarn --version

③安装yarn的依赖:

yarn install

上述是需要的同学安装。

yarn 没有npm稳定建议使用npm命令。

assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下main.js 是项目的入口文件。整个项目的运行,要先执行 main.jsApp.vue 是项目的根组件。

①自己创建Vue需要在components 目录下。

②导入Vue import Ins from 具体目录

③注册到Vue根元素下面的components

components: {
  HelloWorld,
  Ins
}

④标签方式使用组件。

下面咱们就体验一下Vue组件。

新建一个mains.Vue如下:

<template>
<div id="app">
  <h3>内容输出</h3>
  <p>
    {{username}}
  </p>
</div>
</template>
​
<script>
export default {
​
  name: "Mains",
  /*data:{
    username:'张大大'
  }*/
  data(){
    return {
      username:'张大大'
    }
}
​
}
</script>
​
<style lang="less">
​
</style>

将main.js中的换成mains里内容,上述Mains.Vue就可以在页面渲染。

说明Vue初始化先执行main.js 油main.js 确定加载哪个Vue来做初始加载。

Vue初始就是Vue组件

组件中的data用data函数。

Vue事件(下篇)

  1. 绑定事件:<div v-on:事件名='函数名'></div>

  2. 实现方法:methods:{

    函数名(){
    
    
    }
    
    

    }

  1. 事件对象 event

    1. 无参数传递 :第一个参数就是event

    2. 有参数传递 :需要手动传递事件对象

      <div v-on:click='demo(1,2,$event)'></div>

  2. 事件修饰符.stop *.prevent *.capture.self.once.passive

    案例一(阻止事件冒泡)

    <template>
      <div>
        <h2>vue事件处理</h2>
        <!-- 1. 事件修饰符 -->
        <div @click="parent">
          我是小头爸爸
          <!--  阻止单击事件继续传播  -->
          <button @click.stop="child">大头儿子</button>
        </div>
      </div>
    </template>
    <script>
    export default {
      name: "vue-event",
      methods: {
        child(e) {
           e.stopPropagation()//使用vue提供的修饰符
          console.log("子元素事件");
        },
        parent(){
          console.log("父元素事件");
        }
      },
    ​
    }
    </script>
    ​
    <style scoped>
    ​
    </style>

    两种方式:

    一、通过@click.stop 阻止单击事件继续传播

    二、通过 e.stopPropagation()阻止单击事件继续传播

  1. 按键修饰符.enter * .tab.delete (捕获“删除”和“退格”键).esc.space.up.down.left.right

    案例二(按键事件)

<template>
  <input type="text" v-on:keyup.enter='getInput'>
​
</template>
​
<script>
export default {
  name: "input-vue",
  methods:{
    getInput(e){
      //console.log(e);
      console.log('按下了回车--搜索');
​
    }
  }
}
</script>
​
<style scoped>
​
</style>
  1. 系统修饰键.ctrl.alt.shift.meta

案例三:

<template>
  <div>
    <!-- 3. 系统修饰键 -->
    <textarea @keyup.ctrl.enter="" cols="30" rows="10"></textarea>
    <button @click="send">发送</button>
  </div>
​
</template>
​
<script>
export default {
  name: "vue-send",
methods:{
  //系统修饰符
  send(){
    console.log('发送了聊天信息');
  }
}
​
}
</script>
​
<style scoped>
​
</style>

  1. 鼠标按钮修饰符.left.right.middle

数组更新检测

  1. 说明:在列表渲染中,如果遍历是数组,当数组数据发生改变时,页面什么时候能自动更新(页面重新渲染)

  2. 实现数组视图同步更新

    1. 变更方法 (修改了原数组)push()pop()shift()unshift()splice()sort()reverse()

    2. 替换数组(修改后返回新的数组 原数据不修改 视图想同步更新 覆盖原数组)filter()、concat() 和 slice()

  **案例演示数组追加、反转、切割**

  ```vue
  <template>
    <div>
      <h2>数组更新同步</h2>
      <p>arr:{{ arr }}</p>
      <button @click="addArr">追加数组</button>
      <button @click="sliceArr">切割数组</button>
      <button @click="reverseArr">数组反转</button>
    </div>
  </template>
  
  <script>
  export default {
    name: "vue-array",
    data() {
      return {
        arr: [1, 2, 3],
      };
    },
    methods: {
      reverseArr(){
        this.arr.reverse()
      },
      addArr() {
         this.arr.push(100)
  
      },
      sliceArr() {
        //slice() 返回新的数组
        let newArr = this.arr.slice(0);
        console.log(newArr);
        //替换
        this.arr = newArr;
      },
    },
  
  }
  </script>
  
  <style scoped>
  
  </style>
  ```

对象更新检测

  1. 说明:对象修改后 视图同步更新视图 -- 内存:栈内存 堆内存

  2. 实现对象视图同步更新

    1. Vue.set( target, propertyName/index, value )参数:

      {Object | Array} target
      {string | number} propertyName/index
      {any} value
      返回值:设置的值。
      
      

      用法:

      向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi')
      
      

案例(对象同步更新)

<template>
  <div>
    <h2>对象同步更新</h2>
    <p>对象obj:{{ obj }}</p>
    <button @click="changeUname">修改对象已存在的属性</button>
    <button @click=" obj = {user:'admin'}">修改整个obj</button>
    <button @click="addAttribute">给obj添加不存在的属性</button>
  </div>
</template>
​
<script>
export default {
  name: "vue-object",
  data(){
    return {
      obj:{
        uname:'张三三',
        age:20
      }
    }
  },
  methods:{
    changeUname(){
      this.obj.uname ='李思思'
    },
    addAttribute(){
       this.obj.sex='女'
       console.log('obj',this.obj);
      //问题:vue认为 obj没有修改
      //1. ...
      // this.obj ={...this.obj};
      //2. es6: 合并对象  Object.assign({},{},{})
      // this.obj=Object.assign({},this.obj)
​
      //3. vue官网解决方法:
      //向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。
      // this.$set(this.obj,'love','女')
      //Vue.set(this.obj,'learn','学习')
​
      //删除 同步视图 删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。
      //Vue.delete(this.obj,'age')
​
​
    }
​
  }
​
}
</script>
​
<style scoped>
​
</style>

Class 与 Style 绑定

  1. 介绍:动态的添加class或者是style样式

  2. 绑定 HTML Class

    1. 直接绑定变量

      <div v-bind:class='变量'></div>

    2. 对象语法 ***

      <div v-bind:class="{类名: 表达式-true显示类名、false隐藏 ,类名:boolean}"></div>

    3. 数组语法

      <div v-bind:class="[变量1,变量2, {类名:boolean}]"></div>

  3. 绑定内联样式v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名

    1. 对象语法

      <div v-bind:style="{css样式:变量,... }"></div>

    2. 数组语法

      <div v-bind:style="[baseStyles, overridingStyles]"></div>

    3. 直接变量

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

      data: {

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

      }

表单输入绑定

  1. 介绍你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定通过指令 v-model='' 获取表单输入的信息数据 实现双向数据绑定

  2. 语法: <input type='text' v-model='变量' />data(){

    return{
        msg:''
    }
    
    

    }

  3. 修饰符   .lazy   只有当input失去焦点时才更新数据     .number  把input标签中输入的内容转成数字,调用是parseFloat (Nunber())     .trim  去除左右空格

  1. v-model实现原理v-model只不过是一个语法糖而已,真正的实现靠的还是

    v-bind:绑定响应式数据触发oninput 事件并传递数据

    v-model 是什么。语法糖 :value + @input。还要分为两种情况

    <input v-model="val"><!-- 基本等价于,因为内部还有一些其他的处理 -->是事件对象,​event.target.value表示input框中的输入值<input :value="val" @input="val = $event.target.value">

    *案例练习

<template>
  <div>
    <h2>表单输入绑定</h2>
    <!-- <input type="text" :value="msg" name="" id=""> -->
    <!-- 1. 文本/密码 v-model=''-->
    <input
      type="text"
      placeholder="请输入"
      v-model="formData.msg"
      @keyup.enter="send"
      name=""
      id=""
    />
    <p>msg:{{ formData.msg }}</p>
    <!-- 2. 多行文本 -->
​
    <!-- 3. 单选按钮 -->
    性别:
    <input type="radio" v-model="formData.sex" name="aa" value="1" />男
    <input type="radio" v-model="formData.sex" name="aa" value="2" />女
    <p>选择的性别:{{ formData.sex }}</p>
​
    爱好:
    <input type="checkbox" v-model="formData.arr" value="a" />吃
    <input type="checkbox" v-model="formData.arr" value="b" />喝
    <input type="checkbox" v-model="formData.arr" value="c" />玩
    <p>选择的爱好:{{ formData.arr }}</p>
​
    城市:
    <select name="" id="" v-model="formData.select">
      <option value="">请选择</option>
      <option value="beijing">北京</option>
      <option value="shanghai">上海</option>
      <option value="gaungzhou">广州</option>
    </select>
    <p>城市选择:{{ formData.select }}</p>
​
    <button @click="submit">注册信息</button>
    <hr>
    <h3>表单修饰符 -修饰符 </h3>
    <!-- .lazy 失去焦点或者回车 获取数据 -->
    <input type="text" v-model.lazy="search">
    <p>search:{{ search }}</p>
    <!-- .trim 去掉前后空格 -->
    <input type="text" v-model.trim="msg" name="" id="">
    <p>去空格:{{msg}}</p>
​
    <!-- .number  转数字 -->
    <input type="number" v-model.number="num" name="" id="">
    <p>num:{{ num }}</p>
​
    <!-- v-model实现的原理 -->
    <input type="text" v-model="inp" name="" id="">
    <p>inp:{{inp}}</p>
​
    <!-- v-model == v-bind:value='' @input='函数' -->
    表单值:<input type="text" :value="val" @input="changeVal" name="" id="">
    <p>val:{{val}}</p>
​
  </div>
</template>
​
<script>
export default {
  data() {
    return {
        val:'请输入',
        inp:'',
      msg: "", //输入框
      sex: 1, //性别
      arr: [],
      select: "",
      search:'',
      num:'',
      //对象的语法---------------
      formData: {
        msg: "", //输入框
        sex: 1, //性别
        arr: [],
        select: "",
      },
    };
  },
  methods: {
    send() {
      console.log("输入的数据为:", this.msg);
    },
    submit() {
      //点击按钮--发送输入的数据给后台-- data -- msg  sex arr ...
      console.log("提交注册信息表单",this.formData);
    },
    changeVal(e){
        console.log(e);
        console.log(e.target.value);//獲得輸入信息
        this.val = e.target.value;
    }
  },
};
</script>
​
<style>
</style>

例题:将上述的张大大点击按钮后修改成岳云鹏

实现方式如下:

<template>
<div id="app">
  <h3>内容输出</h3>
  <p>
    {{username}}
  </p>
  <button @click="updateUserName">修改上述张大大</button>
</div>
</template>
​
<script>
export default {
​
  name: "Mains",
  /*data:{
    username:'张大大'
  }*/
  data(){
    return {
      username:'张大大'
    }
},
  //这里需要和data函数平级
  methods:{
    updateUserName(){
      this.username = "岳云鹏"
      //this 表示Vue对象
    }
  }
​
}
</script>
​
<style lang="less">
​
</style>

计算属性讲解

计算属性是定义在computed 这个当中。

计算属性中必须有get()

计算属性是计算出来的没有在Vue对象中,通过Vue插件可以证明。

案例显示如下:

定义一个三峡大学,定义一个科技学院 然后通过计算属性将他们连接起来。

实现如下:

<template>
<div id="app">
  <span>
    {{frName}}
  </span>
  <hr>
  <span>
    {{LzName}}
  </span>
  <hr>
  <span>
    {{allName}}
​
  </span>
</div>
</template>
​
<script>
export default {
​
  name: "Mains",
​
  data(){
    return {
    frName:"三峡大学",
    LzName:"科技学院"
​
    }
},
//用来定义计算属性。
  computed:{
    allName:{
      get(){
        return this.frName +'-'+ this.LzName
      }
    }
  },
​
  methods:{
​
  }
​
}
</script>
​
<style lang="less">
​
</style>

计算属性中也有set()函数。 是用来修改数据的【开发当中不常用】。

上述可以简化为下面代码。

 allName(){
      return this.frName + '-'+this.LzName
    }

实现代码如下:

<template>
<div id="app">
 <h3>你今天生病了吗?{{isValues?'没有':'生病了'}}</h3>
  <hr>
  <button @click="updateValue">点击变化</button>
</div>
</template>
​
<script>
export default {
​
  name: "Mains",
​
  data(){
    return {
      isValues:true,
​
    }
},
  computed:{
​
    },
  methods:{
    updateValue(){    
        this.isValues = !this.isValues   
    }
  }
​
}
</script>
​
<style lang="less">
​
</style>

上述功能实现了,需要用计算属性来实现。

<template>
<div id="app">
 <h3>你今天生病了吗?{{info}}</h3>
  <hr>
  <button @click="updateValue">点击变化</button>
</div>
</template>
​
<script>
export default {
​
  name: "Mains",
​
  data(){
    return {
      isValues:true,
​
    }
},
  computed:{
    info(){
      return this.isValues?'没有':'生病了'
    }
    },
  methods:{
    updateValue(){
        this.isValues = !this.isValues
​
    }
  }
}
</script>
<style lang="less">
</style>

案例三

<template>
  <div>
    <h2>计算属性computed</h2>
    <!-- 如果是字符串 取反操作实现 -->
    <p>字符串:{{ msg }}</p>
    <!-- 不推荐: 模板语法里面写很多方法  多次使用不方便 -->
    <p>字符串-取反:{{ msg.split("").reverse().join("") }}</p>
​
    <p>字符串-取反-封装函数:{{ qufan() }}</p>
    <p>字符串-取反-封装函数:{{ qufan() }}</p>
    <p>字符串-取反-封装函数:{{ qufan() }}</p>
​
    <!-- 计算属性:  -->
    <p>计算属性:-取反:{{ msg2 }}</p>
    <p>计算属性:-取反:{{ msg2 }}</p>
    <p>计算属性:-取反:{{ msg2 }}</p>
​
    <button @click="msg = 'how are you'">修改msg</button>
    <!-- 例子: v-for='' v-if不能在同一个元素使用 -- computed处理数据 -->
    <h4>早市水果更新:</h4>
    <ul>
        <li v-for="item in zaoshi2" :key='item.id'>
            {{item.fruit}}
        </li>
    </ul>
​
  </div>
</template>
​
<script>
export default {
  data() {
    return {
      msg: "hello vue",
      zaoshi: [
        {
          id: 100,
          fruit: "苹果",
          flag: false,
        },
        {
          id: 101,
          fruit: "阳光玫瑰",
          flag: true,
        },
        {
          id: 102,
          fruit: "车厘子",
          flag: false,
        },
        {
          id: 103,
          fruit: "榴莲",
          flag: true,
        },
      ],
    };
  },
  methods: {
    qufan() {
      console.log("执行了方法");
      return this.msg.split("").reverse().join("");
    },
  },
  //计算属性: 对数据进行加工处理  缓存数据
  computed: {
    msg2() {
      console.log("计算属性: 对数据进行加工处理  缓存数据");
      return this.msg.split("").reverse().join("");
    },
    //处理数据
    zaoshi2(){
        //过滤方法 返回的满足条件的数组  比如:[1,2,3,4]  =>[3,4]
        return this.zaoshi.filter((item)=>{
             return item.flag
        })
    }
  },
};
</script>
​
<style>
</style>

侦听器学习:(watch)

定义格式为 watch:{

对那和属性侦听

}

将上面的例子修改一下:

<template>
<div id="app">
 <h3>你今天生病了吗?{{info}}</h3>
  <hr>
  <button @click="updateValue">点击变化</button>
</div>
</template>
​
<script>
export default {
​
  name: "Mains",
​
  data(){
    return {
      isValues:true,
​
    }
},
  computed:{
    info(){
      return this.isValues?'没有':'生病了'
    }
​
    },
​
  watch:{
    isValues:{
      handler(newValue,oldValue){
        //console.log(newValue,oldValue)
        console.log('isValues被修改了',newValue,oldValue)
      },
    }
  },
  methods:{
    updateValue(){
        this.isValues = !this.isValues
​
    }
  }
}
</script>
​
<style lang="less">
​
</style>

侦听 中有handler()函数,通过handler()中newValue,oldValue获得侦听 前的值和侦听后的值。

第二种侦听通过Vue对象中定义的$watch()

<!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>
  </head>
​
  <body>
    <!-- 绑定Vue数据的插值语法 -->
    <div id="root">
      <h3>你今天生病了吗?{{info}}</h3>
      <hr />
      <button @click="updateValue">点击变化</button>
    </div>
​
    <!-- 导入Vue的js -->
​
    <script src="js/vue.js"></script>
    <script>
      // 初始化Vue
      const vm = new Vue({
        el: '#root',
        //绑定事件
        data: {
          isValues: true,
        },
        computed: {
          info() {
            return this.isValues ? '没有' : '生病了'
          },
        },
        methods: {
          updateValue() {
            this.isValues = !this.isValues
          },
        },
      })
      vm.$watch('isValues', {
        handler(newValue, oldValue) {
          //console.log(newValue,oldValue)
          console.log('isValues被修改了', newValue, oldValue)
        },
      })
    </script>
  </body>
</html>

computed和watch区别 (考点面试题)

  1. 相同:computed和watch都是观察页面的数据变化的。

  2. 不同:computed:是计算属性,依赖其它属性值:

    1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
        2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
       watch:没有缓存性,更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;
        1. 不支持缓存,数据变,直接会触发相应的操作;
        2. watch支持异步;
    
    

       # 第三章    vue
    
    

    ​ ​ ​ ​ ​ ​ ​ ​ ​

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值