vue

Vue

1.简介

Vue的核心库只关心视图层(HTML + CSS + JavaScript),是一个渐进式的框架。

就是为了处理DOM

MVVM模式的实现者

●Model:模型层,在这里表示JavaScript对象
●View:视图层,在这里表示DOM (HTML操作的元素)
●ViewModel:连接视图和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者

在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者
●ViewModel能够观察到数据的变化,并对视图对应的内容进行更新
●ViewModel能够监听到视图的变化,并能够通知数据发生改变

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

第一个Vue程序

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

</head>
<body>

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

<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:数据*/
        data:{
            message:"hello,vue!"
        }
    });
</script>
</body>
</html>

其他:

不同部分的工具

网络通信:axios

页面跳转:vue-router

状态管理:vuex

Vue-UI:ICE、elementUI

常见的JavaScript框架:

jQuery:简化DOM操作

Angular:Google的前端框架,具有模块化的优点

React:Facebook的前端框架,具有虚拟DOM的优点:利用内存来缓存一些DOM

Vue:将模块化和虚拟DOM的优点相结合

Axios:前端通信框架

前端三大框架:Angular、React、Vue

UI框架

●Ant-Design:阿里巴巴出品,基于React的UI框架
●ElementUI、 iview、 ice: 饿了么出品,基于Vue的UI框架
●Bootstrap: Twitter推出的一个用于前端开发的开源工具包
●AmazeUI:又叫"妹子UI",一款HTML5跨屏前端框架

JavaScript构建工具

●Babel: JS编译工具,主要用于浏览器不支持的ES6新特性,比如用于编译TypeScript
●WebPack: 模块打包器,主要作用是打包、压缩、合并及按序加载

2.基本指令

1、v-bind

使用v-bind来绑定元素特性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
	<!--导入绑定了span元素的title属性-->
    <span v-bind:title="message">鼠标悬浮</span>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    
<script>
    var vm=new Vue({
        el:'#app',
        data: {
            message: "hello world"
        }
    });
</script>
</body>
</html>

2、v-if 和 v-else

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

    <span v-bind:title="message">鼠标悬浮</span>
    <h1 v-if="ok">yes</h1>
    <h1 v-else>no</h1>
    
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">c</h1>
    <h1 v-else-if="type==='C'">c</h1>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
    var vm=new Vue({
        el:'#app',
        data: {
            message: "hello world",
            ok: true,
            type: 'A'
        }
    });
</script>
</body>
</html>

3、v-for

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

    <ul>
        <li v-for="item in items">{{ item.name }}</li>
    </ul>

    <ul>
        <li v-for="(item,index) in items">{{ item.name }}--{{ index }}</li>
    </ul>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
    var vm=new Vue({
        el:'#app',
        data: {
            items: [
                {name: "java"},
                {name: "python"}
            ]
        }
    });
</script>
</body>
</html>

测试:在控制台输入vm.items.push({message:'javascript'}),尝试追加一条数据,你会发现浏览器中显示的内容会增加一条javascript

4、v-on

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <button v-on:click="sayHi">点我</button>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:'Hello World'
        },
        methods:{
            sayHi:function(event){
                //'this'在方法里面指向当前Vue实例
                alert(this.message);
            }
        }
    });
</script>
</body>
</html>

3.双向绑定

你可以用v-model指令在表单、及元素上创建双向数据绑定。因为表单属于非UI控件,所以其不能使用v-bind来进行绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
    
<body>
<div id="app">
    
     输入的文本:
    <input type="text" v-model="message"/>{{ message }}<br/>
  
    性别:
    <input type="radio" name="sex" value="" v-model="radios" ><input type="radio" name="sex" value="" v-model="radios" ><p>选择了谁:{{radios}}  </p>
    
    下拉框 :
    <select v-model="selected">
       <option value="" disabled>--请选择--</option>
       <option>A</option>
       <option selected>B</option>
       <option>C</option>
    </select>
    
    <span>下拉框选中了:{{selected}}</span>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    
<script>
    var vm=new Vue({
        el:'#app',
        data: {
            message: "你好",
            checked: false,
            radios: '',
            selected: ''
        },


    });
</script>
</body>
</html>

在这里插入图片描述

4.组件

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--组件:传递个组件的值:props-->
    <zujian v-for="(item,index) in items" v-bind:rec="item"></zujian>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
    //定义一个Vue组件
    Vue.component("zujian",{
        props: ['rec'],//接收参数
        template:"<li>{{rec}}</li>"
    });

    var vm=new Vue({
        el:'#app',
        data: {
            items: ["java","Linux","前端"]
        }
    });
</script>
</body>
</html>

首先,v-for将data中的items遍历了出来

然后通过v-bind将遍历出item与接收参数进行绑定,

最后在组件中通过props进行接收,再在模板中进行展示

5.插槽

比如准备制作一个待办事项组件(todo) , 该组件由待办标题(todo-title) 和待办内容(todo-items)组成,但这三个组件又是相互独立的,该如何操作呢?
第一步定义一个待办事项的组件

<div id="app">
    <todo></todo>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    Vue.component('todo',{
        template:'<div>\
                <div>代办事项</div>\
                <ul>\
                    <li>学习狂神说Java</li>\
                </ul>\
            </div>'
    })
</script>

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

1-将上面的代码留出一个插槽,即slot

 Vue.component('todo',{
        template:'<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });

2-定义一个名为todo-title的待办标题组件 和 todo-items的待办内容组件

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

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

3-实例化Vue并初始化数据

 var vm = new Vue({
        el:"#vue",
        data:{
            todoItems:['test1','test2','test3']
        }
    });

4-将这些值,通过插槽插入

<div id="vue">
    <todo>
        <todo-title slot="todo-title" title="秦老师系列课程"></todo-title>
        <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下为简写-->
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items
    </todo>
</div>

完整

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    
<!--view层,模板-->
<div id="vue">
    <todo>
        <todo-title slot="todo-title" title="title"></todo-title>
        
        <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下为简写-->
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items
    </todo>
</div>
        
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
        
<script type="text/javascript">
    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>'
    });
    //这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
    Vue.component("todo-items",{
        props:["item","index"],
        template:"<li>{{index+1}},{{item}}</li>"
    });

    var vm = new Vue({
        el:"#vue",
        data:{
            title:"秦老师系列课程",
            todoItems:['test1','test2','test3']
        }
    });
</script>
</body>
</html>

6.自定义事件

通过以上代码不难发现,数据项在Vue的实例中, 但删除操作要在组件中完成, 那么组件如何才能删除Vue实例中的数据呢?此时就涉及到参数传递与事件分发了, Vue为我们提供了自定义事件的功能很好的帮助我们解决了这个问题; 使用this.$emit(‘自定义事件名’, 参数) , 操作过程如下:

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

var vm = new Vue({
        el:"#vue",
        data:{
            title_text:"秦老师系列课程",
            todoItems:['test1','test2','test3']
        },
        methods:{
            removeItems:function(index){
                console.log("删除了"+this.todoItems[index]+"OK");
                //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目,其中index
                this.todoItems.splice(index,1);
            }
        }
    });

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

 Vue.component("todo-items",{
        props:["item_p","index_p"],
        template:"<li>{{index_p+1}},{{item_p}} <button @click='remove'>删除</button></li>",
        methods:{
            remove:function (index) {
            //这里的remove是自定义事件名称,需要在HTML中使用v-on:remove的方式
                //this.$emit 自定义事件分发
                this.$emit('remove',index);
            }
        }
    });

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

<!--增加了v-on:remove="removeTodoItems(index)"自定义事件,该组件会调用Vue实例中定义的-->
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item_p="item" :index_p="index" v-on:remove="removeItems(index)" :key="index"></todo-items>

完整实现删除功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="vue">
    <todo>
        <todo-title slot="todo-title" :title="title_text"></todo-title>
        <!--<todo-items slot="todo-items" v-for="(item,index) in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下为简写-->
        <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item_p="item" :index_p="index" v-on:remove="removeItems(index)" :key="index"></todo-items>
    </todo>
</div>
<!--1.导入Vue.js-->
<script src="../js/vue.js"></script>
<script type="text/javascript">
    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>'
    });
    //这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!
    Vue.component("todo-items",{
        props:["item_p","index_p"],
        template:"<li>{{index_p+1}},{{item_p}} <button @click='remove_methods'>删除</button></li>",
        methods:{
            remove_methods:function (index) {
                //this.$emit 自定义事件分发
                this.$emit('remove',index);
            }
        }
    });

    var vm = new Vue({
        el:"#vue",
        data:{
            title_text:"秦老师系列课程",
            todoItems:['test1','test2','test3']
        },
        methods:{
            removeItems:function(index){
                console.log("删除了"+this.todoItems[index]+"OK");
                this.todoItems.splice(index,1);
            }
        }
    });
</script>
</body>
</html>

逻辑理解

img

7.vue-cli脚手架

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

安装vue-cli

//在命令台输入
cnpm install vue-cli -g
//查看是否安装成功
vue list

创建项目

// 这里的 myvue 是项目名称,可以根据自己的需求起名
vue init webpack myvue
cd myvue//进入项目
npm install//安装项目所需依赖
npm run dev//构建并运行
//访问8080端口

8.vue-router路由

Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。

安装vue-router

npm install vue-router --save-dev 

实例测试:

根目录下的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>

src目录下的main.js

//main.js主要创建Vue实例,使路由router文件和总组件App结合起来
import Vue from 'vue'
import App from './App.vue'		/*引入组件文件*/
import router from './router' 	/*引入路由文件夹*/

Vue.config.productionTip = false

new Vue({ 			/*创建初始Vue实例*/
  el: '#app',   	/*组件App里的div */
  router,			 //配置路由
  components: { App },  /*Vue实例的组件*/
  template: '<App/>'	/*渲染模板*/
})

src目录下的App.vue: 可以理解为一个页面的固定组件

<!--App.vue就是main.js里的App,当路由文件根据路径匹配到组件时,将组件渲染到<router-view/>标签所在的位置-->
<template>
  <div id="app">
      <!--控制路由-->
 	 <router-link to="/content">内容页</router-link>
 	 <router-link to="/main">首页</router-link>
      
 	 <router-view/>              <!--路由文件匹配的组件渲染在这里-->
  </div>
</template>

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

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
}
</style>

src目录下,新建一个文件夹:router,专门存放路由,配置路由index.js

import Vue from'vue'						//导入路由插件
import Router from 'vue-router'				//导入上面定义的组件
import Content from '../components/Content'
import Main from '../components/Main'

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

//配置路由
export default new Router({
	routes:[
		{
			//路由路径
			path:'/content',
			//路由名称
			name:'content',
			//跳转到组件
			component:Content
			},{
			//路由路径
			path:'/main',
			//路由名称
			name:'main',
			//跳转到组件
			component:Main
			}
		]
	});

调用关系

1、请求访问 main.js文件时,首先查到挂载的文件index.html中的元素#app

2、注册组件(此处只有组件App),选择其中用于替换挂载元素(第一步中的元素)的模板组件(<App/>),即用App.vue替换index.html中的<div id="app"><div>

3、注入路由器router:

  • 模板组件(App.vue)中有,将在其中渲染路由匹配到的组件

  • 在APP.vue注入(import)路由时指定的是router文件夹,即文件夹下所有routes

  • router文件夹下此时只有index.js文件,其中routes:[]规定了文件地址及其url地址映射

  • 根据文件地址,载入组件(First.vue),组件被渲染在中,显示在index.html中

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jgB4NsLY-1615420643608)(C:\Users\国\AppData\Roaming\Typora\typora-user-images\image-20210305171819681.png)]

文件调用关系

index.html为何默认显示?

//其实,双击执行npm中dev时,控制台将执行如下语句
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

//由此可见,运行时启动文件webpack.dev.conf.js,而文件中包含如下语句,规定了起始页面
	new HtmlWebpackPlugin({
	      filename: 'index.html',
	      template: 'index.html',
	      inject: true
	    }),

main.js为何默认加载?

//因为使用的脚手架工具vue-cli里用webpack来打包项目文件,webpack.dev.conf文件里还定义了webpack基础配置文件webpack.base.conf.js,定义语句如下:
const baseWebpackConfig = require('./webpack.base.conf')

//而文件webpack.base.conf.js中,包含如下语句,指定了入口:
 entry: {
    app: './src/main.js'
  }

9.使用ElementUI组件库

创建工程以及安装相关依赖

//创建一个名为hello-vue的工程 
vue init webpack hello-vue
//安装依赖,我们需要安装vue-router、element-ui、 sass -loader和node-sass四个插件

#进入工程目录
cd hello-vue
#安装vue-router
npm install vue-router --save-dev
#安装element-ui
npm i element-ui -S

#安装依赖
npm install
#安装SASS加载器
cnpm install sass-loader node-sass --save-dev
#启动测试
npm run dev

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

在views下创建Main.vue

<template>
    <h1>首页</h1>
</template>

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

<style scoped>

</style>

在router文件下创建index.js路由配置文件

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Main'
import Main from  '../views/Login'

Vue.use(VueRouter);

export default new VueRouter({
   routes:[{
     path:'/main',
     component: Main
   },
     {
       path:'/login',
       component:Login
     }
   ]

})

配置main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(router);
Vue.use(Element);

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

App.vue

<template>
  <div id="app">
    <router-link to="/login">登录</router-link>
    <router-link to="/main">主页</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>

在控制台输入 npm run dev 运行项目

注: “sass-loader”: "^5.0.0 ",sass的版本不能太高,如果报错以下错误,应适当调低版本在这里插入图片描述

成功运行在这里插入图片描述

10.路由嵌套

1、在上一个项目基础上,在views目录新建一个user文件夹,在user文件下创建,List.vue和perfile.vue两个文件

在这里插入图片描述

2、编写List.vue(perfile.vue类似)

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

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

<style scoped>

</style>

3、编写index.js,配置嵌套路由修改 router 目录下的 index.js 路由配置文件,使用children放入main中写入子模块,代码如下

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

import Login from '../views/Login'
import Main from  '../views/Main'
import UserList from '../views/user/List'
import UserPerfile from  '../views/user/Perfile'

Vue.use(VueRouter);

export default new VueRouter({
   routes:[{
     path:'/login',
     component: Login,
   },
     {
       path:'/main',
       component:Main,
       children:[{
         path:'/user/list',          //路由嵌套             
         component:UserList},
         {
           path:'/user/perfile',
           component:UserPerfile
         }
       ]
     }
   ]

})

4、编写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/perfile">个人信息</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>

测试在这里插入图片描述

11.参数传递

第一种传参:

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

 <el-menu-item index="1-1">
       <!--插入的地方-->
		<router-link  v-bind:to="{name:'UserPerfile',params:{id:1}}">个人信息
    	</router-link>
 </el-menu-item>

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

 children:[{
         path:'/user/list',
         component:UserList},
         {
           path:'/user/perfile/:id',
           name:'UserPerfile',
           component:UserPerfile
         }

3、在要展示的组件Profile.vue中接收参数 使用 {{$route.params.id}}来接收

<!--Profile.vue 部分代码-->
<template>
  <div>
    {{$route.params.id}}
    <h1>个人信息</h1>

  </div>
</template>

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

<style scoped>

</style>

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

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

path:'/user/perfile/:id',
           name:'UserPerfile',
           component:UserPerfile,
           props:true,

2、传递参数和之前一样 在Main.vue中修改route-link地址

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

3、在Profile.vue接收参数为目标组件增加 props 属性

<template>
  <div>
    <!--{{$route.params.id}}-->
    <!--<h1>个人信息</h1>-->
		{{id}}
  </div>
</template>

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

<style scoped>

</style>

12.组件重定向

Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:在router下面index.js的配置

 routes:[{
     path:'/login',
     component: Login,
   },{
       path:'/goHome',
       redirect:'/main'
   },

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

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

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

13.路由钩子与404

路由模式有两种

●hash:路径带#符号,如http://localhost/#/login

●history: 路径不带#符号,如http://localhost/login

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

 mode:'history',
   routes:[{
     path:'/login',
     component: Login,
   }

404问题

1、在views目录下新建一个NotFound.vue页面

<template>
    <h1>404,页面没有找到</h1>
</template>

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

<style scoped>

</style>

2、配置路由index.vue

  {
       path:'*',
       component:NotFound
     }

路由钩子与异步请求

beforeRouteEnter:在进入路由前执行

beforeRouteleave :在离开路由前执行

 beforeRouteEnter:(to,from,next)=>{
         console.log("进入路由之前")
      },
      //进入路由之后
      beforeRouteleave:(to,from,next)=>{
        console.log("进入路由之后")
    }

参数说明: .

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

在钩子函数中使用异步请求
1、安装 Axios

cnpm install --save vue-axios

2、main.js引用 Axios

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

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

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

4.在 beforeRouteEnter 中进行异步请求
Profile.vue

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

5.路由钩子和axios结合图

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值