Vue.js快速进门

1、简介

什么是Vue.js

Vue 是一套用于构建用户界面的渐进式框架,渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等特性。

Vue 的核心库只关注视图层,易于上手,还便于与第三方库(如:vue-router:跳转vue-resource:通信vuex:管理)或既有项目整合。

为什么使用Vue.js

  • 吸取了Angular(模块化)和React(虚拟Dom:就是把Dom操作放到内存中执行)的长处,并拥有自己独特的功能,如:计算属性

2、前端知识体系

前端三要素

  • HTML(结构)
  • CSS(表现)
  • JavaScript(行为)

CSS预处理器

用一种专门的编程语言,进行Web页面样式设计,再通过编译器转化为正常的CSS文件,以供项目使用

LESS

  • 基于Node.js,通过客户端处理,使用简单

3、MVVM模式

MVVM是一种软件架构模式,源自于经典的MVC模式,它的方式是以事件驱动编程。

它的核心就是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。

在这里插入图片描述
ViewModel封装出来的数据模型包括视图的状态和行为两部分

视图的状态和行为都封装在了ViewModel里面,这样的封装使得ViewModel可以完整的去描述View层

Vue完全解耦了View层和Model层,这个解耦至关重要,它是前后端分离方案实施的重要一环。

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                //Model:数据
                data: {
                    message: "qwe,vue!"
                }
            })
        }
    </script>
</head>

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

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

4、基本语法

v-bind

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind

v-bind简写:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                //Model:数据
                data: {
                    message: "qwe,vue!",
                }
            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    <span v-bind:title="message">测试title悬停事件</span>
</div>
</body>
</html>

v-bind被称为指令。指令带有前缀v-,以表示他们是Vue提供的特殊特性,这里的意思就是说,将这个元素节点的title特性和Vue实例的message属性保持一致

v-if、v-elsif、v-else

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                //Model:数据
                data: {
                    flag: true,
                    type: "A"
                }
            })
        }
    </script>
</head>

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

    <!--测试if-else-->
    <span v-if="flag"></span>
    <span v-else></span>

    <!--
        if-else判断非bool类型
        注意:控制台需要使用引号+字符串测试
    -->
    <span v-if="type==='A'">AAA</span>
    <span v-else-if="type==='B'">BBB</span>
    <span v-else>CCC</span>

</div>
</body>
</html>

v-for

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                //Model:数据
                data: {
                    items:[
                        {message:'bootstrap'},
                        {message:'vue'},
                    ]
                }
            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    <li v-for="item in items">{{item.message}}</li>
<hr/>
    <!--自带下标-->
    <li v-for="(item, index) in items">{{index}}-{{item.message}}</li>
</div>
</body>
</html>

5、绑定事件

v-on简写@

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                data: {
                    message:"methods test"
                },
                //方法必须定义在Vue的methods对象中
                methods:{
                    show:function () {
                        alert(this.message)
                    }
                }

            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    <button v-on:click="show">click me</button>
</div>
</body>
</html>

6、双向数据绑定

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

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

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

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                data: {
                    message:'',
                    sex:'',
                    selected:''
                },


            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    <!--文本框-->
    输入的文本:<input type="text" v-model="message">{{message}}

    <br/>
    <!--单选框-->
    性别:<input type="radio" name="sex" value="" v-model="sex"><input type="radio" name="sex" value="" v-model="sex"><span>选中了:{{sex}}</span>

    <br/>
    <!--下拉框-->
    <select v-model="selected">
        <option value="">--请选择--</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <span>选中了:{{selected}}</span>

</div>
</body>
</html>

7、组件

组件就是可复用的Vue实例,说白了就是一组可以重复使用的模板,跟JSTL的自定义标签等框架类似。通常一个应用会以一棵嵌套的组件树的形式来组织

在这里插入图片描述

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            /**
             * 定义一个Vue组件component
             * indi 组件的名字
             * props 用来接收数据的参数
             * template 模板
             */
            Vue.component("indi", {
                props: ['i'],
                template: '<li>{{i}}</li>'
            })

            vm = new Vue({
                el: "#app",
                data: {
                    items: ["Java", "Linux", "Vue"]
                }
            })
        }
    </script>
</head>

<body>
<div id="app">
    <!--
        v-bind:i="item"    
        将遍历的item项绑定到组件中props定义的名为i的属性上
    -->
    <indi v-for="item in items" v-bind:i="item"></indi>
</div>
</body>
</html>

8、Axios*

Axios是一个开源的用在浏览器端和NodeJS的异步通信框架,它的主要作用就是实现AJAX异步通信。

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--v-clock:设置白屏,手动解决闪烁问题-->
    <style>
        [v-clock]{
            display: none;
        }
    </style>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {

            vm = new Vue({
                el: "#vue",
                //data()方法与属性data不同
                data() {
                    return {
                        //请求的返回参数格式必须和JSON中的格式一样
                        info: {
                            name: null,
                            address: {
                                street: null,
                                city: null,
                                country: null
                            },
                            url:null
                        }
                    }
                },
                //钩子函数:可以在程序执行时插入到中间执行
                //链式编程,ES6新特性
                mounted() {
                    axios.get('data.json').then(response => (
                        this.info = response.data
                    ))
                }
            })
        }
    </script>
</head>

<body>
<div id="vue" v-clock>
    {{info.name}}
    <br/>
    {{info.address.street}}
    <br/>
    <a v-bind:href="info.links[0].url">click me</a>
</div>
</body>
</html>

9、计算属性

简单点来说,计算出来的结果,保存在属性中,内存中运行,可以想象为缓存。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            vm = new Vue({
                el: "#app",
                //Model:数据
                data: {
                    message: "qwe,vue!"
                },
                methods:{
                    currentTime1:function () {
                        return Date.now();
                    }
                },
                //计算属性,methods优先级高于computed,不建议重名
                computed:{
                    currentTime2:function () {
                        this.message;
                        return Date.now();
                    }
                }
            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    {{currentTime1()}}
    {{currentTime2}}
</div>
</body>
</html>

计算属性的主要特性就是为了将不经常发生变化的计算结果进行缓存,只有当其内部数据发生变化的时候,才会重新计算

10、slot

在Vue中使用<slot>元素作为承载分发内容的出口,称之为插槽,可以应用在组合组件的场景中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            Vue.component("todo",
                {
                template:'<div>\
                        <slot name="todo-title"></slot>\
                        <ul>\
                            <slot name="todo-list"></slot>\
                        </ul>\
                    </div>'
            });



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

            Vue.component("todo-list",{
                props:['todoItem'],
                template:'<li>{{todoItem}}</li>'
            });

            vm = new Vue({
                el: "#app",
                data:{
                    todoTitle:'待办列表',
                    todoList:['Java','Linux','Python']
                }
            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="todoTitle"></todo-title>
        <!--
            todoItem -> todo-item
            因为HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符
            这就意味着在使用DOM模板的时候,需要将props的驼峰命名法,在html中转换成短横线命名法
        -->
        <todo-list slot="todo-list" v-for="item in todoList" :todo-item="item"></todo-list>
    </todo>
</div>
</body>
</html>

11、自定义事件

流程解析
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  导入Vue.js  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>
        var vm;
        window.onload = function () {
            Vue.component("todo",
                {
                template:'<div>\
                        <slot name="todo-title"></slot>\
                        <ul>\
                            <slot name="todo-list"></slot>\
                        </ul>\
                    </div>'
            });



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

            //组件
            Vue.component("todo-list",{
                props:['todoItem','index'],
                template:'<li>{{index}}------{{todoItem}}<button @click="remove">删除</button></li>',
                methods:{
                    //只能绑定当前组件的方法
                    remove:function (index) {
                        //自定义事件分发
                        this.$emit('remove',index)
                    }
                }
            });

            //Vue实例
            vm = new Vue({
                el: "#app",
                data:{
                    todoTitle:'待办列表',
                    todoList:['Java','Linux','Python']
                },
                methods:{
                    removeItem:function (index) {
                        //一次只删除一个元素

                        this.todoList.splice(index,1);
                    }
                }
            })
        }
    </script>
</head>

<body>
<!--view层 模板-->
<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="todoTitle"></todo-title>
        <!--
            todoItem -> todo-item
            因为HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符
            这就意味着在使用DOM模板的时候,需要将props的驼峰命名法,在html中转换成短横线命名法
        -->
        <todo-list slot="todo-list" v-for="(item,index) in todoList" :todo-item="item" :index="index" @remove="removeItem(index)" :key="index"></todo-list>
    </todo>
</div>
</body>
</html>

12、vue-cli

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

config目录下的index.js可以修改端口号

1. 安装Node.js

2. 安装Node.js淘宝镜像加速器(cnpm)
	npm install cnpm -g

3. 安装vue-cli
	cnpm install vue-cli -g
	
4. 查看是否安装成功
	vue list
	
5. 创建一个项目,建立一个空文件夹,命令行跳转到目录,项目名myvue
	vue init webpack myvue
	
6. 两个回车,输入一个作者名字,之后一路选择no

7. 初始化
	cd myvue
	npm install
	
8. 运行
	npm run dev

13、Webpack

本质上,webpack是一个现代JavaScript应用程序的静态模块打包器,它会递归的构建一个依赖关系图

ES6模块

EcmaScript6标准增加了JavaScript语言层面的模块体系定义,其核心思想就是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量,而以往的CommondJS和AMD模块,都只能在运行时确定这些东西。

优点:

  • 容易进行静态分析
  • 面向未来的EcmaScript标准

缺点:

  • 原生浏览器还没有实现该标准
  • 全新的命令,新版的NodeJS才支持

安装Webpack

WebPack是一个模块化加载的兼容打包工具,它能把各种资源都当做模块化处理

切换到项目目录

npm install webpack -g

npm install webpack-cli -g

使用Webpack

在这里插入图片描述

  1. 创建一个空文件夹,用idea打开
  2. 创建一个名为modules的目录,用于防止JS模块等资源文件
  3. 在modules下创建模块文件,例如hello.js,用于编写JS模块相关代码
//暴露一个方法
exports.sayHi = function () {
    document.write("<h1>ES6</h1>");
}
  1. 在modules下创建一个名为main.js的入口文件,用于打包时设置entry属性
var hello = require("./hello");
hello.sayHi();
  1. 在项目根目录下创建webpack.config.js的配置文件,使用webpack命令打包
module.exports = {
    entry: './modules/main.js',
    output: {
        filename: "./js/bundle.js"
    }
}
  1. 在项目根目录下创建HTML页面,如index.html,导入webpack打包后的js文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 前端的模块化开发   -->
    <script src="dist/js/bundle.js"></script>
</head>
<body>
</body>
</html>

说明:

# 参数 --watch 修改js之后,将自动打包,用于监听变化
webpack --watch

14、vue-router

Vue Router 是 Vue.js官方的路由管理器

  1. 安装
npm install vue-router --save-dev
  1. 清空router文件夹内的所有文件
  2. 创建components文件夹存放编写的组件
  3. 定义一个Content.vue的组件
<template>
    <h1>内容页</h1>
</template>

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

<!--scoped仅在当前文件中有效-->
<style scoped>

</style>
  1. 创建一个Main.vue的组件
<template>
    <h1>首页</h1>
</template>

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

<style scoped>

</style>
  1. 创建router文件夹,用来存放路由

  2. 在router文件夹中创建index.js,用来配置路由

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

import Content from '../components/Content'
import Mainn from '../components/Main'

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

//配置导出路由
export default new VueRouter({
  routes:[
    {
      //路由路径
      path:'/content',
      name:'content',
      //跳转的组件
      component:Content
    },
    {
      //路由路径
      path:'/main',
      name:'main',
      //跳转的组件
      component:Mainn
    }
  ]
})

  1. 修改main.js,导入路由配置
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/>'
})

  1. 修改App.vue
<template>
  <div id="app">
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: 'App'
  }
</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>
  1. 运行
npm run dev

15、vue+ElementUI

环境配置

  1. 创建一个vue-cli的工程
vue init webpack hello_vue
  1. 安装依赖
# 进入工程目录
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
  1. 修改package.json
    "sass-loader": "^7.3.1",

目录结构

  • assets:用于存放资源文件
  • components:用于存放 Vue 功能组件
  • views:用于存放 Vue 视图组件
  • router:用于存放 vue-router 配置

创建视图

首页

在 views 目录下创建一个名为 Main.vue 的视图组件;主要用于登录后展示登录成功的跳转效果;

<template>
    <div>
      首页
    </div>
</template>

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

<style scoped>

</style>

登录页

在 views 目录下创建一个名为 Login.vue 的视图组件

<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: '密码不可为空', 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;
  }
</style>

创建路由

在 router 目录下创建一个名为 index.js 的 vue-router 路由配置文件

import Vue from 'vue'
import Router from 'vue-router'

import Login from "../views/Login"
import Main from '../views/Main'

Vue.use(Router);

export default new Router({
  routes: [
    {
      // 登录页
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      // 首页
      path: '/main',
      name: 'Main',
      component: Main
    }
  ]
});

配置路由

  1. 修改入口代码 main.js
import Vue from 'vue'
import App from './App'
import router from './router'

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

// 安装路由
Vue.use(router)
Vue.use(ElementUI)

new Vue({
  el: '#app',
  // 启用路由
  router,
  // 启用 ElementUI
  render: h => h(App)
})
  1. 修改App.vue
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'App',

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

16、路由嵌套

路由嵌套又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。同样的,URL中各段动态路径也按某种结果对应嵌套的各层组件

在这里插入图片描述

  1. 在views目录下创建一个user文件夹,添加新的组件List.vue
<template>
  <div style="float: left;">
    <h1>用户列表</h1>
  </div>
</template>

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

<style scoped>

</style>
  1. 再添加一个Profile.vue
<template>
  <div style="float: left;">
    <h1>个人信息</h1>
  </div>
</template>

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

<style scoped>

</style>

  1. 修改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 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>

  1. 修改路由配置index.js
import UserList from '../views/user/List'
import UserProfile from '../views/user/Profile'

export default new Router({
  routes: [
    {
      path: '/main',
      name: 'Main',
      component: Main,
      children: [
        {path: '/user/profile', name: 'UserProfile', component: UserProfile},
        {path: '/user/list', name: 'UserList', component: UserList}
      ]
    },
  ]
})
  1. 效果图
    在这里插入图片描述

17、参数传递

示例一

  1. 修改index.js
// ...
export default new Router({
  routes: [
    {
      path: '/main',
      name: 'Main',
      component: Main,
      children: [
        {path: '/user/profile/:id', name: 'UserProfile', component: UserProfile},
        {path: '/user/list', name: UserList, component: UserList}
      ]
    }
  ]
})
  1. 修改Main.vue
                <router-link :to="{name:'UserProfile',params:{id: 1}}">个人信息</router-link>
  1. 修改Profile.vue
    所有的元素在使用时必须放在标签内
<template>
  <div style="float: left;">
    <h1>个人信息</h1>
    <h1>{{$route.params.id}}</h1>
  </div>
</template>
  1. 效果图
    在这里插入图片描述

示例二

props解耦

  1. 修改Profile.vue
<script>
  export default {
    props: ['id'],
    name: "UserProfile"
  }
</script>
  1. 修改index.js
export default new Router({
  routes: [
    {
      path: '/main',
      name: 'Main',
      component: Main,
      children: [
      	//修改了这里
        {path: '/user/profile/:id', name: 'UserProfile', component: UserProfile, props: true},
        {path: '/user/list', name: UserList, component: UserList}
      ]
    }
  ]
})

示例三

登录用户之后,在main页面右上角显示用户名

  1. 修改Login.vue
    methods: {
      onSubmit(formName) {
        // 为表单绑定验证功能
        this.$refs[formName].validate((valid) => {
          if (valid) {
            // 在这里添加参数
            this.$router.push("/main/"+this.form.username);
          } else {
            this.dialogVisible = true;
            return false;
          }
        });
      }
    }
  1. 修改index.js
  routes: [
    {
      path: '/main/:name',
      name: 'Main',
      component: Main,
      children: [
        {path: '/user/profile/:id', name: 'UserProfile', component: UserProfile, props: true},
        {path: '/user/list', name: UserList, component: UserList}
      ],
      props: true
    }
  1. 修改Main.vue
        <el-header style="text-align: right; font-size: 12px">
          <!--...-->
          <span>{{name}}</span>
        </el-header>
<script>
  export default {
    props: ['name'],
    name: "Main"
  }
</script>

18、重定向

  1. 修改index.js
    添加一个新的路由

    {
          path:'/home',
          redirect:'/main'
        }
    
  2. 修改Profile.vue
    在前端使用

                  <el-menu-item index="1-3">
                    <!--插入的地方-->
                    <router-link to="/home">回到首页</router-link>
                  </el-menu-item>
    

带参数的重定向

  1. 修改index.js

    {
          path:'/home/:name',
          name: 'Home',
          redirect:'/main/:name',
          props: true
        }
    
  2. 修改Profile.vue

                  <el-menu-item index="1-3">
                    <router-link :to="{name:'Home',params:{name: 'admin'}}">回到首页</router-link>
                  </el-menu-item>
    

19、路由模式

路由模式有两种

  • hash:路径带 # 符号,如 http://localhost/#/login(默认)
  • history:路径不带 # 符号,如http://localhost/login

修改路由配置

index.js

export default new Router({
  mode:'history'
})

20、404

处理 404 需要创建一个名为 NotFound.vue 的视图组件

21、钩子函数

类似拦截器的作用

beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行

<script>
  export default {
    props: ['id'],
    name: "UserProfile",
    //在进入路由前执行
    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 是组件实例

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

  1. 安装Axios

    cnpm install axios -s
    
    cnpm install --save vue-axios
    
  2. main.js引用Axios

    import axios from 'axios'
    import VueAxios from 'vue-axios'
    
    Vue.use(VueAxios, axios)
    
  3. 准备数据

    只有static目录下的文件可以被访问到

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

    beforeRouteEnter中执行异步请求

    <script>
      export default {
        props: ['id'],
        name: "UserProfile",
        //在进入路由前执行
        beforeRouteEnter: (to, from, next) => {
          console.log('进入路由之前');
          next((vm)=>{
            //进入路由之前执行getData()
            vm.getData();
          });
        },
        //在路由离开前执行
        beforeRouteLeave: (to, from, next) => {
          console.log('离开路由之前');
          next();
        },methods:{
          getData:function () {
            this.axios({
              method:'get',
              url:'http://localhost:8081/static/mock/data.json'
            }).then(function (response) {
              console.log(response)
            })
          }
        }
      }
    </script>
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值