Vue快速入门

什么是Vue?

官方文档永远是最好的老师:

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

Vue是一套用于构建用户界面的渐进式框架,与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用.

Vue只关注视图层的构建

视图层: HTML(结构) + CSS(表现) + JavaScript(行为) 给用户看 刷新后台给的数据
其中作用分布如下:

网络通信: axios
页面跳转: vue-router
状态管理: verx
Vue-UI : ICE(飞冰)

JavaScript框架部分讲解:

jQuery:

最熟悉的JavaScript框架,优点是简化了dom操作,缺点是dom操作太频繁,影响前端性能

angular:

特点是将后台的mvc模式(m:DATA V:JSP${} C:vm数据双向绑定)搬到了前端,并增加了模块化开发的理念,与微软合作,使用typescript语法开发,最大的缺点就是版本不合理

React:
一款高性能的前端框架,特点是提出了新概念(虚拟dom),用于减少真实dom操作,在内存中模拟dom操作,有效的提升了前端渲染效率;缺点是使用复杂,需要额外学习一门jsx语言

VUE:
一款渐进式JavaScript框架,所谓渐进式就是逐步实现新特性的意思,比如模块化开发,路由,状态管理等新特性,特点是综合了Angular(模块化)和React(虚拟dom)的优点

Axios:
前端通信框架,因为Vue的边界很明确,就是为了处理dom,所以不具备通信能力,此时就需要额外使用一个通信框架与服务器交互,当然也可以直接使用jQuery提供的Ajax通信功能

UI框架:

ElementUI,iview,ice: 饿了么出品,基于Vue的ui框架

Bootstrap: 前端开发工具包 有个Bootstrap可视化布局非常实用

AmazeUI: 又叫妹子ui 一款HTML5跨屏前端框架

JavaScript构建工具:

Webpack:模块打包器,主要作用是打包,压缩,合并,以及按序加载

MVVM模式

mvvm(Model-View-ViewModel)是一种软件架构设计模式,是一种简化用户界面的事件驱动编程方式

mvvm源自于经典的mvc模式,mvvm的核心是viewmodel层,负责转换model层中的数据对象,来让数据变得更加容易管理和适用

大致架构为:
MVVM架构图

Model层

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

View层

指视图层,也就是用户界面,前端主要由html和css来构建,为了方便展现viewmodel层或者model层的数据而出现的模板语言有:

FreeMaker,Thymeleaf等,各大mvvm框架如Vue.js,AngularJS,EJS等也有自己用来构建用户界面的内置模板语言

ViewModel层

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

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

页面哪个部分用来显示什么属于数据视图状态

而页面加载进来时发生什么,点击这一部分发生了什么,这一块滚动时发生了什么,这些都属于视图行为

Vue概念总结:

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

mvvm模式的优点

mvvm模式和mvc模式一样,主要目的就是分离视图和模型,主要优点如下:

低耦合:

视图可以独立于model变化和修改,一个viewmodel合一绑定到不同的view上,挡view变化的时候model可以不变,挡model变化的时候view也可以不变

可复用:

可以把一些视图逻辑放在一个viewmodel里面,让很多view重用这段视图逻辑

独立开发:

卡法人员可以专注于业务逻辑和数据开发(viewmodel),设计人员可以专注于页面设计

可测试:

界面素来是比较难以测试的,而现在测试可以针对viewmodle来写

我的第一个Vue程序(HTML实现)

首先要想使用Vue,就必须先在idea中下载vue的插件,第一次下载之后还需要再创建一个a.vue的程序之后新建菜单栏才会出现创建vue程序的栏目选项
Vue动态导入:

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

学习vue我们必须知道到它的7个属性,8个 方法,以及7个指令。787原则
el属性
用来指示vue编译器选择从什么地方开始解析 vue的语法,与之对应的就是标签属性了(如id=“xxx”),可以说是一个占位符。
data属性
用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中。
template属性
用来设置模板,会替换页面元素,包括占位符。
methods属性
放置页面中的业务逻辑,js方法一般都放置在methods中
render属性
创建真正的Virtual Dom
computed属性
用来计算
watch属性
watch:function(new,old){}
监听data中数据的变化
两个参数,一个返回新值,一个返回旧值,

以下是一个简单地示范:

<!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>
    var vm=new Vue({
        /*第一步,绑定一个标签 el就是element(元素)*/
        el:"#app",
        /*第二步,存放一个数据 这里也相当于Model层*/
        data:{
            message:"hello,Vue"
        }
    });
</script>
</body>
</html>

可以看到 要想使用Vue就必须要先创建一个Vue对象,然后再对对象进行具体的操作

并且不难发现,vue框架此时已经把mvc的结构给展现出来了,并且div标签显示message信息的时候,message就相当于是一个虚拟dom

此时打开网页,网页上只会有一行hello,Vue

最关键的是,在页面上f12的时候,直接在console输入 vm.message="XXX"时,页面上也会随之进行变化,不用刷新页面

Vue基本逻辑语法

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<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@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        el:"#app",
        data:{
            message:"title中才是隐藏的信息,现在时间为:"+new Date().toLocaleString()
        }
    });
</script>
</body>
</html>

在Vue中,V-XXX都被称为指令,都带有"v-",以表示它们是Vue提供的特殊属性,它们会在渲染的DOM节点上应用特殊的响应式行为,

在此段代码中该指令的意思为:“将这个元素节点的title特性和Vue示例的message属性保持一致”

这里v-bind:XXX=msg与{{XXX}}的作用一样,都可以用来表示数据

Vue基础逻辑判断

一般前端对后台传递过来的数据只有一下两种逻辑判断处理进行显示,或者就是直接显示

if-else及多重if:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层  模板-->
<div id="app">
    <h1 v-if="ok==true">Yes</h1>
    <h1 v-else-if="false">NO</h1>
    <h1 v-else="null">???</h1>
</div>

<!--    第一步,导入vue.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:{
            ok: null
        }
    });
</script>
</body>
</html>

注意.JavaScript中"==="代表绝对等于,表示类型和值都相等
for循环:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层  模板-->
<div id="app">
    前面的item代表item中的具体哪一项,后面的item代表item本身
    <h1 v-for="(item,index) in item">
        <li>
            {{item.message}}--{{index}}
        </li>
    </h1>
</div>
<!--    第一步,导入vue.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:{
            item:[
                {message:'java'},
                {message:'mysql'},
                {message:'jdbc'}
            ]
        }
    });
</script>

</body>
</html>

Vue绑定事件

Vue的绑定事件只有一个,就是v-on,也可以用@来代替v-on,并在触发的时候运行一些JavaScript 代码,
官网事件有很多:
https://www.jquery123.com/category/events/mouse-events/
此处只拿点击来做示范

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <button v-on:click="sayHello()">click me</button>
<!-- 可以用@来省略掉v-on   <button @click="sayHello()">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:"xi哥牛逼"
        },
        methods:{ //方法必须定义在Vue的Methods对象中,v-on事件
            sayHello:function (){
                alert(this.message)
            }
        }
    });
</script>
</body>
</html>

Vue双向绑定

什么是双向数据绑定?
双向数据绑定说的就是Vue的MVVM框架,也就是当数据发生变化的时候,视图也就发生变化,同样,当视图发生变化的时候数据也会发生变化
但是需要注意的是,数据双向绑定一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定
在表单中进行双向绑定:
v-Model负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊操作
但需要注意的是:v-model会忽略所有表单元素的 value,checked,selected特性的初始值,而总是将Vue示例的数据作为数据来源,所以应该通过JavaScript在组件的data选项中声明属性值

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

<!--view层  模板-->
<div id="app">
    输入的文本框:<textarea name="" v-model="message" cols="30" rows="10"></textarea>
    {{message}}
    <ul> 注意这里的textarea一定要适用全封闭标签,不然就会把代码也注入到文本框中</ul>
</div>

<!--    第一步,导入vue.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:{
            message:"111"
        }
    });
</script>

</body>
</html>

效果如下:
不管是直接在文本框中改变字符,还是在审查元素中直接vm.message=“xxx”,最终两者都必定相同
在这里插入图片描述
双向绑定多选一扩展示范:
此处原理就是通过v-model让表单中控件的值与data中的数据做双向绑定

<!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="xige"><input type="radio" name="sex" value="" v-model="xige"><p>
        你的性别选择了:{{xige}}
    </p>
</div>

<!--    第一步,导入vue.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:{
            xige:''
        }
    });
</script>

</body>
</html>

网页显示如下:
此处原理暂时不明白
双向数据绑定下拉框示范:

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

<!--view层  模板-->
<div id="app">
    下拉框:
    <select v-model="xige">
<!--        这里使用v-model="xige"后,selected(在哪默认选哪个)的默认效果不会生效
    还需要再创建一个option空值选项并设置为disable(禁选)
-->
        <option value="" disable>--请选择你的学科--</option>
        <option>java</option>
        <option selected>sql</option>
        <option>jdbc</option>
    </select>
    <p>
        你选择了:{{xige}}
    </p>
</div>

<!--    第一步,导入vue.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:{
            xige:''
        }
    });
</script>

</body>
</html>

Vue组件讲解

什么是组件?
组件是可复用的Vue实例,说白了就是一组可以重复使用的模板,与jstl的自定义标签,Thymeleaf的th:fragment等框架有着异曲同工之妙.通常一个应用会以一棵嵌套的组件树的形式来组织:
在这里插入图片描述
使用组件就必须要新创建一个组件:Vue.component
Vue.component定义一个Vue组件后,需要两个参数,一个是组件的名字,另外一个就是组件的对象
//组件的对象又有两个属性,一个是需要接收的参数props,另外一个就是模板template
确定好template中的内容以及需要接收的参数后,直接使用组件名字的标签就完成了
一定要注意自定义的标签要跟组件的名称一致
上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<!--    下面定义好了之后就可以直接使用自定义的标签了,但是注意标签要跟组件的名称一样
     并且v-for循环之后必须要v-bind:XXX="aaa"来将每一个数据封装为aaa,并指定要发送给XXX,本身组件接收参数只能通过props:['XXX']来进行接收
     注意,此时<xige>标签就已经是一个组件的具体实现了,
-->

    <xige v-for="aaa in items" v-bind:name="aaa"></xige>
</div>

<!--    第一步,导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    Vue.component("xige",{
        props:['name'],
        template:'<li>{{name}}</li>'
    });
    var vm=new Vue({
        el:"#app",
        data:{
            items:["java","Linux","前端"]
        }
    });
</script>

</body>
</html>

总结:
此处的步骤我理解为< xige >标签循环遍历vm中的item对象,然后将对象遍历的参数封装为aaa,
再指定传给name(v-bind:XXX="aaa"就是指定将参数aaa传递给已经绑定好的属性名:XXX)
然后返回给Vue.component的props:[‘XXX’]接收
再组合到template的对应位置,最后再呈现到< xige >标签处

Axios异步通信

什么是Axios?
Axios是一个开源的可以再浏览器和NodeJS的异步通信框架,其主要作用就是实现了Ajax异步通信,其特点功能如下:

  • 从浏览器中创建XMLHttpRequests
  • 从node.js中创建http请求
  • 支持Promise API [JS中链式编程]
  • 拦截请求和相应
  • 转换请求数据和相应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF(跨站请求伪造)
    Axios的生命周期
    Vue实例有一个完整的生命周期,也就是从开始创建,初始化数据,编译模板,挂载DOM,渲染->更新->渲染,卸载等一系列过程,这就是Vue从创建到销毁的生命周期

在这里插入图片描述
能动手就别BB:
首先新建一个json文件:

{
  "name": "希哥",
  "url": "https://editor.csdn.net/md?articleId=108784043",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "小狗窝"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://editor.csdn.net/md?articleId=108784043"
    },
    {
      "name": "hahahaha",
      "url": "https://mp.csdn.net/console/article"
    }
  ]
}

代码演示如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--加载网页时 网速如果过慢就会看到有一个{{info.address}}却没有匹配值,这就是闪烁问题   可以用v-cloak解决-->
    <style>
        [v-clock]{
            display: none;
        }
    </style>
</head>
<body>
<div id="vue" v-cloak>
    <div>{{info.address}}</div>

    <a v-bind:href="info.url">点击跳转到我的博客</a>
</div>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script src= "https://unpkg.com/axios/dist/axios.min.js"></script>

<script type="text/javascript">
    var vm=new Vue({
        el:"#vue",
        //注意了,此时的data是一个方法,而不是vue的data:"XXX"这样的键值对
        data(){
            return{
                //请求的返回参数格式,必须和json字符串一样
                info:{
                    //info翻译过来就是消息
                    name:null,
                    address:{
                        street:null
                    },
                    url:null
                }
            }
        },
/*        data:{info:''},可以有上面一样的效果*/
        mounted(){//钩子函数,链式编程,ES6新特性,可以在程序执行途中执行
            axios
            .get("../data.json")
            .then(response=>(this.info=response.data));
/*            .then(response=>(console.log(response.data)))*/
        }
    });
</script>

</body>
</html>

上面的代码简略一下就是:

<script type="text/javascript">
    var vm=new Vue({
        el:"#vue",
        data:{info:''},
        mounted(){
            axios
            .get("../data.json")
            .then(response=>(this.info=response.data));
        }
    });
</script>

新增一个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="vue">
    <div>{{userList.name}}</div>
    <table border="1">
        <tr v-for="cc in userList.links">
            <td>{{cc.name}}</td>
            <td>{{cc.url}}</td>
        </tr>
    </table>


</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是一个方法,而不是vue的data:"XXX"这样的键值对
        data:{
            userList:[]
        },
        
        created() {
            this.getList()
        },

        methods:{//钩子函数,链式编程,ES6新特性,可以在程序执行途中执行
            getList(){
             axios
                .get("test.json") //获取json数据
                .then(response=>{ //获取成功(then)就将数据封装为response  
                    //response为自定义的名字
                    console.log(response)
                    this.userList=response.data //将封装好的response对象赋值给data数据中的userList
                })
                .catch(error =>{//执行失败之后会跳转到catch方法中
                    console.log('aaa')
                });
            }
        }
    })
</script>

</body>
</html>

计算属性(computed)

computed翻译为 “定义的”
作用在于可以在不更新定义的数据时将数据缓存,方便加载
一般用来定义很长时间才更新的数据,如一些页面的固定内容部分,以节约系统开销
与methods使用方法和格式都一样,
但是因为被视为属性,所以调用时没有方法的括号
代码如下:

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

<div id="vue" v-cloak>
    <p>普通方法加载的数据动态更新currenTime1  {{currentTime1()}}</p>
    <p>定义的数据可以暂时缓存currenTime2  {{currentTime2}}</p>
</div>
<!--引入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:"#vue",
        data(){
            message:"hello,xige"
        },
        methods:{
            currentTime1: function (){
                return Date.now();
            }
        },
        computed:{
            currentTime2: function (){
                this.message;
                return Date.now();
            }
        }
    });
</script>

</body>
</html>

结果区别如下:
属性缓存后不变
注意,当定义的属性被改变时,缓存将被更新,老秦的可以,但我的却不行,懵逼了

插槽(重点)

其实就是套娃,自定义标签模板里面再插入一个带插槽的模板
首先创建好一个模板这里为< todo/>,然后确定slot插槽在模板中的位置,如此处的两个插槽一个为标题,一个为具体的项目
然后再创建另外两个模板用来装载插槽< todo-title/>和< todo-items/>
最后模板直接嵌套就可以了:
< todo>
< todo-title/>
< todo-items/>
< /todo>
要注意的是这里的title和items都是从vue组建中获取的数据,最后分配或遍历的,为了方便理解变量,我直接写成汉字了
还有的重点为同一个模板的标签回车后需要加上""表示下一行
并且每一个模板前面都必须有名字,遍历的参数绑定还需要加上v-bind:items=“XXX”
也可以简写为:items=“XXX”

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

<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="标签"></todo-title>
<!--        for循环遍历每一项到<li>标签,并且有几个元素就自动遍历几个-->
        <todo-items slot="todo-items" v-for=" 每一项数据 in 集合" v-bind:items="每一项数据"></todo-items>
    </todo>
</div>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

<script>
    Vue.component("todo",{
        template://插槽模板
            '<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });
//标题
    Vue.component("todo-title",{
        props:['title'],
        template: '<div>{{title}}</div>'
    });
//内容
    Vue.component("todo-items",{
        props: ['items'],
        template:'<li>{{items}}</li>'
    });

    var vm=new Vue({
        el:"#app",
        data:{
            标签:"我是废物",
            集合:['java','linux','vue']
        }
    });
</script>

</body>
</html>

自定义事件内容分发

自定义时间分发其实就是将vue对象中的事件方法绑定到vue组件中
注意了啊,new的vue是vue对象,Vue.component是vue的模板组件
因为vue组件设定是不能直接绑定vue对象的方法,所以就需要利用mvvm的视图双向绑定机制来进行间接绑定,绑定就会报错无法找到XXX方法
概括的讲就是在vue对象与view视图层有双向绑定的基础上,然后再利用vue组件在view层的插槽机制与vue对象的方法进行绑定
也就是将view层当做vue对象与vue组件的桥梁
这里用到了两个关键的点,一个是自定义事件v-on:组件方法名=“对象方法名”
一个是this.$emit(‘组件方法名’,参数)
以下是插槽代码基础上的新加代码:

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

<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="标签"></todo-title>
<!--        for循环遍历每一项到<li>标签,并且有几个元素就自动遍历几个-->
        <todo-items slot="todo-items" v-for=" (每一项数据,index) in 集合"
                    v-bind:items="每一项数据" :index="index" v-on:xige="removeItems(index)"></todo-items>
<!--        注意这里的v-on自定义事件的意思-->
    </todo>
</div>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

<script>
    Vue.component("todo",{
        template://插槽模板,并且每个模板前面都要有名字,比如这个模板名字为todo
            '<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });
//标题
    Vue.component("todo-title",{
        props:['title'],
        template: '<div>{{title}}</div>'
    });
//内容
    Vue.component("todo-items",{
        props: ['items','index'],
        //vue对象只能绑定当前组件的方法
        template:'<li>{{index}}---{{items}} <button @click="xige">删除</button></li>',
        methods: {
            xige:function (index) {
                this.$emit('xige',index);
            }
        }
    });

    var vm=new Vue({
        el:"#app",
        data:{
            标签:"我是废物",
            集合:['java','linux','vue']
        },
        methods: {
            removeItems:function (index) {
                console.log("删除了"+this.集合[index]+"ok!");
                this.集合.splice(index,1);//一次删除一个元素
            }
        }
    });
</script>

</body>
</html>

这里为了方便理解,同样适用了奇怪的方法名称
到这里开始,vue前端的四个核心就搞定了
基础语法,条件判断,网络通信,组件以及界面布局
现在已经可以写一个单页面应用了(vue全都是自定义标签,无法使用超链接标签),
并且使用vue之后,后端只需要跟前端对接vue对象实例中的data数据就可以了

       data:{
            title:"我是废物",
            Items:['java','linux','vue']
        },

这里的数据交互也就是引用axios通信了
通信就通过data方法return过去就可以了
遵循SoC关注度分离原则,Vue是纯粹的视图框架,并不包含如Ajax之类的通信功能,为了解决通信问题,也就必须要使用Axios框架进行异步通信了

第一个Vue-cli项目

vue-cli是官方系统的一个脚手架,用于快速生成vue项目
主要的功能有:

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

当然,还需要下载一个Node.js:

https://nodejs.org/en/download/

安装之后自动装配环境变量
之后cmd检测版本

node -v
npm -v

这个npm其实就是一个软件包管理工具,安装完node,js后就自带npm了
然后需要一个淘宝镜像加速器:
直接cmd管理员输入:

npm install cnpm -g --registry=https://registry.npm.taobao.org

然后还需要安装一个vue -cli (-g代表全局部署安装)

cnpm install vue-cli -g

还可以cmd输入 vue list 查看可基于哪些模板创建
默认下载在C:\Users\20458\AppData\Roaming\npm(注意设置隐藏文件可见)
然后我们就可以初始化一个vue项目了:

vue init webpack(模板名)  myvue(自定义项目名称)

成功后的自定义选择设定可以按照下图:
在这里插入图片描述

如果cmd初始化模板一直在转downloading template然后超时,是因为电脑无法访问github导致的,有两种解决办法,一种如下:
注:电脑端无法访问GitHub只需要在C:\Windows\System32\drivers\etc的host文件末尾添加以下内容

#github
140.82.112.4 github.com

199.232.69.194 github.global.ssl.fastly.net

185.199.108.153 assets-cdn.github.com

185.199.110.153 assets-cdn.github.com

185.199.111.153 assets-cdn.github.com

另外一种则是直接更新vue到3.0以上版本然后直接vue create webpack XXX
就创建成功了
创建成功之后还需要安装依赖环境

npm install

然后还可以手动启动项目

npm run dev

出现下图则代表启动成功:
在这里插入图片描述
可以打开http://localhost:8080试一下,就会出现vue官网首页
如果停止只需要在刚才的cmd页面ctrl+c输入y就行了
与tomcat差不多
之后就可以在idea中打开,这里以src/components/HelloWorld.vue为例快速运行vue项目
在idea中双击ctrl就可以唤出自定义命令行,用来代替cmd运行
成功运行之后就会直接出现下列内容
在这里插入图片描述

Webpack

本质上, webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle.
Webpack是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过loader转换,任何形式的资源都可以当做模块,比如CommonsJS、AMD、ES6、CSs、JSON、CoffeeScript、LESS等;
伴随着移动互联网的大潮,当今越来越多的网站已经从网页模式进化到了 WebApp伴随着移动互联网的大潮,当今越来越多的网站已经从网页模式进化到了 WebApp模式。它们运行在现代浏览器里,使用HTML5、CSS3、ES6等新的技术来开发丰富的功能,网页已经不仅仅是完成浏览器的基本需求; WebApp通常是一个SPA (单页面应用),每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的JS代码,这给前端的开发流程和资源组织带来了巨大挑战。
前端开发和其他开发工作的主要区别,首先是前端基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器的,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。

模块化的演进

以script标签举例:

<script src ="module1.js"></scirpt>
<script src ="module2.js"></scirpt>
<script src ="module3.js"></scirpt>
<script src ="module4.js"></scirpt>

这是最原始的JavaScript文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window对象中,不同模块的调用都是一个作用域。
这是最原始的JavaScript文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window对象中,不同模块的调用都是一个作用域。
这种原始的加载方式暴露了一些显而易见的弊端:

  • 全局作用域下容易造成变量冲突
  • 文件只能按照< script>的书写顺序进行加载
  • 开发人员必须主观解决模块和代码库的依赖关系
  • 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪
    所以就需要更新换代

安装Webpack

webpack是一块模块加载器兼打包工具,它可以把各种资源,比如JS,ES6,图片等都作为模块来处理和使用,
安装使用webpack只做一件事情,就是将ES6规范的代码打包编译成ES5规范,让所有浏览器都可以使用
安装:

npm install webpack -g   //安装打包工具
npm install webpack-cli -g   //安装客户端

注意此处安装的webpack以及其他插件与初始化的vue项目中package.json自动生成的版本号可能不一样,到时候打包的时候可能会出错,到时候需要更改一下
安装好之后同样的-v测试是否安装成功

webpack配置

创建webpack.config.js配置文件

  • entry: 入口文件,指定WebPack 用哪个文件作为项目的入口.
  • output:输出,指定 WebPack 把处理完成的文件放置到指定路径.
  • module:模块,用于处理各种类型的文件
  • plugins:插件,如:热更新、代码重用等.
  • resolve:设置路径指向
  • watch:监听,用于设置文件改动后直接打包
使用webpack

1.创建项目
2.创建一个名为modules的目录,用于放置JS模块等资源文件
3.在modules下创建模块文件,如 hello.js,用于编写JS模块相关代码

//暴露一个方法: s ayHi
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配置文件,注意,一定要是在项目根目录下创建,在终端栏使用webpack命令打包

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

打包成功后如下图所示:
在这里插入图片描述
注意,webpack打包之后会多出来一个文件夹,这个文件夹就是webpack打包之后的结果,以后导入也是导入这个打包的js文件
在这里插入图片描述

6,打包完成之后自然就要测试一下了,新建一个html,然后在JavaScript标签中src打包的bundle.js文件然后直接打开网页就可以了
注:还有一个命令叫webpack --watch,用来监听文件变化,如果js文件有变动,会立刻重新打包,算是一种热部署,同样ctrl+c停止

vue-router路由

vue-router是vue官方的路由管理器,它和vue的核心深度集成,让构建单页面应用变得易如反掌,包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的基于组件的路由装配
  • 路由参数,查询,通配符
  • 基于vue过滤系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的CSS class的链接
  • HTML5历史模式或者hash模式,在IE9中自动降级
  • 自定义的滚动条行为

安装

基于第一个vue-cli进行测试学习,先查看node_modules中是否存在vue-router
vue-router是一个插件包,所以我们还是需要用npm/cnpm来进行安装的,打开命令行工具,进入项目目录,输入下面命令进行安装

npm install vue-router --save-dev

安装之后还需要进行导入和显式的声明

import VueRouter from 'vue-router' //首先就是导入,前面的名字(VueRouter)无所谓,但是要跟后面的显式声明对应
Vue.use(VueRoute);//显式声明

之后就可以直接在终端运行测试一下是否有错:

npm run dev

到真正的使用时则新建一个包 router
注意,每一个包里面都有一个index.js,这个并不代表是主页,而是代表主配置,
顾名思义,其他杂乱的配置也都在这个index.js的下一级,属于它的组成部分
新建router包之后自然要新建一个index.js页面
第一步import导入环境及路由插件,并安装路由:

import Vue from "vue";
//导入路由插件
import VueRouter from "vue-router";
//导入自定义插件
import Content from "../components组件/Content";
import main from "../components组件/main";

//安装路由
Vue.use(VueRouter);

第二步,在新建的index.js编写路由自定义插件,此处以自定义的内容页为例,自定义的首页代码一样

<template>
  <h1>内容页</h1>

</template>

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

<style scoped>

</style>

第三步,在main.js中配置路由
注意,main.js不是自定义的main.vue
其实就导入router的目录,并在new的Vue中配置一句router就行了

import Vue from 'vue'
import App from './App'
import router from './router路由' //导入router目录时自动扫描里面的路由配置

Vue.config.productionTip = false


new Vue({
  el: '#app',
  //配置路由只需要一句:
  router,
  components: { App },
  template: '<App/>'
})

第四步,在App.vue中使用路由
router-link可以看做是一个a连接,to可以看做是

<template>
  <div id="app">
 <!--同样需要先导入-->
    <h1>vue-router</h1>
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <router-view></router-view>
<!--    view就是页面中放组件的地方-->
  </div>
</template>

<script>
/*这里的思路为在别处创建了Content组件之后又导入进了App.vue,
  然后App.vue再导出到main.js,然后main.js再出到index.html*/
import Content from "./components组件/Content";

export default {
  name: 'App',
  comments:{
    Content
  }
}
</script>
<!--如果style标签中有scoped代表只在当前范围生效-->
<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>

经过npm run dev之后,8080页面显示如下:
在这里插入图片描述
点哪一个,下面的视图组件就显示哪一个router组件的内容
注意了,这里的逻辑关系是8080端口打开了vue的index.html,然后html中组进了App.vue组件,然后App.vue组件嵌套了main.js组件,然后main.js组件又导入了router组件的index.vue主页面,index.vue主页面又有两个router组件,一个是main.vue一个是content.vue,这两个router-link组件单独显示在router-view视图区

vue+elementUI

前面只是学的再多都只是岸上学游泳,接下来就是实战演示,将vue结合elementUI进行实操,从而系统掌握,那么:
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加载器,此处安装了两个,一个是sass-loader一个是node-sass
cnpm install sass-loader node-sass --save-dev
//启动测试
npm run dev

注:npm命令行解释:

npm install moduleName :       
安装模块到项目目录下
npm install -g moduleName :         
-g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看npm config prefix的位置
npm install -save moduleName :            
--save的意思是将模块安装到项目目录下,并在package 文件的dependencies节点写入依赖,-S为该命令的缩写
npm install -save-dev moduleNam e: 
--save-dev的意思是将模块安装到项目目录下,并在package文件的 devDependencies 节点写入依赖,-D为该命令的缩写

接下来用idea打开新建的vue项目
然后把没用的(components和components里面的logo和helloworld.vue)删掉
接着完善路由方面:
首先创建两个路由页面:
登录页面:

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

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


<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");
          } 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;
}

main页面:

<template>
  <h1>登录成功页面</h1>
</template>

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

<style scoped>

</style>

接着将两个路由组件导入路由的总页面index.js

import Vue from "vue";
import Router from "vue-router";
//在路由主页面导入路由组件,现在两个组件放在views包下了
import Main from "../views/Main";
import Login from "../views/Login";

//显式的使用路由
Vue.use(Router);

//导出一个路由接口
export default new Router({
  routes:[
    //在接口中导入两个路由组件和对应路径
    {
      path:'/main',
      component:Main
    },
    {
      path:'/login',
      component: Login
    }
  ]
})

再把路由接口导入到项目的main.js中

import Vue from 'vue'
import App from './App'
//将路由导入main.js
import router from './router'
//导入element-ui
import Element from 'element-ui'
//这里导入了一个css页面.就需要sass遍历器
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(Element);

new Vue({
  el: '#app',
  router,
  render: h => h(App) //Element组件的官方渲染方法
})

然后就是App.vue组件组合路由显示组件了:

<template>
  <div id="app">
<!--    显示路由页面-->
    <router-link to="/Login">登录页面</router-link>
    <router-view></router-view>
  </div>
</template>

<script>

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

<style>

</style>

接着就是终端命令npm run dev了
注意:
如果报错Module build failed: TypeError: Path must be a string. Received undefined路径必须是string类型,现路径无法识别,或者XXXnot find,打开项目的package.json,这个json文件是专门用来显示/设置资源版本的.
找到"sass-loader": “^10.?.?”,将版本号改为7.3.1后,终端重新运行npm install
然后再npm run dev,
最终8080端口网页渲染后如下:
在这里插入图片描述
大致思路与上一节其实没多大区别,两个路由页面现在一个变成了登录页面,一个变成了登录成功之后的页面,然后两个路由页面换了位置罢了,项目最终文件结构图如下:
在这里插入图片描述

路由嵌套(children)

嵌套路由又叫做子路由,在实际应用中,通常由多层嵌套的组件组合而成,同样的url中各段动态路径也按某种结构对应嵌套的各层组件,例如:
在这里插入图片描述
说白了就是插件中更换不同的插件,用到一个children关键词
步骤:
首先在上面的element-ui的基础上创建两个路由组件:
这里是又创建一个user包,然后在包里面创建的,两个组件都一样,就h1标签不一样,这里只上一个

<template>
  <h1>用户列表</h1>
</template>

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

<style scoped>

</style>

然后在index.js页面中登录成功时显示的Main.vue组件中嵌套进去

import Vue from "vue";
import Router from "vue-router";
//在路由主页面导入路由组件,现在两个组件放在views包下了
import Main from "../views/Main";
import Login from "../views/Login";
//导入最新组件
import UserList from '../views/user/List'
import UserProfile from '../views/user/Profile'

//显式的使用路由
Vue.use(Router);

//导出一个路由接口
export default new Router({
  routes:[
    //在接口中导入两个路由组件和对应路径
    {
      path:'/main',
      component:Main,//在一个组件中嵌套路由
      children:[
        {path:'/user/profile',component:UserProfile},
        {path:'/user/list',component:UserList}
      ]
    },
    {
      path:'/login',
      component: Login,
    }
  ]
})

效果如下:
在这里插入图片描述

参数传递及重定向

第一种传参方式:

传参之前必须声明组件的name属性:

      children:[
        {
          //路径最后/:id就代表要传递的参数,如果有多个参数只需要在后面继续加上/:XX就行了
          path:'/user/profile/:id',
          name:'UserProfile',
          component:UserProfile
        },
        {path:'/user/list',component:UserList}
      ]

在Main.vue的用户管理组件下的个人信息组件中router-link组件可以夹带参数

//将
<router-link to="/user/profile">个人信息</router-link>
//改为
<router-link v-bind:to="{name: 'UserProfile',params:{id: 1}}">个人信息</router-link>

因为组件传参只能按照名称和参数对应的方式进行,并且既然是传参,那么由于双向绑定的原因这边还需要加上v-bind才能传递过去,
这里的参数是传递到Profile.vue中的,所以那边就需要接收并显示了:

<template>
<!--  所有的元素不能在根节点下直接渲染或者声明,必须要在标签内进行-->
  <div>
    <h1>个人信息</h1>
    <!--接收参数-->
    {{$route.params.id}}
  </div>
</template>

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

<style scoped>

</style>

注意:这里组件中的参数显示{{$route.params.id}}必须包含在标签中,不能直接在根几点上进行声明渲染,否则就会报错
大体上传递参数的过程为:
Main.vue中声明参数,然后通过v-bind根据name属性传递给index.js组件,当然,index.js组件中要声明好name属性才能接收,接收到ID参数后,再传递给指定path地址(path:‘/user/profile/:id’),后面的/:XX就代表只指定传递哪一个参数,
到profile.vue组件后再传递给组件中的模板< template>组件,最后在< router-view/>中进行显示

第二种传参方式:

第二种传参不需要改动Main.vue声明参数的部分:

<el-menu-item index="1-1">
<!--                name传递组件名,params传递参数,需要对象v-bind: -->
                <router-link v-bind:to="{name: 'UserProfile',params:{id: 1}}">个人信息</router-link>
              </el-menu-item>

首先需要在index.js页面的router组件中声明支持参数传递

import Vue from "vue";
import Router from "vue-router";
//在路由主页面导入路由组件,现在两个组件放在views包下了
import Main from "../views/Main";
import Login from "../views/Login";
//导入最新组件
import UserList from '../views/user/List'
import UserProfile from '../views/user/Profile'

//显式的使用路由
Vue.use(Router);

//导出一个路由接口
export default new Router({
  routes:[
    //在接口中导入两个路由组件和对应路径
    {
      path:'/main',
      component:Main,//在一个组件中嵌套路由
      children:[
        {
          //路径最后/:id就代表要传递的参数,如果有多个参数只需要在后面继续加上/:XX就行了
          path:'/user/profile/:id',
          name:'UserProfile',
          component:UserProfile,
          //第二种传参方式需要先声明支持传参
          props:true
        },
        {path:'/user/list',component:UserList}
      ]
    },
    {
      path:'/login',
      component: Login,
    }
  ]
})

然后直接profile.vue组件接收并且在组件中显示:

<template>
<!--  所有的元素必须不能直接在根节点下,不能直接渲染或者声明,必须要在标签内进行-->
  <div>
    <h1>个人信息</h1>
    <!--{{$route.params.id}}-->
    <!--直接在标签中显示-->
    {{id}}
  </div>
</template>

<script>
export default {
//接收参数:id
  props:['id'],
  name: "UserProfile"
}
</script>

<style scoped>

</style>

重定向

首先: url不变叫转发,url改变叫重定向
这里直接在index.js中添加了一个组件:

//导出一个路由接口
export default new Router({
  routes:[
    //在接口中导入两个路由组件和对应路径
    {
      path:'/main',
      component:Main,//在一个组件中嵌套路由
      children:[
        {
          //路径最后/:id就代表要传递的参数,如果有多个参数只需要在后面继续加上/:XX就行了
          path:'/user/profile/:id',
          name:'UserProfile',
          component:UserProfile,
          //第二种传参方式需要先声明支持传参
          props:true
        },
        {path:'/user/list',component:UserList}
      ]
    },
    {
      path:'/login',
      component: Login,
    },
    //新增重定向组件:
    {
    path:'/goHome',
      redirect:'/main'
    }
  ]
})

然后在main.vue中声明一个超链接就好了:

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

路由模式:

路由模式有两钟:
hash:路径带#号,如:http://localhost:8080/#/goHome
history:路径不带#号:如http://localhost:8080/goHome
修改路由配置代码如下:

export default new Router({
//只需要一句mode:'history',
  mode:'history',
  routes:[XXX]

修改路由模式暂时不知道有什么作用

传递用户名到页面显示:

首先直接在login页面的路由地址中传递username属性:

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;
          }
        });
      }
    }

然后再index.js中添加path:'/main/:name’接收,注意,这个name是给传递过来参数的自定义名字,并声明可传递props:true

//在接口中导入两个路由组件和对应路径
    {
      path:'/main/:name',
      component:Main,//在一个组件中嵌套路由
      props:true,
      children:[

接着把index’.js中的name再传递到Main.vue中接收并显示:
接收:

<script>
export default {
  props:['name'],
  name: "Main"
}
</script>

显示:

      <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>
<!--          显示name属性-->
          <span>{{name}}</span>
        </el-header>

这样就可以了,但是有一点还需要注意,这里添加传递用户名后,之前写的重定向到首页也需要在path后面传递随便一个参数当做name,不然就会报错:
现在重定向的组件为:

    //新增重定向组件:
    {
    path:'/goHome',
      redirect:'/main/:aaa'
    },

404页面:

首先声明一点,写的组件中,请求有对应组件地址的,会直接显示地址对应的组件,没有组件地址的,地址一律视为 ’ * ’
所以404也就是创建一个NotFound组件再import到index,js中,然后地址设置为
‘*’

import NotFound from "../views/NotFound";
    //404页面
    {
      path: '*',
      component: NotFound
    }

404页面就一个新建组件,组件模板中一个h1标签,别的没了,这里就不浪费地方了

路由钩子和异步请求:

beforeRouteEnter:在进入路由前执行,
beforeRouteLeave:在离开路由前执行,
两个方法都需要三个固定名称的参数
profile.vue组件中示例代码如下:

<script>
export default {
  //接收参数
  props:['id'],
  name: "UserProfile",
  //使用方法跟过滤器一样,最后都必须要加上next()
  //如下为进入页面之前所执行的代码
  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是组件实例

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

1,首先安装axios和vue-axios
npm install axios -save axios vue-axios
2,main.js引用axios

//导入依赖
import axios from 'axios'
import vueAxios from 'vue-axios'
//声明实装
Vue.use(vueAxios,axios);

new Vue({
  el: '#app',
  router,
  data:{

  },
  //装载axios
  methods:{
    getData:function () {
      this.axios
    }
  },
  render: h => h(App) //Element组件的官方渲染方法
})

3,在static包下创建一个json静态资源测试文件,测试文件一般统一名称都叫mock:

{
  "name": "希哥",
  "url": "https://editor.csdn.net/md?articleId=108784043",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "小狗窝"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://editor.csdn.net/md?articleId=108784043"
    },
    {
      "name": "hahahaha",
      "url": "https://mp.csdn.net/console/article"
    }
  ]
}

这个时候访问http://localhost:8080/static/mock测试/data.json就会显示json文件了
4,使用:
使用axios读取json字符串并显示

<template>
<!--  所有的元素必须不能直接在根节点下,不能直接渲染或者声明,必须要在标签内进行-->
  <div>
    <h1>个人信息</h1>
    <!--{{$route.params.id}}-->
<!--    第二种方式直接显示参数:-->
    {{id}}
  </div>
</template>

<script>
export default {
  //接收参数
  props:['id'],
  name: "UserProfile",
  //使用方法跟过滤器一样:
  //如下为进入页面之前所执行的代码
  beforeRouteEnter:(to, from, next)=>{
    console.log("进入路由之前");//加载数据
    next(vm => {
      vm.getData();//进入路由之前,执行getData
    });
  },
  //离开前执行
  beforeRouteLeave:(to, from, next)=>{
    console.log("离开路由之前");
    next();
  },
  //使用axios读取json字符串并显示
  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>

这个时候在项目中来回切换效果如下:
在这里插入图片描述

就是这样,完结撒花

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值