Vue2详解

基本介绍


  • Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合
  • 支持和其它类库结合使用
  • 开发复杂的单页应用非常方便
  • Vue 是 Vue.js 的简称

在这里插入图片描述

  • M∶即 Model,模型,包括数据和一些基本操作

  • V∶即View,视图,页面渲染结果

  • VM∶即 View-Model,模型与视图间的双向操作(无需开发人员干涉)

  • 在 MVVM之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model
    渲染到View 中。而后当用户操作视图,我们还需要通过 DOM获取 View 中的数据,
    然后同步到Model 中。

  • 而 MVVM中的VM 要做的事情就是把DOM 操作完全封装起来,开发人员不用再关心
    Model 和View 之间是如何互相影响的

  • 只要我们 Model 发生了改变,View上自然就会表现出来

  • 当用户修改了View,Model 中的数据也会跟着改变。。

  • 结果:把开发人员从繁琐的 DOM操作中解放出来,把关注点放在如何操作 Model上, 大
    大提高开发效率

快速入门


在这里插入图片描述
为了让 IDEA 识别 Vue 代码,需要安装插件 Vue.js

在这里插入图片描述

  1. 创建新文件夹 D:\workspace\vue , 直接拖到 Idea 工具,使用 idea 打开
  2. 将下载好的 vue.js 拷贝到 D:\workspace\vue\vue.js
  3. 创建 D:\workspace\vue\vue_quick_start.html
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <div id="app">
    <!--
    1. {{message}} : 插值表达式
    2. message 就是从model的data数据池来设置
    3. 当我们的代码执行时,会到data{}} 数据池区匹配,如果匹配上,就进行替换
        ,如果没有匹配上,就会输出空
    -->
    <h1>欢迎你{{message}}-{{name}}</h1>
  </div>
<!--引入vue.js-->
<script src="vue.js"></script>
<script>
  //创建Vue对象
  /**
   * 1. 创建Vue对象实例
   * 2.
   */
  let vm = new Vue({
    el:'#app',  //创建的vue实例挂载到 id=app 的 div
    data: {  //data{} 表示数据池,有很多数据,以k-v形式设置
      message: 'Hello Vue!',
      name: 'ma'
    }
  })
</script>
</body>
</html>

在这里插入图片描述

数据单向渲染


v-bind 指令可以完成基本数据渲染/绑定,v-bind 简写形式就是一个冒号(:)

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1>{{message}}</h1>
  <!--
  1. 使用插值表达式引用 data 数据池数据是在标签体内
  2. 如果是在标签元素的属性上去引用 data 数据池数据时,不能使用插值表达式
  3. 需要使用v-bind
  -->
  <img v-bind:src="img_src" v-bind:width="img_width">
</div>

</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
    el:'#app',  //创建的vue实例挂载到 id=app 的 div
    data: {  //data{} 表示数据池,有很多数据,以k-v形式设置
      message: 'Hello Vue!',
      name: 'ma',
      img_src: '1.jpg',
      img_width: '300px'
    }
  })

  console.log(vm)
</script>
</html>

在这里插入图片描述

双向数据绑定


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>双向数据渲染</title>
</head>
<body>
<div id="app">
  <h1>{{message}}</h1>
  <!--
  1. v-bind是数据单向渲染:data 数据池绑定的数据变化,会影响view
  2. v-model 是数据的双向渲染:(1)data 数据池绑定的数据变化,会影响view
                            (2)view 关联的元素变化会影响到data数据池的数据
  -->
  <input type="text" v-model="hobby.val"><br>
  <input type="text" :value="hobby.val"><br>
  <p>你输入的爱好:{{hobby.val}}</p>
</div>

</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
        el:'#app',  
        data: {  
          message: 'hi 输入你的爱好',
          hobby: {
            val: '购物'
          }
        }
      })
  </script>
</html>

效果如下:
在这里插入图片描述

事件绑定


  • 使用 v-on 进行事件处理,比如: v-on:click 表示处理鼠标点击事件
  • 事件调用的方法定义在 vue 对象声明的 methods 节点中
  • v-on:事件名 可以绑定指定事件
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <button v-on:click="show">点击按钮</button>
</div>
</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
    el:'#app',
    data: {

    },
    methods: {
      show(){
        console.log('Hello Vue')
      }
    }
  })
</script>
</html>

注意事项和使用细节:

  • 如果方法没有参数,可以省略()
  • v-on 指令的简写形式 @

修饰符

  1. 修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定。
  2. 例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()即阻
    止事件原本的默认行为
  3. 事件修饰符
    .stop 阻止事件继续传播
    .prevent 阻止标签默认行为
    .capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进
    行处理
    .self 只当在 event.target 是当前元素自身时触发处理函数
    .once 事件将只会触发一次
    .passive 告诉浏览器你不想阻止事件的默认行为
  4. 键盘事件的修饰符
    比如: 项目经常需要监听一些键盘事件来触发程序的执行,而 Vue 中允许在监听的时候添
    加关键修饰符

官方文档 :
https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6
在这里插入图片描述
应用实例

需求: 演示 v-on:submit.prevent 的使用, 如果没有输入名字,控制台输出 “请输入名
字”,否则输出 “提交表单”

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <form action="http://www.baidu.com" v-on:submit.prevent="onMySubmit">
    姓名:<input type="text" v-model="user.name"><br/><br/>
    <button type="submit">注册</button>
  </form>
</div>
</body>

<script src="vue.js"></script>
<script>
  let vm = new Vue({
    el: '#app',
    data: {
      user: { // user数据(对象)的属性,可以动态生成

      }
    },
    methods: {
      onMySubmit() {
        if (this.user.name) {
          console.log('提交表单 name=', this.user.name)
        } else {
          console.log('请输入名字')
        }
      }
    }
  })
</script>
</html>

在这里插入图片描述
在这里插入图片描述

条件渲染/控制


Vue 提供了 v-if 和 v-show 条件指令完成条件渲染/控制

v-if 介绍
在这里插入图片描述
v-show 介绍
在这里插入图片描述
官方文档:https://cn.vuejs.org/v2/guide/conditional.html

应用实例

  1. 使用v-if实现
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="checkbox" v-model="sel">是否同意条款
  <h1 v-if="sel">你同意条款</h1>
  <h1 v-else>你不同意条款</h1>
</div>
</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
    el: '#app',
    data: {
      sel: false
    }
  })
</script>
</html>

在这里插入图片描述

  1. 使用v-show实现
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="checkbox" v-model="sel">是否同意条款
  <h1 v-show="sel">你同意条款</h1>
  <h1 v-show="!sel">你不同意条款</h1>
</div>
</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
    el: '#app',
    data: {
      sel: false
    }
  })
</script>
</html>

v-if和v-show的区别

v-if 会确保在切换过程中,条件块内的事件监听器和子组件销毁和重建

在这里插入图片描述
v-show 机制相对简单, 不管初始条件是什么,元素总是会被渲染,并且只是对 CSS 进行切换

在这里插入图片描述
使用建议:如果要频繁地切换,建议使用 v-show ;如果运行时条件很少改变,使用 v-if 较好

列表渲染


Vue 提供了 v-for 列表循环指令

在这里插入图片描述
在这里插入图片描述

用 v-for 来遍历一个对象的 property

在这里插入图片描述
在这里插入图片描述
你也可以提供第二个的参数为 property 名称 (也就是键名):

在这里插入图片描述
还可以用第三个参数作为索引:

在这里插入图片描述

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1>简单的列表渲染</h1>
  <ul>
    <li v-for="i in 3">{{i}}</li>
  </ul>

  <h1>简单的列表渲染-带索引</h1>
  <ul>
    <li v-for="(i, index) in 3">{{i}}-{{index}}</li>
  </ul>

  <h1>遍历数据列表</h1>
  <table width="400px" border="1px">
    <tr v-for="user in users">
      <td>{{user.id}}</td>
      <td>{{user.name}}</td>
      <td>{{user.age}}</td>
    </tr>
  </table>
</div>
</body>

<script src="vue.js"></script>
<script>
  let vm = new Vue({
    el: '#app',
    data: {
      users: [
        {id: 1, name: '张三', age: 20},
        {id: 2, name: '李四', age: 22},
        {id: 3, name: '王五', age: 21}
      ]
    }
  })
</script>
</html>

在这里插入图片描述

练习

  1. 将学生对象, 存放在数组中
  2. 遍历显示所有学生, 只显示成绩及格的学员
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1>学生成绩列表-及格学生</h1>
  <table width="500px" border="1px">
    <tr>
      <td>id</td>
      <td>名字</td>
      <td>年龄</td>
      <td>分数</td>
    </tr>
    <tr v-if="student.score >= 60" v-for="student in students">
      <td>{{student.id}}</td>
      <td>{{student.name}}</td>
      <td>{{student.age}}</td>
      <td>{{student.score}}</td>
    </tr>
  </table>
</div>
</body>

<script src="vue.js"></script>
<script>
  let vm = new Vue({
    el: '#app',
    data: {
      students: [
        {id: 1, name: '张三', age: 20, score: 70},
        {id: 2, name: '李四', age: 22, score: 50},
        {id: 3, name: '王五', age: 21, score: 90},
        {id: 4, name: '赵六', age: 21, score: 40}
      ]
    }
  })
</script>
</html>

在这里插入图片描述

组件化编程


基本说明

  1. 在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部
    分。例如可能会有相同的头部导航。

  2. 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不
    同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发(如图)

    在这里插入图片描述

  3. 解读上图

    • 组件(Component) 是 Vue.js 最强大的功能之一(可以提高复用性[1.界面2.业务处理])
    • 组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等
    • 组件渲染需要 html模板,所以增加了template 属性,值就是 HTML 模板
    • 对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用组件
    • data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据

应用实例

为什么需要组件化编程

  • 需求如下, 点击一个按钮, 可以显示点击的次数
    在这里插入图片描述
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <button v-on:click="click1">点击次数= {{count}} 次【非组件化方式】</button><br/><br/>
  <button v-on:click="click1">点击次数= {{count}} 次【非组件化方式】</button>
</div>
</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
    el: '#app',
    data: {
      count: 10
    },
    methods: {
      click1(){
        this.count += 1
      }
    }
  })
</script>
</html>

在这里插入图片描述
可见如果有多个按钮就会就会跟着一起变,如果把它们分开,需要再定义一个事件和数据,那么如果再增加第三个按钮、第四个按钮… ,每次都重新写,业务处理类似,复用性很差,我们下面来用组件化编程解决

使用全局组件化方式

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1>组件化编程-全局组件</h1>
<!--  使用全局组件-->
  <counter></counter><br/><br/>
  <counter></counter>
</div>
</body>

<script src="vue.js"></script>

<script>
  //1. 定义一个全局组件,名称为 counter
  //2. {}表示我们组件相关的内容
  //3. template 指定该组件的界面,因为会引用到数据池的数据,所以需要使用模板字符串
  //4. 要把组件视为一个Vue实例,也有自己的数据池和methods
  //5. 对于组件,数据池的数据是使用函数返回,不能使用原来的方式,目的是为了保证每个组件的数据是独立的
  Vue.component('counter',{
    template: `<button v-on:click="click()">点击次数= {{count}} 次【全局组件化方式】</button>`,
    data(){
      return {
        count: 10
      }
    },
    methods: {
      click(){
        this.count++
      }
    }
  })
  let vm = new Vue({
    el: '#app'
  })
</script>
</html>

在这里插入图片描述

使用局部组件化方式

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1>组件化编程-局部组件</h1>
<!--  使用局部组件,该组件是从挂载到 app的 Vue中的-->
  <my_counter></my_counter><br/><br/>
  <my_counter></my_counter>
</div>
</body>

<script src="vue.js"></script>

<script>
  //1. 定义一个组件
  const  buttonCounter = {
    template: `<button v-on:click="click()">点击次数= {{count}} 次【局部组件化方式】</button>`,
    data(){
      return {
        count: 10
      }
    },
    methods: {
      click(){
        this.count++
      }
    }
  }

  let vm = new Vue({
    el: '#app',
    components: { //引入某个组件,此时 my_counter就是一个组件,是一个局部组件,它的适用范围就在当前Vue
      'my_counter': buttonCounter
    }
  })
</script>
</html>

在这里插入图片描述
好处:

  • 可以把常用的组件,定义在某个commons.js中 export
  • 如果某个页面需要使用,直接 import

注意事项

  • 组件定义需要放置在 new Vue() 前,否则组件注册会失败

生命周期和钩子函数


  1. Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载
    DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期
  2. 钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模
    板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函
  3. 钩子函数的 作用就是在某个阶段, 给程序员一个做某些处理的机会

Vue实例的生命周期示意图,地址:

https://v2.cn.vuejs.org/v2/guide/instance.html

1) new Vue()
new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。

2) Init Events & Lifecycle
初始化组件的事件和生命周期函数

3) beforeCreate
组件创建之后遇到的第一个生命周期函数,这个阶段 data 和 methods 以及 dom 结构都未
被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数

4) Init injections & reactivity
这个阶段中, 正在初始化 data 和 methods 中的方法

5) created

  • 这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 dom 结构未
    初始化,页面未渲染

在这个阶段,经常会发起 Ajax 请求

6) 编译模板结构(在内存)

7) beforeMount
当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据

8) Create vm.$el and replace ‘el’ with it
这一步,再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上

9) mounted
此时,页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运
行中的阶段

10) 生命周期运行中
10.1 beforeUpdate
当执行此函数,数据池的数据新的,但是页面是旧的
10.2 Virtual DOM re-render and patch
根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面

10.3 updated
页面已经完成了更新,此时,data 数据和页面的数据都是新的

11) beforeDestroy
当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods
数据或方法 还可被调用

12) Teardown…… 注销组件和事件监听

13) destroyed
组件已经完成了销毁

应用实例-展示 VUE 实例生命周期和钩子函数执行时机

重点研究几个重要的钩子函数 (beforeCreate, created, beforeMount, mounted,beforeUpdate,updated)

在这几个钩子函数中, 数据模型是否加载/使用? 自定义方法是否加载/可用? html 模板是否加载/使用? html 模板是否完成渲染?

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <span id="num">{{num}}</span><br/><br/>
  <button @click="num++">赞!</button>
  <h2>{{name}},有{{num}}个人点赞</h2>
</div>
</body>

<script src="vue.js"></script>

<script>
  let vm = new Vue({
    el: '#app',
    data: {
      name: 'Tom',
      num: 1
    },
    methods: {
      show(){
        console.log('执行了show方法')
        return this.name;
      },
      add(){
        this.num++;
      }
    },
    beforeCreate(){ //生命周期函数-创建Vue实例前
      console.log('====================beforeCreate=====================')
      console.log('数据模型/数据池的数据是否加载/使用?[no]', this.name,' ', this.num)
      // console.log('自定义方法是否加载/使用?[no]', this.show())
      console.log('用户页面dom是否加载/使用?[yes]', document.getElementById('num'))
      console.log('用户页面dom是否被渲染?[no]', document.getElementById('num').innerText)
    },
    created(){ //生命周期函数-创建Vue实例
      console.log('====================created=====================')
      console.log('数据模型/数据池的数据是否加载/使用?[yes]', this.name,' ', this.num)
      console.log('自定义方法是否加载/使用?[yes]', this.show())
      console.log('用户页面dom是否加载/使用?[yes]', document.getElementById('num'))
      console.log('用户页面dom是否被渲染?[no]', document.getElementById('num').innerText)
      //可以发出Ajax
      //接收返回的数据
      //再次去更新data数据池的数据
      //编译内存模板结构
    },
    beforeMount(){ //生命周期函数-挂载前
      console.log('====================beforeMount=====================')
      console.log('数据模型/数据池的数据是否加载/使用?[yes]', this.name,' ', this.num)
      console.log('自定义方法是否加载/使用?[yes]', this.show())
      console.log('用户页面dom是否加载/使用?[yes]', document.getElementById('num'))
      console.log('用户页面dom是否被渲染?[no]', document.getElementById('num').innerText)
    },
    mounted(){ //生命周期函数-挂载前挂载后
      console.log('====================mounted=====================')
      console.log('数据模型/数据池的数据是否加载/使用?[yes]', this.name,' ', this.num)
      console.log('自定义方法是否加载/使用?[yes]', this.show())
      console.log('用户页面dom是否加载/使用?[yes]', document.getElementById('num'))
      console.log('用户页面dom是否被渲染?[yes]', document.getElementById('num').innerText)
    },
    beforeUpdate(){ //生命周期函数-数据池更新前
      console.log('====================beforeUpdate=====================')
      console.log('数据模型/数据池的数据是否加载/使用?[yes]', this.name,' ', this.num)
      console.log('自定义方法是否加载/使用?[yes]', this.show())
      console.log('用户页面dom是否加载/使用?[yes]', document.getElementById('num'))
      console.log('用户页面dom是否被更新?[no]', document.getElementById('num').innerText)
    },
    updated(){ //生命周期函数-数据池更新后
      console.log('====================updated=====================')
      console.log('数据模型/数据池的数据是否加载/使用?[yes]', this.name,' ', this.num)
      console.log('自定义方法是否加载/使用?[yes]', this.show())
      console.log('用户页面dom是否加载/使用?[yes]', document.getElementById('num'))
      console.log('用户页面dom是否被更新?[yes]', document.getElementById('num').innerText)
    }
  })
</script>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值