浅学vue

  • Post author:
  • Post category:vue


浅学vue


官方文档

概述

  • Soc原则:关注点分离原则

  • Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。

  • HTML + CSS + JS : 视图 : 给用户看,刷新后台给的数据

  • 网络通信 : axios

  • 页面跳转 : vue-router

  • Vue-UI : ICE , Element UI

1.1、Vue.js是什么?

​ Vue (读音 /vjuː/,类似于

view

) 是一套用于构建用户界面的

渐进式框架

。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与

现代化的工具链

以及各种

支持类库

结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。


  • MVVM模式的实现者

    • Model:模型层, 在这里表示JavaScript对象

    • View:视图层, 在这里表示DOM(HTML操作的元素)

    • ViewModel:连接视图和数据的中间件, Vue.js就是MVVM中的View Model层的实现者

在MVVM架构中, 是不允许数据和视图直接通信的, 只能通过ViewModel来通信, 而View Model就是定义了一个Observer观察者

  • ViewModel能够观察到数据的变化, 并对视图对应的内容进行更新

  • ViewModel能够监听到视图的变化, 并能够通知数据发生改变

至此, 我们就明白了, Vue.js就是一个MV VM的实现者, 他的核心就是实现了DOM监听与数据绑定

1.2、为什么要使用Vue.js


  • 轻量级, 体积小是一个重要指标。

    Vue.js压缩后有只有20多kb(Angular压缩后56kb+,React压缩后44kb+)


  • 移动优先

    。更适合移动端, 比如移动端的Touch事件


  • 易上手,学习曲线平稳,文档齐全


  • 吸取了Angular(模块化) 和React(虚拟DOM) 的长处

    , 并拥有自己独特的功能,如:计算属性


  • 开源,社区活跃度高


1.3、前端三要素

  • HTML(结构):超文本标记语言(Hyper Text Markup Language),决定网页的结构和内容

  • CSS(表现):层叠样式表(Cascading Style Sheets),设定网页的表现样式。

  • JavaScript(行为):是一种弱类型脚本语言,其源码不需经过编译,而是由浏览器解释运行,用于控制网页的行为

2.1、第一个Vue程序

2.2、什么是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.js



Anfular JS

2.3、为什么要使用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是指数据模型, 泛指后端进行的各种业务逻辑处理和数据操控, 主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则


  • 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层, 这个解耦是至关重要的, 它是前后端分离方案实施的重要一环。

2.4、第一个Vue程序

【说明】IDEA可以安装Vue的插件!  注意:Vue不支持IE 8及以下版本, 因为Vue使用了IE 8无法模拟的ECMAScript 5特性。但它支持所有兼容ECMAScript 5的浏览器。  可以使用HBuilder编写,效果一样!


  • 下载地址

    • 开发版本

      • 包含完整的警告和调试模式:https://yuejs.org/js/vue.js

      • 删除了警告, 30.96KB min+gzip:https://vuejs.org/js/vue.min.js

    • CDN



      • <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>


  • 代码编写

    ​Vue.js的核心是实现了MVVM模式, 她扮演的角色就是View Model层, 那么所谓的第一个应用程序就是展示她的数据绑定功能,操作流程如下:

  1. 创建一个HTML文件

  2. 引入Vue.js

  3. 创建一个Vue实例

  4. 将数据绑定到页面元素

<!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@2.5.21/dist/vue.min.js"></script>

<script type="text/javascript">
	<!-- 第三步:创建一个Vue实例 -->
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            message:"hello,vue!"
        }
    });
</script>
</body>
</html>

说明:


  • el:#app

    :绑定的是元素的ID


  • data:{message:'Hello Vue!'}

    :数据对象中有一个名为message的属性,并设置了初始值 Hello Vue!

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


测试:

为了能够更直观的体验Vue带来的数据绑定功能, 我们需要在浏览器测试一番, 操作流程如下:

1、在浏览器上运行第一个Vue应用程序, 进入开发者工具

2、在控制台输入vm.message=‘HelloWorld’, 然后回车, 你会发现浏览器中显示的内容会直接变成HelloWorld

此时就可以在控制台直接输入vm.message来修改值, 中间是可以省略data的, 在这个操作中, 我并没有主动操作DOM, 就让页面的内容发生了变化, 这就是借助了Vue的数据绑定功能实现的; MV VM模式中要求View Model层就是使用观察者模式来实现数据的监听与绑定, 以做到数据与视图的快速响应。

2.5、基础语法命令


以下所有基础语法代码均省略HTML代码


v-if-else

判断,多重判断

<!--view层,模板-->
<div id="app">
    <span v-if="number === 1">時間学vue 难</span>
    <span v-else-if="number ===  2">時間学vue 一般</span>
    <span v-else-if="number ===  3">時間学vue 简单</span>
    <span v-else>時間学vue 保持沉默</span>
</div>
<!-- 引入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script>
    <!-- 创建一个vue实例-->
    var vm = new Vue({
        el : "#app",
        data : {
            number : 2
        }
    });
</script>


v-for

循环

<!--view层,模板-->
<div id="app">
    <h1 v-for="it in items">
        {{it.message}}
    </h1>
</div>
<!-- 引入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script>
    <!-- 创建一个vue实例-->
    var vm = new Vue({
        el : "#app",
        data : {
            items :[
                {message : "時間学Java1"},
                {message : "時間学前端2"},
                {message : "時間学运维3"},
            ]
        }
    });
</script>


v-on

监听事件



v-on:click="hello"

给hello函数绑定一个单击事件

<button id="btn" v-on:click="sayHi">Click Me</button>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script>
    var vm = new Vue({
        el : "#btn",
        data: {},
        methods : {
            sayHi : function () {
                alert("hello vue !");
            }
        }
    });
</script>


v-model

双向数据绑定


v-model

会忽略所有表单元素的

value



checked



selected

attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的

data

选项中声明初始值。


v-model

在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用

    value

    property 和

    input

    事件;

  • checkbox 和 radio 使用

    checked

    property 和

    change

    事件;

  • select 字段将

    value

    作为 prop 并将

    change

    作为事件。

<div id="text">
    文本框:<input type="text" v-model="message"> {{message}}
    <p />
    单选框:
    <input type="radio" name="gender" value="男" v-model="radioMessage">男
    <input type="radio" name="gender" value="女" v-model="radioMessage">女
    我的性别是:{{radioMessage}}
    <p />
    复选框:
    <input type="checkbox" value="西瓜" v-model="checkFlag">西瓜
    <input type="checkbox" value="苹果" v-model="checkFlag">苹果
    <input type="checkbox" value="哈密瓜" v-model="checkFlag">哈密瓜
    <input type="checkbox" value="桃子" v-model="checkFlag">桃子
    我喜欢的水果是:{{checkFlag}}
    <p />
    下拉框:
    <select v-model="selectMessage">
        <option value="" disabled>--请选择--</option>
        <option value="中国">中国</option>
        <option value="美国">美国</option>
    </select>
    我所在的国度是:{{selectMessage}}

    <p />
    文本域:<textarea v-model="textareaMessage"></textarea>
    我输入的内容是:<textarea>{{textareaMessage}}</textarea>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script>
    var vm = new Vue({
        el : "#text",
        data : {
            message : "hello vue !",
            radioMessage : "",
            checkFlag : [],
            selectMessage : "",
            textareaMessage : ""
        }
    });
</script>


v-component

组件

什么是组件?

组件是可复用的

Vue

实例, 说白了就是一组可以重复使用的模板, 跟

JSTL

的自定义标签、

Thymeleal



th:fragment

等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织:

注意:在实际开发中,我们并不会用以下方式开发组件,而是采用

vue-cli

创建,

vue

模板文件的方式开发,以下方法只是为了让大家理解什么是组件。

<div id="text">
    <zfc v-for="item in items" v-bind:message="item"></zfc>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script>
    Vue.component("zfc",{
        props:['message'],
        template:"<li>{{message}}</li>",
    });
    new Vue({
        el : "#text",
        data : {
            items : ["時間学vue","時間学前端","時間学后端"]
        }
    });
</script>

说明:


  • Vue.component()

    :注册组件


  • zfc

    :自定义组件的名字


  • template

    :组件的模板


  • 默认规则下props属性里的值不能为大写


  • v-for="item in items"

    :遍历

    Vue

    实例中定义的名为

    items

    的数组,并创建同等数量的组件


  • v-bind:message="item"

    :将遍历的

    item

    项绑定到组件中

    props

    定义名为

    item

    属性上;= 号左边的

    message



    props

    定义的属性名,右边的为

    item in items

    中遍历的item项的值

3.1、Axios异步通信

3.2、什么是Axios?

​ Axios是一个开源的可以在浏览器端和

Node Js

的异步通信框架,它的主要作用就是实现Ajax异步通信。

3.3、特性

  • 从浏览器中创建

    XMLHttpRequests

  • 从 node.js 创建

    http

    请求

  • 支持

    Promise

    API

  • 拦截请求和响应

  • 转换请求数据和响应数据

  • 取消请求

  • 自动转换 JSON 数据

  • 客户端支持防御

    XSRF

GitHub:

GitHub – axios/axios: Promise based HTTP client for the browser and node.js

中文文档:

axios中文网|axios API 中文文档 | axios

3.4 为什么要用Axios?

​ 由于

vue.js

是一个视图层的框架并且作者(尤雨溪)严格遵守

SoC(关注度分离原则)

所以

vue.js

并不包含Ajax的通信功能,为了解决通信问题,作者单独开发了一个名为

vue-resource

的插件,不过在2.0版本后停止了对该插件的维护并推荐了

Axios

框架。少用jQuery,因为他操作DOM太繁琐了!

3.5、第一个Axiox程序

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

{
  "name": "時間学Java",
  "url": "https://blog.csdn.net/qq_54027065",
  "address": {
    "country": "中国"
    "city": "湖南益阳"
  },
  "links": [
    {
      "name": "時間学Java",
      "url": "https://blog.csdn.net/qq_54027065"
    },
    {
      "name": "bilibili",
      "url": "https://space.bilibili.com/95256449"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}


测试代码

<div id="vue">
    <div>姓名:{{info.name}}</div>
    <div>地址:{{info.address.country}} - {{info.address.city}} - {{info.address.street}}</div>
    <div>
        <a v-bind:href="info.url">{{info.url}}</a>
    </div>
    <div>
        <li v-for="link in info.links">{{link.name}}
            <font color="red">-</font>
            <a v-bind:href="link.url">{{link.url}}</a>
        </li>
    </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>
    var vm = new Vue({
        el : "#vue",
        data(){
            return{
                info : {
                    name : null,
                    address:{
                        city: null,
                        country: null
                    },
                    url : null,
                    links : [
                        {
                            name : null,
                            url : null,
                        },
                    ]
                }
            }
        },
        mounted(){//钩子函数
            axios
                .get("./data.json")
                .then((response) => (this.info = response.data));
       }
    });
</script>

说明:

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

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

  3. 我们在data中的数据结构必须和

    Ajax

    响应回来的数据格式匹配!

3.4、Vue的声明周期

官方文档:

生命周期图示

​         Vue实例有一个完整的生命周期,也就是从开始创建初女台化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。

4.1、计算属性、内容分发、自定义事件

4.2、什么是计算属性?

​         计算属性的重点突出在


属性


两个字上(属性是名词),首先它是个


属性


其次这个属性有


计算


的能力(计算是动词),这里的


计算


就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
    <p>currentTime1:{{currentTime1()}}</p>
    <p>currentTime2:{{currentTime2}}</p>
</div>

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
          message:"me"
        },
        methods:{
            currentTime1:function(){
                return Date.now();//返回一个时间戳
            }
        },
        computed:{
            currentTime2:function(){
              	//计算属性:methods,computed方法名不能重名,重名之后,只会调用methods的方法
                this.message;
                return Date.now();//返回一个时间戳
            }
        }
    });
</script>
</body>
</html>


注意:methods和computed里的东西不能重名

说明:

  • methods:定义方法, 调用方法使用currentTime1(), 需要带括号

  • computed:定义计算属性, 调用属性使用currentTime2, 不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化


结论:

调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,

计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。

4.3、内容分发



Vue.js

中我们使用

<slot>

元素作为承载分发内容的出口,作者称其为

插槽

,可以应用在组合组件的场景中;


第一步:定义一个待办事项的组件(todo)


第二步 我们需要让,代办事项的标题和值实现动态绑定,怎么做呢?我们可以留一个插槽!

  • 接着定义一个名为todo-title的待办标题组件 和 todo-content的待办内容组件

  • 实例化Vue并初始化数据

  • 将值,通过插槽插入

<!--view层,模板-->
<div id="vue">
    <doto>
        <doto-title slot="doto-title" v-bind:title="title"></doto-title>
        <doto-content slot="doto-content" v-for="(c,index) in all" 
          v-bind:content="c,index"></doto-content>
    </doto>
</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>
    Vue.component("doto",{
        template : "<div>\
                        <slot name='doto-title'></slot>\
                        <ul>\
                            <slot name='doto-content'></slot>\
                        </ul>\
                    </div>"
    });

    Vue.component("doto-title",{
        props:["title"],
        template: "<h1>{{title}}</h1>"
    });

	//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
    Vue.component("doto-content",{
        props:["content","index"],
        template: "<li>{{content}} -- {{index}}</li>"
    })

    new Vue({
        el : "#vue",
        data:{
            title:"時間学习路线",
            all:["時間学后端","時間学前端","時間学Linux"]
        }
    });
</script>

4.4、自定义事件

​ 不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称


this.$emit(‘自定义事件名’, 参数)


对上一个代码进行修改,实现删除功能

  • 在vue的实例中增加了methods对象并定义了一个名为byIndexRemove的方法

  • 修改todo-content待办内容组件的代码,增加一个删除按钮,并且绑定单击事件!

  • 修改todo-content待办内容组件的HTML代码,增加一个自定义事件,比如叫remove,可以和组件的方法绑定,然后绑定到vue的方法!

<!--view层,模板-->
<div id="vue">
    <doto>
        <doto-title slot="doto-title" v-bind:title="title"></doto-title>
        <doto-content slot="doto-content" v-for="(c,index) in all" 
          v-bind:content="c,index"></doto-content>
    </doto>
</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>
    Vue.component("doto",{
        template : "<div>\
                        <slot name='doto-title'></slot>\
                        <ul>\
                            <slot name='doto-content'></slot>\
                        </ul>\
                    </div>"
    });

    Vue.component("doto-title",{
        props:["title"],
        template: "<h1>{{title}}</h1>"
    });

	//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
    Vue.component("doto-content",{
        props:["content","index"],
        template: "<li>{{content}} -- {{index}}</li>"
    })

    new Vue({
        el : "#vue",
        data:{
            title:"時間学习路线",
            all:["時間学后端","時間学前端","時間学Linux"]
        }
    });
</script>

5.1、vue小结

核心:数据驱动,组件化

优点:借鉴了AngularJS的模块化开发和React的虚拟Dom,虚拟Dom就是把Demo操作放到内存中执行;

常用的属性:

  • v-if

  • v-else-if

  • v-else

  • v-for

  • v-on绑定事件,简写@

  • v-model数据双向绑定

  • v-bind给组件绑定参数,简写 :

组件化:

  • 组合组件slot插槽

  • 组件内部绑定事件需要使用到

    this.$emit("事件名",参数);

  • 计算属性的特色,缓存计算数据

遵循SoC关注度分离原则,Vue是纯粹的视图框架,并不包含,比如Ajax之类的通信功能,为了解决通信问题,我们需要使用Axios框架做异步通信;


说明

Vue的开发都是要基于NodeJS,实际开发采用Vue-cli脚手架开发,vue-router路由,vuex做状态管理;Vue UI,界面我们一般使用ElementUI(饿了么出品),或者ICE(阿里巴巴出品)来快速搭建前端项目~

官网:


Element – The world’s most popular Vue UI framework


飞冰-基于 React 的研发解决方案 | 飞冰

6.1、第一个vue-cli项目

6.2、什么是vue-cli?

vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板;

预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速;


项目的功能

  • 统一的目录结构

  • 本地调试

  • 热部署

  • 单元测试

  • 集成打包上线

6.3、需要的环境

Node.js:

下载 | Node.js 中文网

安装就是无脑的下一步就好,安装在自己的环境目录下

Git:

https://git-scm.com/doenloads

镜像:

CNPM Binaries Mirror


确认nodejs安装成功:

  • cmd下输入

    node -v

    ,查看是否能够正确打印出版本号即可!

  • cmd下输入

    npm -v

    ,查看是否能够正确打印出版本号即可!


安装Node.js淘宝镜像加速器(cnpm)— 这样的话,下载会快很多~

# -g 就是全局安装
npm install cnpm -g

# 或使用如下语句解决npm速度慢的问题
npm install --registry=https://registry.npm.taobao.org

安装的位置:

C:\Users\administrator\AppData\Roaming\npm


安装vue-cli

cnpm instal1 vue-cli-g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list

6.4、第一个vue-cli程序

  1. 创建一个Vue项目,随便建立一个空的文件夹在电脑上。

  2. 创建一个基于webpack模板的vue应用程序

    #1、首先需要进入到对应的目录 cd D:\Project\vue-study
    #2、这里的myvue是顶日名称,可以根据自己的需求起名
    vue init webpack myvue


    一路都选择no即可;


说明:

  • Project name:项目名称,默认回车即可

  • Project description:项目描述,默认回车即可

  • Author:项目作者,默认回车即可

  • Install vue-router:是否安装vue-router,选择n不安装(后期需要再手动添加)

  • Use ESLint to lint your code:是否使用ESLint做代码检查,选择n不安装(后期需要再手动添加)

  • Set up unit tests:单元测试相关,选择n不安装(后期需要再手动添加)

  • Setupe2etests with Nightwatch:单元测试相关,选择n不安装(后期需要再手动添加)

  • Should we run npm install for you after the,project has been created:创建完成后直接初始化,选择n,我们手动执行;运行结果!

一、初始化并运行

cd myvue
npm install
npm run dev

执行完成后,目录多了很多依赖。

7.1、webpack使用

7.2、什么是Webpack?

​         webpack 是代码编译工具,有入口、出口、loader 和插件。webpack 是一个用于现代

JavaScript

应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个

bundle

7.3、安装Webpack

​         WebPack是一款模块加载器兼打包工具, 它能把各种资源, 如JS、JSX、ES 6、SASS、LESS、图片等都作为模块来处理和使用。

npm install webpack -g
npm install webpack-cli -g

测试安装成功



  • webpack -v



  • webpack-cli -v

成功就会显示版本信息,否则就是安装失败!

7.4、使用WebPack

(1)创建项目,直接中新建一个文件夹,然后用idea打开即可

(2)创建一个名为modules的目录,用于放置JS模块等资源文件

(3)在modules下创建模块文件,如hello.js,用于编写JS模块相关代码

//暴露一个方法:sayHi
    exports.sayHi = function(){
        document.write("<div>Hello Webpack</div>");
    }

(4)在modules下创建一个名为main.js的入口文件,用于打包时设置entry属性

//require 导入一个模块,就可以调用这个模块中的方法了
var hello = require("./hello")
hello.sayHi()

(5)在项目目录下创建webpack.config.js配置文件,使用idea终端用

webpack

命令打包

module.exports = {
    entry:"./modules/main.js",
    output:{
        filename:"./js/bundle.js"
    }
}

(6)在项目目录下创建HTML页面,如index.html,导入webpack打包后的JS文件

<!doctype html>
	<html lang="en">
		<head>
			<meta charset="UTF-8">
			<title>title</title>
		</head>
		<body>
			<script src="dist/js/bundle.js"></script>
		</body>
	</html>

注意:

  • 在IDEA控制台中直接执行webpack;如果失败的话,就使用管理员权限运行即可!

  • 运行HTML看效果

说明:

# 参数--watch 用于监听变化
webpack --watch

8.1、vue-router路由

8.2、什么是vue-router?

​         Vue Router 是

Vue.js

官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。路由实际上就是可以理解为指向,就是我在页面上点击一个按钮需要跳转到对应的页面,这就是路由跳转;

首先我们来学习三个单词(route,routes,router):


route:

首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;


routes:

它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;


router:

译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由。

中文文档:

Vue Router

8.3、安装


基于第一个vue-cli进行测试学习; 先查看项目中node_modules文件夹中是否存在vue-router

​ vue-router是一个插件包,所以我们还是需要用npm/cnpm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。

npm install vue-router --save-dev

如果在一个模块化工程中使用它,必须要通过Vue.use()明确地安装路由功能:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

8.4、测试

(1)先删除没有用的东西

(2)

components

目录下存放我们自己编写的组件

(3)定义一个

Content.vue

的组件

<template>
    <div>
        <h1>内容页</h1>
    </div>
</template>
​
<script>
    export default {
        name:"Content"
    }
</script>

(4)

Main.vue

组件

<template>
    <div>
        <h1>首页</h1>
    </div>
</template>
​
<script>
    export default {
        name:"Main"
    }
</script>

(5)安装路由,在src目录下,新建一个文件夹:

router

,专门存放路由,配置路由

index.js

,如下

import Vue from'vue'
//导入路由插件
import Router from 'vue-router'
//导入上面定义的组件
import Content from '../components/Content'
import Main from '../components/Main'
//安装路由
Vue.use(Router) ;
//配置路由
export default new Router({
    routes:[
        {
            //路由路径
            path:'/content',
            //路由名称
            name:'content',
            //跳转到组件
            component:Content
            },{
            //路由路径
            path:'/main',
            //路由名称
            name:'main',
            //跳转到组件
            component:Main
            }
        ]
    });

(6)在

main.js

中配置路由

import Vue from 'vue'
import App from './App'
​
//导入上面创建的路由配置目录
import router from './router'//自动扫描里面的路由配置
​
//来关闭生产模式下给出的提示
Vue.config.productionTip = false;
​
new Vue({
    el:"#app",
    //配置路由
    router,
    components:{App},
    template:'<App/>'
});

(7)在

App.vue

中使用路由

<template>
    <div id="app">
        <!--
            router-link:默认会被渲染成一个<a>标签,to属性为指定链接
            router-view:用于渲染路由匹配到的组件
        -->
        <router-link to="/">首页</router-link>
        <router-link to="/content">内容</router-link>
        <router-view></router-view>
    </div>
</template>
​
<script>
    export default{
        name:'App'
    }
</script>

9.1、小练习

​ 结合ElementUI组件库掌握Vue的使用。

9.2、创建项目


注意:命令行都要使用管理员模式运行

1、创建一个名为hello-vue的工程


vue init webpack hello-vue

2、安装依赖, 我们需要安装

vue-router



element-ui



sass-loader



node-sass

四个插件

#进入工程目录
cd hello-vue
#安装vue-router 
npm install vue-router --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
# 安装SASS加载器
cnpm install sass-loader node-sass --save-dev
#启功测试
npm run dev

3、Npm命令解释:

  • npm install moduleName:安装模块到项目目录下

  • npm install -g moduleName:-g的意思是将模块安装到全局,具体安装到磁盘哪个位置要看npm config prefix的位置

  • npm install -save moduleName:–save的意思是将模块安装到项目目录下, 并在package文件的dependencies节点写入依赖,-S为该命令的缩写

  • npm install -save-dev moduleName:–save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写

9.4、创建登录页面

在src目录中创建如下 结构:

  • assets:用于存放资源文件

  • components:用于存放Vue功能组件

  • views:用于存放Vue视图组件

  • router:用于存放vue-router配置

(1)

创建首页视图,在views目录下创建一个名为Main.vue的视图组件:

<template>
	<div>Main</div>
</template>
<script>
	export default {
			name:"Main"
	}
</script>
<style scoped>
</style>

(2)创建登录页视图在views目录下创建名为Login.vue的视图组件,其中el-*的元素为ElementUI组件;

<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>

    <el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "Login",
  data(){
    return{
      form:{
        username:'',
        password:''
      },
      //表单验证,需要在 el-form-item 元素中增加prop属性
      rules:{
        username:[
          {required:true,message:"账号不可为空",trigger:"blur"}
        ],
        password:[
          {required:true,message:"密码不可为空",tigger:"blur"}
        ]
      },

      //对话框显示和隐藏
      dialogVisible:false
    }
  },
  methods:{
    onSubmit(formName){
      //为表单绑定验证功能
      this.$refs[formName].validate((valid)=>{
        if(valid){
          //使用vue-router路由到指定界面,该方式称为编程式导航
          this.$router.push('/main');
        }else{
          this.dialogVisible=true;
          return false;
        }
      });
    }
  }
}
</script>

<style lang="scss" scoped>
.login-box{
  border:1px solid #DCDFE6;
  width: 350px;
  margin:180px auto;
  padding: 35px 35px 15px 35px;
  border-radius: 5px;
  box-shadow: 0 0 25px #909399;
}
.login-title{
  text-align:center;
  margin: 0 auto 40px auto;
  color: #303133;
}
</style>
(3)APP.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'App',
}
</script>

(4)main.js

import Vue from 'vue'
import App from './App'
import router from "./router";

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)
Vue.use(router)

new Vue({
  el: '#app',
  router,
  render:h=>h(App)
})

(5)测试

9.5、路由嵌套

嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。

(1) 创建用户信息组件,在 views/user 目录下创建一个名为 Profile.vue 的视图组件。

<template>
  <h1>Profile</h1>
</template>
<script>
  export default {
    name: "Profile"
  }
</script>
<style scoped>
</style>

(2)在用户列表组件在 views/user 目录下创建一个名为 List.vue 的视图组件。

<template>
  <h1>List User</h1>
</template>
<script>
  export default {
    name: "List"
  }
</script>
<style scoped>
</style>

(3)修改首页视图,我们修改 Main.vue 视图组件,此处使用了 ElementUI 布局容器组件,代码如下:

<template>
    <div>
      <el-container>
        <el-aside width="200px">
          <el-menu :default-openeds="['1']">
            <el-submenu index="1">
              <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
              <el-menu-item-group>
                <el-menu-item index="1-1">
                <!--插入的地方-->
                  <router-link to="/user/profile">个人信息</router-link>
                </el-menu-item>
                <el-menu-item index="1-2">
                <!--插入的地方-->
                  <router-link to="/user/list">用户列表</router-link>
                </el-menu-item>
              </el-menu-item-group>
            </el-submenu>
            <el-submenu index="2">
              <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
              <el-menu-item-group>
                <el-menu-item index="2-1">分类管理</el-menu-item>
                <el-menu-item index="2-2">内容列表</el-menu-item>
              </el-menu-item-group>
            </el-submenu>
          </el-menu>
        </el-aside>

        <el-container>
          <el-header style="text-align: right; font-size: 12px">
            <el-dropdown>
              <i class="el-icon-setting" style="margin-right: 15px"></i>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>个人信息</el-dropdown-item>
                <el-dropdown-item>退出登录</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </el-header>
          <el-main>
          <!--在这里展示视图-->
            <router-view />
          </el-main>
        </el-container>
      </el-container>
    </div>
</template>
<script>
    export default {
        name: "Main"
    }
</script>
<style scoped lang="scss">
  .el-header {
    background-color: #B3C0D1;
    color: #333;
    line-height: 60px;
  }
  .el-aside {
    color: #333;
  }
</style>

(4)配置嵌套路由修改 router 目录下的 index.js 路由配置文件,使用children放入main中写入子模块。

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//导入子模块
import List from "../views/user/List";
import Profile from "../views/user/Profile";

//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
      //登录页
      path: '/main',
      component: Main,
      //  写入子模块
      children: [
        {
          path: '/user/profile',
          component: Profile,
        }, {
          path: '/user/list',
          component: List,
        },
      ]
    },
    //首页
    {
      path: '/login',
      component: Login
    }
  ]
})

(5)测试

9.6、传递参数

第一种取值方式

(1)修改路由配置, 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符

{
	path: '/user/profile/:id', 
	name:'Profile', 
	component: Profile
}

(2)此时我们在Main.vue中的route-link位置处 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径。

<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>

(3)在要展示的组件Profile.vue中接收参数 使用 {

{$route.params.id}}来接收Profile.vue 部分代码

<template>
  <!--  所有的元素必须在根节点下-->
  <div>
    <h1>个人信息</h1>
    {{$route.params.id}}
  </div>
</template>

第二种取值方式    使用props 减少耦合

  • 修改路由配置 , 主要在router下的index.js中的路由属性中增加了 props: true 属性

{
	path: '/user/profile/:id', 
	name:'Profile', 
	component: Profile, 
	props: true
}
  • 传递参数和之前一样 在Main.vue中修改route-link地址

<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'Profile',params:{id:1}}">个人信息</router-link>
  • 在Profile.vue接收参数为目标组件增加 props 属性

<template>
  <div>
    个人信息
    {{ id }}
  </div>
</template>
<script>
    export default {
      props: ['id'],
      name: "Profile"
    }
</script>
<style scoped>
</style>

9.7、组件重定向

重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:

{
  path: '/main',
  name: 'Main',
  component: Main
},
{
  path: '/goHome',
  redirect: '/main'
}

说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件。

使用的话,只需要在Main.vue设置对应路径即可。

<el-menu-item index="1-3">
    <router-link to="/goHome">回到首页</router-link>
</el-menu-item>

9.8、路由模式与 404

路由模式有两种

修改路由配置,代码如下:

export default new Router({
  mode: 'history',
  routes: [
  ]
});


404

1.创建一个NotFound.vue视图组件

<template>
    <div>
      <h1>找不到也面了哦,快叫你的程序猿来修复吧</h1>
    </div>
</template>
<script>
    export default {
        name: "NotFound"
    }
</script>
<style scoped>
</style>

2.修改路由配置index.js

import NotFound from '../views/NotFound'
{
   path: '*',
   component: NotFound
}


路由钩子与异步请求

  • beforeRouteEnter:在进入路由前执行

  • beforeRouteLeave:在离开路由前执行

在Profile.vue中写

  export default {
    name: "Profile",
    beforeRouteEnter: (to, from, next) => {
      console.log("进入 --> go");
      next();
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("离开个 --> out");
      next();
    }
  }

参数说明:

  • to:路由将要跳转的路径信息

  • from:路径跳转前的路径信息

  • next:路由的控制参数

  • next() 跳入下一个页面

  • next(’/path’) 改变路由的跳转方向,使其跳到另一个路由

  • next(false) 返回原来的页面

  • next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例


在钩子函数中使用异步请求

(1)安装 Axios

cnpm install --save vue-axios

(2)main.js引用 Axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

(3)准备数据 : 只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。​ 数据和之前用的json数据一样 需要的去上述axios例子里

// 静态数据存放的位置
static/mock/data.json

(4)在 beforeRouteEnter 中进行异步请求

 export default {
    //第二种取值方式
    // props:['id'],
    name: "UserProfile",
    //钩子函数 过滤器
    beforeRouteEnter: (to, from, next) => {
      //加载数据
      console.log("进入 --> go")
      next(vm => {
        //进入路由之前执行getData方法
        vm.getData();
      });
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("离开 --> out")
      next();
    },
    //axios
    methods: {
      getData: function () {
        this.axios({
          method: 'get',
          url: 'http://localhost:8080/static/mock/data.json'
        }).then(function (response) {
          console.log(response)
        })
      }
    }
  }

学习完啦!

  • 本文章通过学习

    狂神说的vue视频

    和结合

    狂神说Vue笔记整理

    总结出来!



版权声明:本文为qq_54027065原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。