教你快速入门Vue

Vue

看完B站狂神的视频,小编获益匪浅,在学习途中记下了这篇文章
小伙伴也可以从B站获取狂神的完整视频哦!
狂神B站主页

在线CDN

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

模块化开发+虚拟DOM

1 前端核心分析

1.1 VUE 概述

Vue (读音/vju/, 类似于view)是一套用于构建用户界面的渐进式框架,发布于2014年2月。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库(如: vue-router: 跳转,vue-resource: 通信,vuex:管理)或既有项目整合

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

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

网络通信 : axios

页面跳转 : vue-router

状态管理:vuex

Vue-UI : ICE , Element UI

1.2 前端三要素

  • HTML (结构) :超文本标记语言(Hyper Text Markup Language) ,决定网页的结构和内容
  • CSS (表现) :层叠样式表(Cascading Style sheets) ,设定网页的表现样式
  • JavaScript (行为) :是一种弱类型脚本语言,其源代码不需经过编译,而是由浏览器解释运行,用于控制网页的行为
1.2.1 结构层

HTML

就是网页的骨架

1.2.2 表现层

CSS

CSS层叠样式表是一门标记语言,并不是编程语言,因此不可以自定义变量,不可以引用等,换句话说就是不具备任何语法支持,它主要缺陷如下:

  • 语法不够强大,比如无法嵌套书写,导致模块化开发中需要书写很多重复的选择器;
  • 没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护;
    这就导致了我们在工作中无端增加了许多工作量。为了解决这个问题,前端开发人员会使用一种称之为【CSS预处理器】的工具,提供CSS缺失的样式层复用机制、减少冗余代码,提高样式代码的可维护性。大大的提高了前端在样式上的开发效率。

于是出现了CSS预处理器

常用的CSS预处理器有哪些

  • SASS:基于Ruby ,通过服务端处理,功能强大。解析效率高。需要学习Ruby语言,上手难度高于LESS。
  • LESS:基于NodeJS,通过客户端处理,使用简单。功能比SASS简单,解析效率也低于SASS,但在实际开发中足够了,所以如果我们后台人员如果需要的话,建议使用LESS。
1.2.3 行为层

JavaScript

JavaScript一门弱类型脚本语言,其源代码在发往客户端运行之前不需要经过编译,而是将文本格式的字符代码发送给浏览器,由浏览器解释运行。

Native 原生JS开发

原生JS开发,也就是让我们按照【ECMAScript】标准的开发方式,简称ES,特点是所有浏览器都支持。截至到当前,ES标准以发布如下版本:

  • ES3
  • ES4(内部,未正式发布)
  • ES5(全浏览器支持)
  • ES6(常用,当前主流版本:webpack打包成为ES5支持)
  • ES7
  • ES8
  • ES9(草案阶段)

区别就是逐步增加新特性。
TypeScript 微软的标准
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集, 而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。由安德斯·海尔斯伯格(C#、Delphi、TypeScript之父; .NET创立者) 主导。该语言的特点就是除了具备ES的特性之外还纳入了许多不在标准范围内的新特性,所以会导致很多浏览器不能直接支持TypeScript语法, 需要编译后(编译成JS) 才能被浏览器正确执行。

JavaScript框架

  • JQuery:大家熟知的JavaScript库,优点就是简化了DOM操作,缺点就是DOM操作太频繁,影响前端性能;在前端眼里使用它仅仅是为了兼容IE6,7,8;
  • Angular:Google收购的前端框架,由一群Java程序员开发,其特点是将后台的MVC模式搬到了前端并增加了模块化开发的理念,与微软合作,采用了TypeScript语法开发;对后台程序员友好,对前端程序员不太友好;最大的缺点是版本迭代不合理(如1代–>2 代,除了名字,基本就是两个东西;截止发表博客时已推出了Angular6)
  • React:Facebook 出品,一款高性能的JS前端框架;特点是提出了新概念 【虚拟DOM】用于减少真实 DOM 操作,在内存中模拟 DOM操作,有效的提升了前端渲染效率;缺点是使用复杂,因为需要额外学习一门【JSX】语言;
  • Vue:一款渐进式 JavaScript 框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了 Angular(模块化)和React(虚拟 DOM) 的优点;
  • Axios:前端通信框架;因为 Vue 的边界很明确,就是为了处理 DOM,所以并不具备通信能力,此时就需要额外使用一个通信框架与服务器交互;当然也可以直接选择使用jQuery 提供的AJAX 通信功能;

1.3 前端技术

1.3.1 UI框架
  • Ant-Design:阿里巴巴出品,基于React的UI框架
  • ElementUI、iview、ice:饿了么出品,基于Vue的UI框架
  • BootStrap:Teitter推出的一个用于前端开发的开源工具包
  • AmazeUI:又叫“妹子UI”,一款HTML5跨屏前端框架
1.3.2 JavaScript构建工具
  • Babel:JS编译工具,主要用于浏览器不支持的ES新特性,比如用于编译TypeScript
  • WebPack:模块打包器,主要作用就是打包、压缩、合并及按序加载

注:以上知识点已将WebApp开发所需技能全部梳理完毕

1.3.3 三端合一

混合开发(Hybrid App)

主要目的是实现一套代码三端统一(PC、Android:.apk、iOS:.ipa)并能够调用到设备底层硬件(如:传感器、GPS、摄像头等),打包方式主要有以下两种:

  • 云打包:HBuild -> HBuildX,DCloud 出品;API Cloud
  • 本地打包: Cordova(前身是 PhoneGap)

微信小程序

详见微信官网,这里就是介绍一个方便微信小程序UI开发的框架:WeUI

1.3.4 后端技术

前端人员为了方便开发也需要掌握一定的后端技术但我们Java后台人员知道后台知识体系极其庞大复杂,所以为了方便前端人员开发后台应用,就出现了Node JS这样的技术。Node JS的作者已经声称放弃Node JS(说是架构做的不好再加上笨重的node modules,可能让作者不爽了吧)开始开发全新架构的De no
既然是后台技术,那肯定也需要框架和项目管理工具, Node JS框架及项目管理工具如下:

  • Express:Node JS框架
  • Koa:Express简化版
  • NPM:项目综合管理工具,类似于Maven
  • YARN:NPM的替代方案,类似于Maven和Gradle的关系

2 MVVM

2.1 什么是MVVM

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zFMJDVqP-1631334308776)(E:\学习文件\JAVA学习\学习记录\前端\imgs\image-20210819212331520.png)]

2.2 为什么要使用MVVM

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

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

2.3 Vue 是 MVVM 模式的实现者

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zvyXxOzY-1631334308778)(E:\学习文件\JAVA学习\学习记录\前端\imgs\image-20210819212639580.png)]

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

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

  • ViewModel : 连接视图和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者

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

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

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

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <!--view层 模板-->
    <div id="app">
        <h1 id="mvvm">{{message}}</h1>
    </div>
    </body>

    <!--导入js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                //model
                message: "Hello,Vue!"
            }
        })
    </script>
</html>

3 Vue基础语法

3.1 条件

注意数组和对象的定义

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>基础语法</title>
    </head>
    <body>
    <div id="app">
        <h1 title="我也可以">这样呢?</h1>
        
        <h1 v-bind:title="bind">悬停查看</h1>

        <b v-if="ifBody=='A'">后台数据是A</b>
        <b v-else>后台数据不是A</b>

        <p v-for="item in items">
            {{item.message}}
        </p>
    </div>
    </body>

    <!--导入js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                bind: "这是一个隐藏绑定的title标签",
                ifBody: "A",
                items: [
                    {message: "Java"},
                    {message: "MySql"},
                    {message: "Python"},
                    {message: "C"},
                    {message: "C++"},
                    {message: "Matlab"}
                ]
            }
        })
    </script>
</html>

3.2 事件

注意:

  • methods不是method
  • 注意作用域
<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>绑定事件</title>
    </head>
    <body>
    <div id="app">
        <button v-on:click="Hi()">Click me</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data:{message:"Hello,Java Designer!"},
            methods: {
                Hi:function () {
                    alert(this.message)
                }
            }
        });
    </script>
    </body>
</html>

4 双向绑定

4.1 什么是双向绑定

Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue.js的精髓之处了。

值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。

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

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

  • 在全局性数据流使用单项,方便跟踪

  • 局部性数据流使用双向,简单易操作

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

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

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

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>双向绑定</title>
    </head>
    <body>


    <div id="app">
        <input type="text" v-model="input">{{input}}<br>
<!--        还有文本域-->
        性别:<input type="radio" name="sex" value="" v-model="sex"><input type="radio" name="sex" value="">女
        {{sex}}<br>

        领域:<select name="area" v-model="select">
        <option value="Java">Java</option>
        <option value="Python">Python</option>
        <option value="Go">Go</option>
        </select>
        {{select}}<br>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data:{
                input: "",
                sex: "",
                select: ""
            }
        });
    </script>
    </body>
</html>

5 组件

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

    <div id="app">
<!--        使用这个组件,我们就必须要为它传递参数(使用v-bind:参数名="被绑定key")-->
        <get-items v-for="item in items" v-bind:each="item" :head="ui"></get-items>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        Vue.component("getItems",{
            //定义了一个组件,它的结构是template,它的参数有each和head
            props:{
                each: Number,
                head:String
            },
//注意template的整体是一个标签,不能定义两个,这就是为什么要在外面嵌套一个div的原因
            template:`<div>
                <span>{{head}}</span>
                <li>{{each}}</li>
            </div>`
        })
        var vm = new Vue({
            el: "#app",
            data:{
                items: ["Java","Go","Python"],
                ui:"领域"
            }
        });
    </script>
    </body>
</html>

使用模板传递参数有三种

  • 使用v-bind:参数名=“被绑定key”
  • :参数名=“被绑定key”
  • 参数名:“自定义参数”

6 Axios

虚拟DOM版的Ajax

6.1 什么是Axios

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

  • 从浏览器中创建XMLHttpRequests

  • 从node.js创建http请求

  • 支持Promise API [JS中链式编程]

  • 拦截请求和响应

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

  • 取消请求

  • 自动转换JSON数据

  • 客户端支持防御XSRF (跨站请求伪造)

GitHub: https://github.com/axios/axios

中文文档: http://www.axios-js.com/

6.2 为什么要使用Axios

由于Vue.js是一个视图层框架且作者(尤雨溪) 严格准守SoC (关注度分离原则),所以Vue.js并不包含Ajax的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource的插件,不过在进入2.0 版本以后停止了对该插件的维护并推荐了Axios 框架。少用jQuery,因为它操作Dom太频繁 !

6.3 使用

Json数据

{
  "name": "狂神说java",
  "url": "http://baidu.com",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "含光门",
    "city": "陕西西安",
    "country": "中国"
  },
  "links": [
    {
      "name": "B站",
      "url": "https://www.bilibili.com/"
    },
    {
      "name": 4399,
      "url": "https://www.4399.com/"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}

导入Vue和Axios的在线cdn

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<!--导入axios-->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Axios</title>
    </head>
    <body>
    <div id="vue">
        <div>{{info.name}}</div>
        <a v-bind:href="info.url">点我进入</a>
    </div>

    <!--1.导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <!--导入axios-->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        var vm = new Vue({
            el: "#vue",
            data: {
                items: ['Java','Python','Php']
            },
            //data:vm的属性
            //data():vm方法
            data(){
                return{
                    //请求的返回参数,必须和json字符串一样
                    info:{
                        name: null,
                        age: null,
                        sex: null,
                        url: null,
                        address: {
                            street: null,
                            city: null,
                            country: null
                        }
                    }
                }
            },
            //钩子函数,链式编程,ES6新特性
            mounted(){
                axios.get("6.axios.json").then(res => (this.info=res.data))
            }
        })
    </script>
    </body>
</html>

7 计算属性

计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数

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

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>计算属性</title>
    </head>
    <body>

    <div id="app">
        <h1>{{method1()}}</h1>
        <h1>{{method2}}</h1>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{},
            methods:{
                method1:function () {
                    return Date.now();
                }
            },
            computed:{
                method2:function () {
                    return Date.now();
                }
            }
        })
    </script>
    </body>
</html>

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

8 插槽

slot就是为了给我们的自定义组件传递参数的,预留空间

官方文档:如果 <todo-button> 的 template 中没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>插槽</title>
    </head>
    <body>
    <div id="app">
        <todo>
            <todo-title slot="todo-title" :title="title"></todo-title>
            <todo-body slot="todo-body" v-for="item in items" :item="item"></todo-body>
        </todo>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script>
        Vue.component("todo",{
            props:{

            },
            template:`
            <div>
                <slot name="todo-title"></slot>
                <ul>
                    <slot name="todo-body"></slot>
                </ul>
            </div>
            `
        })
        Vue.component("todo-title",{
            props: {
                title: String
            },
            template:`
            <h1>{{title}}</h1>
            `
        })
        Vue.component("todo-body",{
            props: {
                item: String
            },
            template: `<li>{{item}}</li>`
        })

        var vm = new Vue({
            el:"#app",
            data:{
                title: "领域",
                items: ["Java","Python","Go"]
            }
        })
    </script>
    </body>
</html>

9 自定义事件

<!--        在插槽的基础上进行绑定事件-->
<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>自定义事件</title>
    </head>
    <body>
    <!DOCTYPE html>
    <html lang="en">
        <head>
        <meta charset="UTF-8">
        <title>插槽</title>
        </head>
        <body>
<!--        在插槽的基础上进行绑定事件-->
        <div id="app">
            <todo>
                <todo-title slot="todo-title" :title="title"></todo-title>
<!--                v-on:remove = "方法名(参数)绑定方法"-->
                <todo-body slot="todo-body" v-for="(item,index) in items" :item="item" v-on:remove = "remove(index)"></todo-body>
            </todo>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
        <script>
            Vue.component("todo",{
                props:{

                },
                template:`
            <div>
                <slot name="todo-title"></slot>
                <ul>
                    <slot name="todo-body"></slot>
                </ul>
            </div>
            `
            })
            Vue.component("todo-title",{
                props: {
                    title: String
                },
                template:`
            <h1>{{title}}</h1>
            `
            })
            Vue.component("todo-body",{
                props: {
                    item: String
                },
                //命名传递方法
                emit:"remove",
                //$emit('传递方法名')来使用传递方法
                template: `<li>{{item}}<button v-on:click="$emit('remove')">删除<button></li>`
            })

            var vm = new Vue({
                el:"#app",
                data:{
                    title: "领域",
                    items: ["Java","Python","Go"]
                },
                methods: {
                    remove: function (index) {
                        this.items.splice(index,1)
                    }
                }
            })
        </script>
        </body>
    </html>
    </body>
</html>

10 Vue-lic

10.1 什么是vue-cli

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

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

主要功能:

  • 统一的目录结构
  • 本地调试
  • 热部署
  • 单元测试
  • 集成打包上线

10.2 需要的环境

  • Node.js : http://nodejs.cn/download/

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

  • Git : https://git-scm.com/downloads
    镜像:https://npm.taobao.org/mirrors/git-for-windows/

确认nodejs安装成功:

  • cmd 下输入 node -v,查看是否能够正确打印出版本号即可!

  • cmd 下输入 npm-v,查看是否能够正确打印出版本号即可!

这个npm,就是一个软件包管理工具,就和linux下的apt软件安装差不多!

npm 是 JavaScript 世界的包管理工具,并且是 Node.js 平台的默认包管理工具。通过 npm 可以安装、共享、分发代码,管理项目依赖关系。

安装 Node.js 淘宝镜像加速器(cnpm)

这样子的话,下载会快很多~

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

# 若安装失败,则将源npm源换成淘宝镜像
# 因为npm安装插件是从国外服务器下载,受网络影响大
npm config set registry https://registry.npm.taobao.org

# 然后再执行
npm install cnpm -g

安装的位置:C:\Users\Administrator\AppData\Roaming\npm

10.3 安装vue-cli

#在命令台输入

cnpm install vue-cli -g

#查看是否安装成功

vue list

10.4 第一个 vue-cli 应用程序

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

我这里在D盘下新建一个目录D:\Project\vue-study;

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

# 这里的 myvue 是项目名称,可以根据自己的需求起名,在目标文件夹下面直接输入代码创建
vue init webpack myvue

一路都选择no即可;

初始化并运行

npm install	//下载依赖
npm run dev	//运行
Ctrl+C		//退出

11 WebPack

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

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

测试安装成功: 输入以下命令有版本号输出即为安装成功

webpack -v
webpack-cli -v

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hZpFFyu-1631334308780)(E:\学习文件\JAVA学习\学习记录\前端\imgs\image-20210822165937770.png)]

暴露一个接口

exports.sayHi=function (msg) {
    alert(msg)
};
exports.message = "Hello,Vue Designer!"

引入这个接口

注意这里使用的是require()

var hello = require("./hello");
hello.sayHi(hello.message);

打包文件配置

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

在dos窗口输入webpack进行打包

然后引入打包后的文件即可

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

12 vue-router路由

注意绑定组件是component不是components

Vue Router是Vue.js官方的路由管理器(路径跳转)。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表

  • 模块化的、基于组件的路由配置

  • 路由参数、查询、通配符

  • 基于Vue.js过渡系统的视图过渡效果

  • 细粒度的导航控制

  • 带有自动激活的CSS class的链接

  • HTML5历史模式或hash模式,在IE9中自动降级

1 安装

基于第一个vue-cli进行测试学习

先查看node_modules中是否存在 vue-router

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

npm install vue-router --save-dev

安装完之后去node_modules路径看看是否有vue-router信息 有的话则表明安装成功。

2 使用

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from "./router/router";

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  //使用router(在内部new了一个vue-router)
  router,
  //在这里就绑定了我们的index.html
  el: '#app',
  //导入Vue组件
  components: { App },
  //结构
  template: `<App/>`
})

index.html

<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>myvue</title>
  </head>
  <body>
  <div id="app"></div>
  <!-- built files will be auto injected -->
  </body>
</html>

App.vue

<template>
  <div id="app">
    <head/>
    <hello/>
    <router-link to="/Java">Java</router-link>
    <router-link to="/Python">Python</router-link>
    <router-link to="/Go">Go</router-link>
    <router-view/>
  </div>
</template>

<script>
import head from "./components/head";

import Head from "./components/head";
export default {
  name: 'App',
  components: {
    head,
    hello: {
      template: `<h1>Hello,Vue Designer!</h1>`
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

router.js

//Vue标配
import Vue from "vue";
import VueRouter from "vue-router";

import Java from "../components/Java";
import Python from "../components/Python";
import Go from "../components/Go";

Vue.use(VueRouter)

export default new VueRouter({
  //里面有一个参数,routes,里面存有数组
  routes: [
    {
      path: "/Java",
      component: Java
    },
    {
      path: "/Python",
      component: Python
    },
    {
      path: "/Go",
      component: Go
    }
  ]
})

Java.vue

<template>
    <h1>Java</h1>
</template>

<script>
    export default {
        name: "Java"
    }
</script>

<style scoped>

</style>

Python.vue

<template>
    <h1>Python</h1>
</template>

<script>
    export default {
        name: "Python"
    }
</script>

<style scoped>

</style>

Go.vue

<template>
    <h1>Go</h1>
</template>

<script>
    export default {
        name: "Go"
    }
</script>

<style scoped>

</style>

13 Vue+ElementUI

问题

cnpm install sass-loader@6 --save-dev
# 创建项目
vue init webpack ElementUI
# 安装依赖
npm install
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装 SASS 加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev	
  • npm install moduleName:安装模块到项目目录下
  • npm install -g moduleName:-g 的意思是将模块安装到全局,具体安装到磁盘的哪个位置,要看 npm config prefix的位置
  • npm install moduleName -save:–save的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖,-S为该命令的缩写
  • npm install moduleName -save-dev:–save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写

创建成功后用idea打开,并删除净东西 创建views和router文件夹用来存放视图和路由


main.js

import Vue from 'vue'
import App from './App'
//扫描路由配置
import router from './conter/conter'
//导入elementUI
import ElementUI from "element-ui"
//导入element css
import 'element-ui/lib/theme-chalk/index.css'

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

new Vue({
  el: '#app',
  router,
  render: h => h(App),//ElementUI规定这样使用
})

App.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>
<script>
  export default {
    name: 'App',
  }
</script>
<style>

</style>

Main.vue

<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 v-bind:to="{name: 'Address', params: {address: '重庆邮电大学'}}">地址</router-link>
              </el-menu-item>
              <el-menu-item index="1-2">
                <!--插入的地方-->
                <router-link to="/username">名字</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>
                <router-link to="/login">用户登录</router-link>
              </el-dropdown-item>
              <el-dropdown-item>退出登录</el-dropdown-item>
            </el-dropdown-menu>
            <span>欢迎,{{username}}</span>
          </el-dropdown>
        </el-header>
        <el-main>
          <!--在这里展示视图-->
          <router-view />
        </el-main>
      </el-container>
    </el-container>
    <el-footer>Footer</el-footer>
  </div>
</template>
<script>
  import Address from "./user/Address";
  export default {
    name: "Main",
    props:{
      username: String
    }
  }
</script>
<style scoped lang="scss">
  .el-header{
    background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
    color: #30784a;
    line-height: 60px;
  }
  .el-aside {
    font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
    color: #333;
  }
  .el-main{
    background-color: white;
  }
  .el-footer{
    background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
    color: #30784a;
    line-height: 60px;
  }
</style>

Login.vue

<template>
  <div class="app">
    <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: '密码不可为空', trigger: 'blur'}
          ]
        },

        // 对话框显示和隐藏
        dialogVisible: false
      }
    },
    methods: {
      onSubmit(formName) {
        // 为表单绑定验证功能
        this.$refs[formName].validate((valid) => {
          if (valid) {
            // 使用 vue-router 路由到指定页面,该方式称之为编程式导航
            this.$router.push("/main/"+this.form.username);
          } 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;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    box-shadow: 0 0 25px #909399;
  }

  .login-title {
    text-align: center;
    margin: 0 auto 40px auto;
    color: #303133;
  }
</style>

Address.vue

<template>
    <h1>地址:{{address}}</h1>
</template>

<script>
    export default {
        name: "Address",
        props: {
          address:String
        }
    }
</script>

<style scoped>

</style>

Username.vue

<template>
    <h1>用户名</h1>
</template>

<script>
    export default {
        name: "Username"
    }
</script>

<style scoped>

</style>

路由配置

import Vue from "vue";
import Router from "vue-router";
import Main from "../view/Main";
import Login from "../view/Login";
import Address from "../view/user/Address";
import Username from "../view/user/Username";

Vue.use(Router);

export default new Router({
  mode: "history",
  routes: [
    {
      path: '/main/:username',
      props:true,
      component: Main,
      //设置嵌套路由
      children: [
        {
          path: "/address/:address",
          props: true,
          name :'Address',
          component: Address
        },
        {
          path: "/username",
          component: Username
        }
      ]
    },
    {
      path: '/login',
      component: Login
    },
    //设置主页面
    {
      path: "/",
      component: Main
    }
  ]
});

14 参数传递

14.1 方法传参

方法后面跟参数

this.$router.push("/main/"+this.form.username);

让路由器接收

{
  path: '/main/:username',
  props:true,
  component: Main,
  //设置嵌套路由
  children: [
    {
      path: "/address/:address",
      props: true,
      name :'Address',
      component: Address
    },
    {
      path: "/username",
      component: Username
    }
  ]
},

使用参数

<span>欢迎,{{username}}</span>
<script>
  import Address from "./user/Address";
  export default {
    name: "Main",
    props:{
      username: String
    }
  }
</script>

14.2 标签传参

传递参数

<router-link v-bind:to="{name: 'Address', params: {address: '重庆邮电大学'}}">地址</router-link>

必须给Address命名

{
  path: "/address/:address",
  name :'Address',
  component: Address
},

开启参数传递

{
  path: "/address/:address",
  props: true,
  name :'Address',
  component: Address
},

使用参数

<template>
    <h1>地址:{{address}}</h1>
</template>

<script>
    export default {
        name: "Address",
        props: {
          address:String
        }
    }
</script>

15 重定向

{
  path: "/goHome",
  redirect:"/"
}

16 404页面

notFound.vue

<template>
    <h1>页面走丢了!</h1>
</template>

<script>
    export default {
        name: "notFound"
    }
</script>

<style scoped>

</style>

路由配置

{
  path: "*",
  component: notFound
}

17 路由钩子

17.1 普通用法

更改Address.vue

<template>
    <h1>地址:{{address}}</h1>
</template>

<script>
    export default {
      name: "Address",
      props: {
        address: String
      },
      beforeRouteEnter: (to, from, next) => {
        console.log("进入个人信息页");
        next();
      },
      beforeRouteLeave: (to, from, next) => {
        console.log("离开个人信息页");
        next();
      }
    }
</script>

参数说明:

  • to:路由将要跳转的路径信息
  • from:路径跳转前的路径信息
  • next:路由的控制参数
  • next() 跳入下一个页面
  • next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
  • next(false) 返回原来的页面
  • next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例

17.2 使用Axios

#安装 Axios
cnpm install axios --save
cnpm install --save vue-axios

main.js引用 Axios

import VueAxios from 'vue-axios'
import axios from "axios";

Vue.use(VueAxios,axios);

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

<template>
    <h1>地址:{{address}}</h1>
</template>

<script>
    export default {
      name: "Address",
      props: {
        address: String
      },
      beforeRouteEnter: (to, from, next) => {
        console.log("进入个人信息页");
        next(vm => {
          vm.getData()
        });
      },
      beforeRouteLeave: (to, from, next) => {
        console.log("离开个人信息页");
        next();
      },
      methods: {
        getData: function () {
          this.axios({
            method: 'get',
            url: 'http://localhost:8080/static/mock/data.json'
          }).then(function (response) {
            console.log(response)
          })
        }
      }
    }
</script>

<style scoped>

</style>
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

69岁在线敲Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值