前端Vue

HalukiSan 2024-08-06 10:03:02 阅读 64

第一章 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>

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

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

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事件(下篇)

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

实现方法:methods:{ -- -->

函数名(){

}

}

事件对象 event

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

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

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

事件修饰符.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()阻止单击事件继续传播

按键修饰符.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>

系统修饰键.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>

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

数组更新检测

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

实现数组视图同步更新

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

替换数组(修改后返回新的数组 原数据不修改 视图想同步更新 覆盖原数组)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>

```

对象更新检测

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

实现对象视图同步更新

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 绑定

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

绑定 HTML Class

直接绑定变量

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

对象语法 ***

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

数组语法

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

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

对象语法

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

数组语法

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

直接变量

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

data: { -- -->

styleObject: {

color: 'red',

fontSize: '13px'

}

}

表单输入绑定

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

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

return{

msg:''

}

}

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

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区别 (考点面试题)

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

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

1. 支持缓存,只有依赖数据发生改变,才会重新进行计算

2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化

watch:没有缓存性,更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;

1. 不支持缓存,数据变,直接会触发相应的操作;

2. watch支持异步;

# 第三章 vue

​ ​ ​ ​ ​ ​ ​ ​ ​



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。