Vue完整版(二)

四、MVVM模式

4.1、什么是MVVM?

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

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

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

在这里插入图片描述
MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的 MVVM 框架有Vue.js、AngularJS等。

4.2、为什么要使用MVVM

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

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

4.3、MVVM的组成部分

在这里插入图片描述
View

View 是视图层,也就是用户界面。

前端主要由 HTML 和 CSS 来构建,为了更方便地展现 ViewModel 或者 Model 层的数据,已经产生了各种各样的前后端模板语言,比如 FreeMarker、Thymeleaf 等等,各大 MVVM 框架如 Vue.js,AngularJS,EJS 等也都有自己用来构建用户界面的内置模板语言。

Model

Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。

这里的难点主要在于需要和前端约定统一的 接口规则。

ViewModel

ViewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。

需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的

  • 比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示)
  • 页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互)

视图状态和行为都封装在了 ViewModel 里。这样的封装使得 ViewModel 可以完整地去描述 View 层。由于实现了双向绑定,ViewModel 的内容会实时展现在 View 层,这是激动人心的,因为前端开发者再也不必低效又麻烦地通过操纵 DOM 去更新视图。

MVVM 框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护 ViewModel,更新数据视图就会自动得到相应更新,真正实现 事件驱动编程。

View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。

4.4、MVVM模式的实现者

  • Model : 模型层,在这里表示JavaScript对象
  • View : 视图层,在这里表示DOM (HTML操作的元素)
  • ViewModel : 连接视图和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者
    • ViewModel 能够观察到数据的变化,并对视图对应的内容进行更新
    • ViewModel 能够监听到视图的变化,并能够通知数据发生改变
  • Vue.js 就是一个MVVM的实现者,他的核心就是实现了DOM监听与数据绑定。

4.5、为什么要使用 Vue.js

  • 轻量级,体积小是一个重要指标。Vue.js 压缩后有只有 20多kb (Angular 压缩后 56kb+,React 压缩后 44kb+)
  • 移动优先。更适合移动端,比如移动端的 Touch 事件
  • 易上手,学习曲线平稳,文档齐全
  • 吸取了 Angular(模块化)和 React(虚拟 DOM)的长处,并拥有自己独特的功能,如:计算属性
  • 开源,社区活跃度高

五、第一个Vue程序

5.1、说明

  • IDEA 可以安装 Vue 的插件!

注意:Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。

5.2、下载

  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

5.3、实例 demo

  • Vue.js 就是一个MVVM的实现者,他的核心就是实现了DOM监听与数据绑定。

在这里插入图片描述

  1. 新建一个HTML文件

  2. 导入Vue.js

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  1. 创建一个Vue对象实例
<script>
    var vm = new Vue({
        el: "#app",
        //Model:数据
        data: {
            message: "Hello,Vue!"
        }
    });
</script>
  • el:"#app":绑定元素的 ID
  • data:{message: "Hello,Vue!"}:数据对象中有一个名为 message 的属性,并设置了初始值"Hello,Vue!"
  1. 将实例绑定到页面元素
<!--view层 模板-->
<div id="app">
    {{message}}
</div>

只需要在绑定的元素中使用 双{}Vue 创建的名为 message属性包裹起来,即可实现数据绑定功能,也就实现了 ViewModel 层所需的效果,是不是和 EL 表达式非常像?

  1. 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    {{message}}
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        //Model:数据
        data: {
            message: "Hello,Vue!"
        }
    });
</script>
</body>
</html>
  1. viewModel双向绑定

为了能够更直观的体验 Vue 带来的双向绑定,可以直接在浏览器控制台演示一下:
在这里插入图片描述
此时就可以在控制台直接输入 vm.message 来修改值,中间是可以省略 data 的,在这个操作中,并没有主动操作 DOM,就让页面的内容发生了变化,这就是借助了 Vue 的 数据绑定 功能实现的。

MVVM 模式中要求 ViewModel 层就是使用 观察者模式 来实现数据的监听与绑定,以做到数据与视图的快速响应。

六、基础语法 & 用法

  • 现在数据和DOM已经被建立了关联,所有的东西都是响应式的。

  • 我们在控制台操作对象的属性,界面可以实时更新。

6.1、v-bind 绑定数据和元素属性

我们可以使用v-bind来 绑定数据和元素属性!

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

</head>
<body>

<!--view层 模板-->
<div id="app">
    <span v-bind:title="message">
        鼠标悬停几秒钟查看此处动态绑定的提示信息!
    </span>
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        //Model:数据
        data: {
            message: "Hello,Vue!"
        }
    });
</script>
</body>
</html>

你看到的 v-bind attribute 被称为 指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute。可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的 title attribute 和 Vue 实例的 message property 保持一致”。

如果你再次打开浏览器的 JavaScript 控制台,输入 app2.message = '新消息',就会再一次看到这个绑定了 title attribute 的 HTML 已经进行了更新。

6.2、v-if & v-else 条件渲染

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

<!--view层 模板-->
<div id="app">
    <!--    <p v-if="seen">现在你看到我了</p>-->
    <!--    <p v-else>看不到了</p>-->
    <p v-if="type==='A'">A</p>
    <p v-else-if="type==='B'">B</p>
    <p v-else>C</p>
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            //seen: true
            type: 'A'
        }
    });
</script>

</body>
</html>

6.3、v-for 列表渲染

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

<!--view层 模板-->
<div id="app">
    <ol>
        <li v-for="item in items">
            {{item.text}}
        </li>
    </ol>
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            items: [
                {text: '学习 JavaScript'},
                {text: '学习 Vue'},
                {text: '整个牛项目'}
            ]
        }
    });
</script>

</body>
</html>

在这里插入图片描述
在控制台里,输入 vm.items.push({ text: '新项目' }),你会发现列表最后添加了一个新项目。

6.4、v-on 绑定事件

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

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

<!--view层 模板-->
<div id="app">
    <button v-on:click="sayHi">click me</button>
    <p>The button above has been clicked {{counter}} times.</p>
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            counter: 0,
            message: "快来点我!"
        },
        methods: { //方法必须定义在 Vue 的 methods 对象中, v-on: 绑定事件
            sayHi: function (event) {
                this.counter++;
                alert(this.message)
            }
        }
    });
</script>

</body>
</html>

事件有Vue的事件、和前端页面本身的一些事件!

这里的click是vue的事件,可以绑定到Vue中的methods中的方法事件!

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

6.5、v-model Vue双向绑定

6.5.1、什么是双向绑定

Vue.js是一个MVVM框架,即 数据双向绑定,即:

  • 当数据发生变化的时候,视图也就发生变化,

  • 当视图发生变化的时候,数据也会跟着同步变化。

这也算是Vue.js的精髓之处了。

值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定。

单向数据绑定是使用状态管理工具的前提。

如果我们使用vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。

6.5.2、为什么要实现数据的双向绑定

在Vue.js 中,如果使用vuex ,实际上数据还是单向的,之所以说是数据双向绑定,这是用的UI控件来说,对于我们处理表单,Vue.js的双向数据绑定用起来就特别舒服了。

  • 即两者并不互斥,在全局性数据流使用单项,方便跟踪;
  • 局部性数据流使用双向,简单易操作。

6.5.3、在表单中使用双向数据绑定

你可以用v-model指令在表单<input>、<textarea><select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖它负责监听户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

注意:v-model会忽略所有元素的value、checked、selected特性的初始值而总是将Vue实例的数据作为数据来源,你应该通过JavaScript在组件的data选项中声明。

6.5.4、文本域

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

<!--view层 模板-->
<div id="app">
    输入的文本:<textarea v-model="msg"></textarea><br>
    双向数据绑定: {{msg}}
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            msg: "123"
        }
    });
</script>

</body>
</html>

6.5.5、单选框

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

<!--view层 模板-->
<div id="app">
    性别:
    <input type="radio" name="sex" value="" v-model="msg"><input type="radio" name="sex" value="" v-model="msg"><p>选中了:{{msg}}</p>
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            msg: ""
        }
    });
</script>

</body>
</html>

6.5.6、下拉框

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

<!--view层 模板-->
<div id="app">
    下拉框:
    <select name="" id="" v-model="msg">
        <option value="" disabled>--请选择--</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>D</option>
    </select>
    <span>value:{{msg}}</span>
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            msg: ""
        }
    });
</script>

</body>
</html>

注意: 如果 v-model 表达式的初始值未能匹配任何选项, 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项:value="" disabled

6.5.7、复选框

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

<!--view层 模板-->
<div id="app">
    单复选框:
    <input type="checkbox" id="checkbox" v-model="checked">
    选中的值: {{checked}}
</div>

<!--导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            checked: false
        }
    });
</script>

</body>
</html>

七、Vue组件

7.1、 什么是组件

组件是可复用的Vue实例,说白了就是一组可以重复使用的模板,跟JSTL的自定义标签、Thymeleaf的th:fragment等框架有着异曲同工之妙。
通常一个应用会以一棵嵌套的组件树的形式来组织:

在这里插入图片描述
例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册局部注册。至此,我们的组件都只是通过 Vue.component全局注册的:

Vue.component('my-component-name', {
  // ... options ...
})

全局注册的组件可以用在其被注册之后的任何 (通过new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。

到目前为止,关于组件注册你需要了解的就这些了,如果你阅读完本页内容并掌握了它的内容,我们会推荐你再回来把组件注册读完。

7.2、 第一个vue组件

  • 先注册组件,定义一个Vue组件component
    • Vue.component():注册组件
    • my-component-name:自定义组件的名字
    • template:组件的模板
  • 再实例化 Vue
    组件名必须全小写,一旦有大写,就会注册错误
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层 模板-->
<div id="app">
    <roc></roc>
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    //先注册组件,定义一个Vue组件component
    Vue.component('roc', { //组件名必须全小写,一旦有大写,就会注册错误
        template: '<li>Hello Roc</li>'
    })
    //再实例化Vue
    var vm = new Vue({
        el: "#app",
        //Model:数据
        data: {}
    });
</script>

</body>
</html>

7.3、 Prop 传递参数

注意: 默认规则下 props 属性里的值不能为大写。

  • Prop 的大小写
  • Prop 类型
  • 传递静态或动态 Prop
    • 传入一个数字
    • 传入一个布尔值
    • 传入一个数组
    • 传入一个对象
    • 传入一个对象的所有 property
  • 单向数据流
  • Prop 验证
    • 类型检查
  • 非 Prop 的 Attribute
    • 替换/合并已有的 Attribute
    • 禁用 Attribute 继承
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层 模板-->
<div id="app">
    <roc v-for="item in items" v-bind:prop="item">
    </roc>
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    //先注册组件,定义一个Vue组件component
    Vue.component('roc', { //组件名必须全小写,一旦有大写,就会注册错误
        props: ['prop'], //通过循环的遍历prop,v-bind:prop绑定属性,此属性‘prop’作为媒介,传递给模板
        //组件的模板
        template: '<li>{{prop}}</li>'
    })
    //再实例化Vue
    var vm = new Vue({
        el: "#app",
        //Model:数据
        data: {
            items: ["Java", "Python", "Vue"]
        }
    });
</script>

</body>
</html>
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值