初识Vue.js_介绍与Vue.j s 有关的一些概念、技术、原理。并快速构建出一个Vue.js 应用。

一、Vue.js的有关概念

Vue.js (读音 /vjuː/,类似于view) 是一套用于构建用户界面的渐进式(Progressive)框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

简单小巧的核心,渐进式技术栈,足以应付任何规模的应用。简单小巧是指Vue.js 压缩后大小仅有17KB。所谓渐进式,就是您可以(step by step)一步一步、有阶段性地来使用Vue .j s ,不必一开始就使用所有的东西。

使用Vue.js 可以让Web开发变得简单,它提供了现代Web开发中常见的高级功能:

  • 解辑视图与数据;
  • 可复用的组件;
  • 前端路由;
  • 状态管理;
  • 虚拟DOM。

假设您已了解关于 HTML、CSS 和 JavaScript 的中级水平的知识,就可以开始学习了。如果您刚开始学习前端开发,将框架作为你的第一步可能不是最好的主意——掌握好基础知识再来吧!

1.1 安装

① 兼容性:

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

② 直接用 <script>引入:

直接下载并用 <script> 标签引入,Vue 会被注册为一个全局变量。

对于制作原型或学习,可以这样使用最新版本:

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

对于生产环境,推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>

如果使用原生 ES Modules,这里也有一个兼容 ES Module 的构建文件:

<script type="module">
    import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.esm.browser.js '
</script>

可以在 cdn.jsdelivr.net/npm/vue 浏览 NPM 包的源代码。

Vue 也可以在 unpkg 和 cdnjs 上获取 (cdnjs 的版本更新可能略滞后)。

请确认了解不同构建版本并在你发布的站点中使用生产环境版本,把 vue.js 换成 vue.min.js。这是一个更小的构建,可以带来比开发环境下更快的速度体验。

③ NPM

在用 Vue 构建大型应用时推荐使用 NPM 安装。NPM 能很好地和诸如 webpack 或 Browserify 模块打包器配合使用。同时 Vue 也提供配套工具来开发单文件组件 。

$ npm install vue     # 最新稳定版

④ 命令行工具 (CLI)

Vue 提供了一个官方的 CLI,为单页面应用 (SPA) 快速搭建繁杂的脚手架。它为现代前端工作流提供了 开箱即用(batteries-included) 的构建设置。只需要几分钟的时间就可以运行起来并带有热重载、保存时 lint 校验,以及生产环境可用的构建版本。更多详情可查阅 Vue CLI 的文档

Vue CLI是用于快速Vue.js开发的完整系统,它提供:

  • 交互项目脚手架通过@vue/cli实现;
  • 零配置快速原型制作通过@vue/cli + @vue/cli-service-global实现;
  • 运行时依赖项通过@vue/cli-service实现,这个是:可升级;建立在webpack之上,具有合理的默认值;可通过项目内配置文件进行配置;
  • 丰富的官方插件集合,集成了前端生态系统中的最佳工具;
  • 完整的图形用户界面,用于创建和管理Vue.js项目。

Vue CLI的目标是成为Vue生态系统的标准工具基线。 它可以确保各种构建工具与合理的默认设置一起顺利运行,因此可以专注于编写应用程序,而不必花费大量时间进行配置。 同时,它仍然可以灵活地调整每个工具的配置,而无需弹出。

Vue CLI有几个移动的部分,其中包含许多单独发布的软件包。

CLI

CLI@vue/cli)是全局安装的npm软件包,并在终端中提供vue命令。 它提供了通过vue create快速搭建新项目的能力,或通过vue serve立即为新创意制作原型的功能。 还可以通过vue ui使用图形用户界面来管理项目。

安装: 

推荐先下淘宝镜像:npm install -g cnpm --registry=https://registry.npm.taobao.org
//下好了淘宝镜像之后下面有npm的代码都可以换成cnpm,下载速度会加快
npm install -g @vue/cli

创建一个项目:

vue create mypro
# 或
vue ui

CLI Service

CLI Service@vue/cli-service)是开发依赖项。 这是一个安装在本地的由@vue/cli创建的每个项目中的npm软件包。

CLI Plugins

CLI Plugins是npm软件包,可为Vue CLI项目提供可选功能,例如Babel / TypeScript编译,ESLint集成,单元测试和端到端测试。

1.2 M V V M 模式

Vue.js 在设计上使用MVVM 模式 , MVVM是Model-View-ViewModel的简写,即模型-视图-视图模型。【模型】指的是后端传递来的数据;【视图】指的是所展示的页面;【视图模型】为MVVM 模式的核心,它是连接View和Model的桥梁。它有两个方向:一是将【模型】转化成【视图】,即将后端传递的数据转化成所展示的页面。实现的方式是:数据绑定。二是将【视图】转化成【模型】,即将所展示的页面转化成后端需要的数据。实现的方式是:DOM 事件监听。这两个方向所实现的即为数据的双向绑定。

MVVM的模式下ViewModel是不能直接通信的,它们通过ViewModel来通信。ViewModel通常要实现一个observer观察者,当Model数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的View做自动更新。而当用户操作View,ViewModel也能监听到View的变化,然后通知Model做数据改动,这实际上就实现了数据的双向绑定。

MVVM模式是由经典的软件架构MVC 衍生来的。当View (视图层)变化时,会由ViewModel(视图模型)监听到并自动更新到Model(模型),反之亦然。View 与ViewModel和 ViewModelModel之间通过双向绑定(data-binding )建立联系。如图1所示:

图 1. M V V M关系 MVVM关系

Vue就是基于MVVM模式实现的一套框架。在Vue中,Model指的是JavaScript中的数据,如对象、数组等等;View指的是页面视图ViewModel指的是Vue的实例化对象

Vue.js操作DOM:

① 在清单1中实现ES5操作DOM

清单 1. ECMAScript 5操作DOM

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>ES5操作DOM</title>
  </head>
  <body>
    <div id="app"></div>
    <script>
        var app = document.getElementById("app")
        var showBtn = true;

        function handleButtonClick() {
            if(showBtn) {
                console.log('已点击了我!')
                var hone = document.createElement("h1");
                hone.innerHTML = '已点击了我!';
                app.appendChild(hone);
                showBtn = false;
            }
        }

        var btn = document.createElement("button");
        btn.innerHTML = "点击我";
        btn.onclick = handleButtonClick;
        app.appendChild(btn);
    </script>
  </body>
</html>

清单1中这段代码不难理解,操作的内容也不复杂,不过这样让我们的视图代码和业务逻辑紧藕合在一起,随着功能不断增加,直接操作DOM 会使得代码越来越难以维护。

② 在清单2中实现Vue.js操作DOM

Vue.js 通过MVVM 的模式拆分为视图数据两部分,并将其分离。因此,只要关注数据即可, DOM的事情Vue 会自动搞定。上面的示例清单1用Vue.js 可以改写为清单2:

清单 2. Vue.js操作DOM

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Vue操作DOM</title>
    <script src="js/vue.js"></script>
  </head>
  <body>
    <div id="app">
        <button v-if="showBtn" v-on:click="handleClick">点击我</button>
        <h1>{{clickme}}</h1>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                showBtn: true,
                clickme:''
            },
            methods: {
                handleClick: function() {
                    console.log('已点击了我!');
                    this.clickme = '已点击了我';
                }
            }
        })
    </script>
  </body>
</html>

清单 2中的代码,当执行 new Vue() 时,Vue 就进入了初始化阶段,一方面,Vue 会遍历 data 选项中的属性,Observer 数据监听器,把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用Object.defineProperty()方法把这些属性全部转成setter、getter方法。当data中对象的某个属性被访问时,则会调用getter方法,当data中对象的属性被改变时,则会调用setter方法。实现数据变化监听功能;另一方面,Vue 的指令编译器Compile 对元素节点的指令进行解析,替换模板数据,初始化视图。并使得订阅者Watcher 绑定对应的更新函数Updater以更新视图。 此时Watcher 会将自己添加到消息订阅器中(Dep),初始化完毕。

当数据发生变化时,Observer 中的 setter 方法被触发,setter 会立即调用Dep.notify(),Dep 开始遍历所有的订阅者,并调用订阅者的 update方法,订阅者收到通知后对视图进行相应的更新。

其中的el用于外部的模板template或者将HTML作为模板编译。用于指定一个页面中己存在的DOM 元素来挂载Vue实例。

图 2. Vue执行流程 Vue执行流程

1.3 传统的前端开发模式与Vue.js的开发模式的比较

如今的前端开发己不再是写个HTML 和css 那样简单了,新的概念不断涌现,已有像ECMAScript 6 、Node.js 、NPM 、前端工程化等。它们正在不断优化现有的开发模式,改变传统的编程思想。

曾经以jQuery框架技术为核心的技术栈被许多商业项目用于生产环境:

jQuery + RequireJS ( SeaJS ) + artTemplate ( doT ) + Gulp ( Grunt)

这套技术栈能兼容绝大部分浏览器,有的的客户很可能还在用IE 8及以下浏览器;使用RequireJS 或SeaJS 进行模块化开发可以解决代码依赖混乱的问题,同时便于维护及团队协作;使用轻量级的前端模板(如doT )可以将数据与HTML模板分离;最后,使用自动化构建工具(如Gulp )可以合并压缩代码,如果采用写Less 、Sass以及现在流行的ES 6,也可以进行预编译。

由于以jQuery框架技术为核心的技术栈的简单、高效、实用, 至今仍有不少开发者在使用,这样一套前端解决方案就称为传统前端开发模式。其核心是直接操作DOM的思想,jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。

不过随着项目的扩大和时间的推移,出现了更复杂的业务场景,比如SPA (单页面富应用〉、组件解耦等。为了提升开发效率,降低维护成本,传统的前端开发模式己不能完全满足项目的需求,这时就出现了如Vue.jsAngular 、React 等框架技术为代表的现代Web前端开发模式 。

Vue.js 是一个渐进式的JavaScript框架,根据项目需求,可选择从不同的维度来使用之。如果开发简单的HTML5页面应用,可以通过<script> 直接加载Vue.js独立文件,并不需要jQuery等另外的库文件 :

<!--自动识别最新稳定版本的Vue.j s -->
<script src = "https://unpkg.com/vue/dist/vue.min.js"></script>
<!--指定某个具体版本的Vue.j s -->
<script src = "https://unpkg.com/vue@2.6.11/dist/vue.min.js"></script>

引入Vue.js 框架后,在页面元素标记<body>的底部使用new Vue()的方式创建一个实例,其表示的是ViewModel,它将数据Model和界面视图View完全分离开来了,对数据进行操作不再需要引用相应的DOM对象,可以说数据和视图是分离的,他们通过Vue对象实现相互的绑定。这就是Vue.js最基本的开发模式,即MVVM模式清单2中给出Vue实现完整代码,而清单3给出jQuery实现完整代码:

清单 2. Vue 示例:用户列表展示

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Vue 示例:展示用户列表</title>
  </head>
  <body>
    <div id="app">
        <ul>
            <li v-for="u in users">{{u.name}}</li>
        </ul>
    </div>
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                users: [
                     {name : '张三' },
                     {name : '李四' },
                     {name : '王麻子' }
                ]   
            }
        })
    </script>
  </body>
</html>

清单 3. jQuery 示例:用户列表展示

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>jQuery 示例:展示用户列表</title>
  </head>
  <body>
    <div id="app">
        <ul>
        </ul>
    </div>
    <script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
    <script>
        $(document).ready(function() {
            $("#app").children("ul").append("<li>张三</li>")
            $("#app").children("ul").append("<li>李四</li>")
            $("#app").children("ul").append("<li>王麻子</li>")
        });
    </script>
  </body>
</html>

1.4 声明式渲染

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

<div id="app-1">
    <h1> 
        hello  {{ nameMsg }}  
    </h1>
</div>

var vm1 = new Vue({
    el: '#app-1',
    data: {
       nameMsg: 'world!'
    }
})

通过Vue 实例的data 选项,可以声明应用内需要双向绑定的数据,data 选项中的name 字段, 就是Vue 需要绑定的数据。而Vue实例本身也代理了data 对象里的所有属性。看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。要怎么确认呢?在浏览器运行之后,打开浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 vm1.nameMsg = '张三',改变其值,将看到上例相应地更新。

请注意:不再和 HTML 直接交互了。一个 Vue 应用会将其挂载到一个 DOM 元素上 (对于这个例子是 #app-1) 然后对其进行完全控制。那个 HTML 是入口,但其余都会发生在新创建的 Vue 实例内部。

除了文本插值,还可以像这样来绑定元素属性

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

var vm2 = new Vue({
    el: '#app-2',
    data: {
        message: '页面加载于 ' + new Date().toLocaleString()
    }
})

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

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

1.5 条件与循环

控制切换一个元素是否显示:

<div id="app-3">
    <p v-if="seen">现在你看到我了</p>
</div>

var vm3 = new Vue({
    el: '#app-3',
    data: {
        seen: true
    }
})

继续在控制台输入 vm3.seen = false,会发现之前显示的消息消失了。

这个例子演示了不仅可以把数据绑定到 DOM 文本或元素属性,还可以绑定到 DOM 结构,此处用到了v-if指令。此外,Vue 也提供一个强大的过渡效果系统,可以在 Vue 插入更新/移除元素时自动应用过渡效果。

还有其它很多指令,每个都有特殊的功能,随着学习的逐渐深入,将会了解和掌握。再了解一个v-for 指令可以绑定数组或集合对象的数据来渲染一个项目列表:

<div id="app-4">
    <ol>
        <li v-for="book in books">
            {{ book.text }}
        </li>
    </ol>
</div>

var vm4 = new Vue({
    el: '#app-4',
    data: {
        books: [{
            text: 'JavaScript程序设计'
        },
        {
            text: 'Vue前端框架技术'
        },
        {
            text: 'Flask后端框架技术'
        }]
    }
})

在控制台里,输入 vm4.books.push({ text: 'Java程序设计' }),将会发现列表最后添加了一个新项目。

1.6 处理用户输入

为了让用户和应用进行交互,可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法reverseMessage

<div id="app-5">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">反转消息</button>
</div>

var vm5 = new Vue({
    el: '#app-5',
    data: {
        message: 'Hello 张三!'
    },
    methods: {
        reverseMessage: function () {
            this.message = this.message.split('').reverse().join('')
        }
    }
})

注意:在 reverseMessage 方法中,更新了应用的数据状态message,但没有触碰 DOM——所有的 DOM 操作都由 Vue 来处理,编写的代码只需要关注逻辑层面即可。

Vue 还提供了 v-model 指令,它能轻松实现表单输入和数据状态message之间的双向绑定。

<div id="app-6">
    <p>{{ message }}</p>
    <input v-model="message">
</div>

var vm6 = new Vue({
    el: '#app-6',
    data: {
        message: 'Hello 王麻子!'
    }
})

二、Vue 实例与生命周期

每个 Vue 应用都是通过构造函数Vue 创建一个Vue 的根实例,并启用多个选项开始:

var vm = new Vue({
     // 选项属性
})

变量vm表示对这个Vue 实例的引用,代表了 MVVM 模型中的ViewModel,这个变量名vm表示了 Vue 实例。当创建一个 Vue 实例时,可以传入一个包含多个选项属性的对象。使用这些选项属性创建想要的行为

2.1 el选项

传入Vue构造函数的对象参数,其中必不可少的一个选项属性就是el,其值为一个字符串形式的选择器,或者是DOM的元素对象。若为字符串,则是与css 选择器相同的表示方式,若是DOM的元素对象,则使用document.getElementById()或其它获取元素对象的方式。el提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标:

<div id="app"></div>

var vm = new Vue({
    el: '#app'
})
// 或者
var vm = new Vue({
    el: document.getElementById('app')
})

在实例挂载成功后,可以通过vm.$el来访问该元素。Vue 提供了很多常用的实例属性与方法,都以$开头。如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显示调用这个vm.$mount()手动开启编译。

提供的元素只能作为挂载点,所有的挂载元素会被Vue生成的DOM替换。因此不推荐挂载根实例<html><body>上。如果render函数和template属性都不存在,挂载DOM元素的HTML会被提取出来用作模板,此时,必须使用独立构建(编译器 + 运行时)的Vue库。进一步的解释就是:如果存在render函数或template属性,则挂载元素会被Vue生成的DOM替换;否则,挂载元素所在的HTML会被提取出来用作模版

vue实例中的el属性template属性render函数都是vue对象对应的HTML元素(DOM对象),它们存在时有一个优先级的顺序:el < template < render,Vue会选择其中优先级高的作为HTML输出:

<div id="app">
    <p>我是{{fname}},通过el出来的。</p>
</div>

var vm = new Vue({
    el:"#app",
    template: "<div><p>我是{{fname}},通过template出来的。</p></div>",
    data: {
            fname: '张三'
        },
    render:function(h){
       // 不能使用“双大括号”语法 ,因为Vue只是把render函数的返回值放在HTML里,而不进行再次的绑定。
       // Vue 在调用 render 方法时,会传入一个 createElement 函数作为参数,这里的 h 的实参是 createElement 函数
       return h('h1', '我是'+this.fname+',通过render出来的。')
    }
});

以上会使用render函数的内容,因为它的优先级高。render函数发挥了 JavaScript 最大的编程能力。

2.2 数据与方法

当一个 Vue 实例被创建时,它将data选项属性的对象中的所有的property特性加入到 Vue 的响应式系统中。当这些property特性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。通过Vue 实例的data 选项属性,可以声明应用内需要双向绑定的数据。所有会用到的数据都应该预先在data内声明,这样不至于将数据散落在业务逻辑中。

// 数据对象
var mydata = { msg: 3 }

// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
    data: mydata
})

// 获得这个实例上的 property与返回源数据中对应的字段作比对。
// 它们之间默认建立了双向绑定,当修改其中任意一个时,另一个也会一起变化。
// 切换到Console:
> vm.msg == mydata.msg    
< true                                     // =>true

// 设置 property 也会影响到原始数据
> vm.msg = 5
< 5
> mydata.msg
< 5                                        // => 5

// ……反之亦然
> datamy.msg = 6
< 6
> vm.msg 
< 6                                        // => 6

当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于 data选项中的 property 才是响应式的。也就是说如果你添加一个新的 property,例如:

> vm.myname = '张三'

那么对 myname 的改动将不会触发任何视图的更新。若是晚些时候需要一个 property,不过一开始它的值为空或不存在,则仅需要设置一些初始值。例如:

data: {
    newStudent: {
        name: '',
        gender: '',
        age: 18,
        tel: ''
    },
    visitCount: 0,
    hideCompletedStudent: false,
    students: [],
    error: null
}

这里有一个方法使用 Object.freeze(),它会阻止修改现有的 property,即响应系统无法再追踪变化。

var obj = {
    msg: 'hello'
}
Object.freeze(obj)       //使用Object.freeze()固化obj对象

new Vue({
    el: '#app',
    data: obj
})

<div id="app">
   <p>{{ msg }}</p>
   <!-- 这里的  msg 不会更新! -->
   <button v-on:click="msg = 'world'">更改</button>
</div>

除了数据 property,Vue 实例还有一些有用的实例特性与方法。它们都有前缀 $,以便与用户定义的 property 区分开来。例如:

var mydata = { val: 1 }
var vm = new Vue({
    el: '#app',
    data: mydata
})

//Console
> vm.$data === mydata           // => true
< true
> vm.$el === document.getElementById('app')   // => true
< true

// $watch 是一个实例方法
vm.$watch('val', function (newValue, oldValue) {
      // 这个回调将在 `vm.val` 改变后调用
})

2.3 生命周期

每个Vue 实例创建时,都会经历一系列的初始化过程,同时也会调用相应的生命周期钩子,可以利用这些钩子,在合适的时机执行相应的业务逻辑。

图 2. Vue生命周期 Vue生命周期

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值