Vue框架(1)

2022-11-25

概述

0.1、什么是MVVM

MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是WPF和Sliverlight的架构师)与2005年在他的博客上发表。

MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:

  • 该层向上与视图层进行双向数据绑定
  • 向下与Model层通过接口请求进行数据交互

在这里插入图片描述

MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的MVVM框架有Vue.jsAnfular JS

0.2、为什么要使用MVVM

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处

  • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
  • 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。

在这里插入图片描述

(1)View

View是视图层, 也就是用户界面。前端主要由HTH L和csS来构建, 为了更方便地展现vi eu to del或者Hodel层的数据, 已经产生了各种各样的前后端模板语言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.Angular JS, EJS等也都有自己用来构建用户界面的内置模板语言。

(2)Model

Model是指数据模型, 泛指后端进行的各种业务逻辑处理和数据操控, 主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则

(3)ViewModel

ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层, 前端开发者对从后端获取的Model数据进行转换处理, 做二次封装, 以生成符合View层使用预期的视图数据模型。   需要注意的是View Model所封装出来的数据模型包括视图的状态和行为两部分, 而Model层的数据模型是只包含状态的

比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示) 页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互) 视图状态和行为都封装在了View Model里。这样的封装使得View Model可以完整地去描述View层。由于实现了双向绑定, View Model的内容会实时展现在View层, 这是激动人心的, 因为前端开发者再也不必低效又麻烦地通过操纵DOM去更新视图。   MVVM框架已经把最脏最累的一块做好了, 我们开发者只需要处理和维护View Model, 更新数据视图就会自动得到相应更新,真正实现事件驱动编程。   View层展现的不是Model层的数据, 而是ViewModel的数据, 由ViewModel负责与Model层交互, 这就完全解耦了View层和Model层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环。

1.1 第一个Vue程序

下好插件后可以开始上手:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<!-- 导入vue -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>

<!--view层 模板-->
<div id="app">
    
</div>
<script>
    'use strict'
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            message: 'hello vue!'
        }
    })
</script>

</body>
</html>

在这里插入图片描述

双向绑定,在vm上做的更改会在view层实时变化

1.2. 基础语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--导入vue-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
    <span v-bind:title="message">鼠标悬浮几秒钟查看此处动态绑定的提示信息!</span>
</div>
 
<script>
    'use strict'
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            message: 'hello vue!'
        }
    })
</script>
</body>
</html>

使用v-bind绑定

你看到的v-bind等被称为指令,指令都带有前缀v-,这里该指令的信息是将这个元素节点的title特性和Vue实例的message属性绑定在一起

1.2..各种结构

  • v-if v-else
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--导入vue-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">B</h1>
    <h1 v-else="type==='C'">C</h1>
</div>
 
<script>
    'use strict'
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            message: 'hello vue!',
            type: 'A'
        }
    })
</script>
</body>
</html>
  • for
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--导入vue-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
    <p style='color:blue' v-for="item in items"></p>
</div>
 
<script>
    'use strict'
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            message: 'hello vue!',
            type: 'A',
            items: [{message: '小范'},{message: '小梁'},{message: '小红'}]
        }
    })
</script>
</body>
</html>
  • 事件 用v-on绑定事件(method)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--导入vue-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
    <button v-on:click="sayHi">点我</button>
</div>
 
<script>
    'use strict'
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            message: 'hello vue!',
            type: 'A',
            items: [{message: '小范'},{message: '小梁'},{message: '小红'}]
        },
        methods: {
            sayHi: function () {
                alert(this.message)
            }
        }
    })
</script>
</body>
</html>
  • 双向绑定 v-model=要进行双向绑定的东西
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--导入vue-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
    <input type="text" v-model="message"/> 
</div>
 
<script>
    'use strict'
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            message: ""
        }
    })
</script>
</body>
</html>

表单双绑、组件

1.什么是双向数据绑定 Vue.js是一个MV VM框架, 即数据双向绑定, 即当数据发生变化的时候, 视图也就发生变化, 当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue.js的精髓之处了。   值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的非UI控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用vue x那么数据流也是单项的,这时就会和双向数据绑定有冲突。

(1)为什么要实现数据的双向绑定

在Vue.js中,如果使用vuex, 实际上数据还是单向的, 之所以说是数据双向绑定,这是用的UI控件来说, 对于我们处理表单, Vue.js的双向数据绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双向,简单易操作。

2.在表单中使用双向数据绑定 你可以用v-model指令在表单、及元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇, 但v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。   注意:v-model会忽略所有表单元素的value、checked、selected特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <!--导入vue-->
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
  <select v-model="selected">
    <option value="" disabled>---请选择---</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>

  <p>
  选中了谁
  </p>
</div>

<script>
  'use strict'
  /*Model 数据*/
  let vue = new Vue({
    el: "#app",
    data: {
      selected: ""
    }
  })
</script>
</body>
</html>

1.3. vue组件

在这里插入图片描述

在这里插入图片描述

注意:在实际开发中,我们并不会用以下方式开发组件,而是采用vue-cli创建,vue模板文件的方式开发,以下方法只是为了让大家理解什么是组件。   使用Vue.component()方法注册组件,格式如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--导入vue-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body>
<!--view层 模板-->
<div id="app">
    <xiaofan v-for="item in items" v-bind:xf="item"></xiaofan>
</div>
 
<script>
    'use strict'
 
    Vue.component("xiaofan", {
        // 给组件传递数据需要用props
        props: ['xf'],
        template: '<h1></h1>'
    })
 
    /*Model 数据*/
    let vue = new Vue({
        el: "#app",
        data: {
            items: ['java', 'linux', 'python']
        }
    })
</script>
</body>
</html>
 

说明:

  • Vue.component():注册组件
  • xiaofan:自定义组件的名字
  • template:组件的模板

说明:

  • v-for=”item in items”:遍历Vue实例中定义的名为items的数组,并创建同等数量的组件
    • v-bind:panh=”item”:将遍历的item项绑定到组件中props定义名为item属性上;= 号左边的panh为props定义的属性名,右边的为item in items 中遍历的item项的值

2.1.Axios异步通信

7.1、什么是Axios Axios是一个开源的可以用在浏览器端和Node JS的异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下:

  • 从浏览器中创建XMLHttpRequests
  • 从node.js创建http请求
  • 支持Promise API[JS中链式编程]
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF(跨站请求伪造)

咱们开发的接口大部分都是采用JSON格式, 可以先在项目里模拟一段JSON数据, 数据内容如下:创建一个名为data.json的文件并填入上面的内容, 放在项目的根目录下

{
  "name": "狂神说Java",
  "url": "https://blog.kuangstudy.com",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "含光门",
    "city": "陕西西安",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://space.bilibili.com/95256449"
    },
    {
      "name": "狂神说Java",
      "url": "https://blog.kuangstudy.com"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}

测试代码

<!DOCTYPE html>
<html lang="en" xmlns:v-binf="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--v-cloak 解决闪烁问题-->
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="vue">
    <div>地名:</div>
    <div>地址:----</div>
    <div>链接:<a v-binf:href="info.url" target="_blank"></a> </div>
</div>

<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#vue",
        mounted(){//钩子函数
            axios
                .get('data.json')//get请求请求data.json
                .then(response=>(console.log(response.data)));//返回数据
        }
    });
</script>
</body>
</html>

说明:

  1. 在这里使用了v-bind将a:href的属性值与Vue实例中的数据进行绑定

  2. 使用axios框架的get方法请求AJAX并自动将数据封装进了Vue实例的数据对象中

  3. 我们在data中的数据结构必须和Ajax响应回来的数据格式匹配!

第一次我发现请求到的是http://localhost:63342/Vue-first/chapter1/data.json 404 (Not Found)

说明要请求上一级的,把data.json的路径改为’../data.json’,表示上一级目录,就行

终端成功输出:

image-20221126171046845

但是我们正常开发要想办法把请求到的数据渲染到view而不是终端输出。

那就要以下操作了:(data方法)

<!DOCTYPE html>
<html lang="en" xmlns:v-binf="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--v-cloak 解决闪烁问题-->
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="vue">
    <div>地名:</div>
    <div>地址:----</div>
    <div>链接:<a v-binf:href="info.url" target="_blank"></a> </div>
</div>

<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#vue",
        //data:属性:vm
        data(){
            return{//请求的返回参数要合适,必须和data.json里的参数一样
                info:{
                    name:null,
                    address:{
                        country:null,
                        city:null,
                        street:null
                    },
                    url:null
                }
            }
        },
        mounted(){//钩子函数
            axios
                .get('../data.json')
                .then(response=>(this.info=response.data));//注意这个data是属性
        }
    });
</script>
</body>
</html>

image-20221126173424949

成功渲染

2.2、Vue的生命周期

官方文档:https://cn.vuejs.org/v2/guide/instance.html#生命周期图示

img  Vue实例有一个完整的生命周期,也就是从开始创建初女台化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。   在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。