vue的学习与使用

目录

基础语法

判断与循环v-if v-else for

if

for

事件 v-on

Vue双向绑定

Vue组件

计算属性

插槽 slot

自定义事件内容分发

创建一个vue程序

Webpack

什么是webpack?

安装Webpack

Vue-router路由

测试路由

Vue+ElementUI

路由嵌套

参数传递及重定向

重定向

路由模式与404

路由模式有两种:

添加404页面

路由钩子


基础语法

判断与循环v-if v-else for

if

<div id="app">
    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
</div>

<script>
    var vm=new Vue({
        el:"#app",
        data: {
            ok: true
        }
    });
</script>
<div id="app">
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">B</h1>
    <h1 v-else>C</h1>
</div>

<script>
    var vm=new Vue({
        el:"#app",
        data: {
            type: "A"
        }
    });
</script>

for

<div id="app">
    <!--
    in 相当于forEach中的冒号“:” 也可以这么写
    v-for="(item,index) in items"   index是下标
    -->
    <li v-for="item in items">
        {{item}}
    </li>
</div>

<script>
    var vm=new Vue({
        el:"#app",
        data: {
            items:[
                {message: "五十六精研"},
                {message: "wsljy"},
                {str: 123}
            ]
        }
    });
</script>

事件 v-on

需要引入
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">

<div id="app">
    <button v-on:click="show">clikc me</button>
</div>

<script>
    var vm=new Vue({
        el:"#app",
        data: {
            message: "五十六精研"
        },
        methods: {//方法必须放在 vue的methods对象中
            show: function(){
                alert(this.message);
            }
        }
    });
</script>

Vue双向绑定

v-model

<div id="app">
    请输入文本:<input type="text" v-model="message" > {{message}}
</div>

<div id="app2">
    性别:
    <input name="sex" type="radio" value="男" v-model="sex">男
    <input name="sex" type="radio" value="女" v-model="sex">女
    <br/>
    已选中的性别:{{sex}}
<!--导入vue.js-->
</div>

<div id="app3">
    请选择:
    <select v-model="selected">
        <option value="" disabled >--请选择--</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <br/>
    value:{{selected}}
    <!--导入vue.js-->
</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: "123"
        }
    });
    var vm =new Vue({
        el: "#app2",
        data: {
            sex: "女"//可以设置为默认值
        }
    });
    var vm =new Vue({
        el: "#app3",
        data: {
            selected: ""//可以设置为默认值
        }
    });
</script>

双向绑定后视图可以改变数据

Vue组件

<div id="app">
    <ljy v-for="item in items" v-bind:li="item"></ljy><!--注意items不要打错  itmes-->
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //注册一个组件 第一个参数是组件名,第二个是组件对象
    Vue.component("ljy",{
        props: ['li'],
        template: "<li>{{li}}</li>"//注意template不要打错  成tempate
    });

    var vm=new Vue({
        el:"#app",
        data: {//注意data不要打错  date
            items: ["JAVA","Linux","C#"]
        }
    });

</script>

组件就像是自定义的标签 组件 Vue.component要放在var vm=new Vue的上面,不然无效

Ajax异步通信

创建一个data.json文件

{
  "name": "cqh",
  "age": "18",
  "sex": "男",
  "url":"https://www.baidu.com",
  "address": {
    "street": "缇香郡",
    "city": "宁波",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://www.bilibili.com"
    },
    {
      "name": "baidu",
      "url": "https://www.baidu.com"
    },
    {
      "name": "cqh video",
      "url": "https://www.4399.com"
    }
  ]
}

<div id="app">
    <div>
        {{info}}
        {{info.name}}
        {{info.sex}}
    </div>
    <a v-bind:href="info.url">点击我</a>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<!--导入axios-->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
    var vm =new Vue({
        el: "#app",
        //和data: 不同 属性:vm
        data(){
            return{
                info: {
                    //测试后写不写都行
                    /*name: null,
                    age: null,
                    url: null*/
                }
            }
        },
        mounted(){
            //钩子函数 链式编程 ES6新特性
            //get获取文件后,then转到括号里,response类似一个文件的集合,其中data文件在这个集合里,
            axios.get("../data.json").then(response=>(this.info=response.data));
        }
    });
</script>

注意点:info要写在data()下的return{}里, response才能访问到info。 axios.get("文件路径")文件路径要看好 data:与data()不同

计算属性

<div id="app">
    <p>createtime1:{{createtime1()}}</p>
    <p>createtime2:{{createtime2}}</p>
</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: {
            msg: "123"
        },
        methods: {
            createtime1: function(){
                return Date.now();//返回一个时间戳
            }
        },
        computed: {
            createtime2: function(){//计算属性  不能和methods里的方法重名 不然会调用methods里的方法
                return Date.now();
            }
        }
    });
</script>

createtime1()的效果与createtime2一样,计算属性已属性为主。

插槽 slot

<div id="app">
    <todo>
        <!--注意不要在titl后面在打一个:冒号-->
        <todo-title slot="todo-title" v-bind:titl="title"></todo-title>
        <todo-items slot="todo-items" v-for="item in items" :ite="item"></todo-items>
    </todo>

</div>

<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: ['titl'],
        template: "<h1>{{titl}}</h1>"
    });
    Vue.component("todo-items",{
        props: ['ite'],
        template: "<li>{{ite}}</li>"
    });
    var vm=new Vue({
        el: "#app",
        data: {
            title: "图书列表",
            items:["Java","Pythen","C#"]
        }
    });

</script>

思路是:

  • 先创建一个组件,里面是一个模板,模板里面有几个插槽。
  • 创建插槽需要的组件。 
  • 将创建的模板组件放写在body中
  • 在将插槽需要的组件写在模板组件中
  • 然后配置插槽组件的slot和绑定值

简单来说就是创建 todo,然后将tudo标签下的todo-title与todo-items,插入todo对应的和slot里。

这里的name是插槽的名字也是他的标识

v-bind与:是一样的,:是v-bind的缩写

v-on与@是一样的,@是v-on的缩写

\类似于换行的'+

<todo-title slot="todo-title" v-bind:titl="title"></todo-title> 这段代码中,slot是说明让<todo-title>这个标签放在todo-title这个名字 的插槽里,v-bind:titl="title",是绑定值,其中左边的titl是组件中的props 的值,右边的title是data里的属性值。 左组件,右属性

自定义事件内容分发

<div id="app">
    <todo>
        <!--注意不要在titl后面在打一个:冒号-->
        <todo-title slot="todo-title" v-bind:titl="title"></todo-title>
        <todo-items slot="todo-items" v-for="(item,index) in items"
                    :ite="item" v-bind:index="index" v-on:remove="removeItems(index)" ></todo-items>
    </todo>
</div>

<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: ['titl'],
        template: "<h1>{{titl}}</h1>"
    });
    Vue.component("todo-items",{
        props: ['ite','index'],
        template: "<li>{{index}}--{{ite}} <button @click='remove'>删除</button></li>",
        //只能绑定当前组件的方法
        methods: {
            remove: function(index){
                //自定义事件名,第一个参数自定义事件名,第二个参数是事件参数
                this.$emit("remove",index);
            }
        }
    });
    var vm=new Vue({
        el: "#app",
        data: {
            title: "图书列表",
            items:["Java","Pythen","C#"]

        },
        methods:{
            removeItems: function(index){
                console.log("删除了"+this.items[index]);
                //分割数组的方法
                this.items.splice(index,1);
            }
        }
    });

</script>

在事件中普通事件只能访问vm中methods里的方法, 组件标签中的事件只能访问自己组件中的方法

自定义事件$emit("自定义事件名",参数); 这个思路就是点击删除后,自定义一个事件, v-on:remove中的remove就是自定义的事件名, 在定义了事件名后removeItems(index)方法就会被触发执行 而removeItems方法就是删除这个数据。

创建一个vue程序

需要的环境:

  • Node.js

下载地址: http://nodejs.cn/download/ 安装的时候一直下一步直到结束

确认是否安装成功:

  • 在cmd中运行node -v命令,查看是否能够输出版本号
  • 在cmd中运行npm -v命令,查看是否能够输出版本号

  • 安装node.js淘宝镜像加速器(cnpm)(如果npm命令速度够快可不安装)
# -g 就是全局安装
npm install cnpm -g

# 或使用如下语句解决npm速度慢的问题,但是每次install都需要
npm install --registry=https://registry.npm.taobao.org
  • 安装vue-cli
cnpm install vue-cli -g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list

  • 第一个vue-cli应用程序

找到一个项目路径(空文件夹)
创建一个基于webpack模板的vue应用程序

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

创建过程需要的操作

一路选no

  1. Project name:项目名称,默认回车即可
  2. Project description:项目描述,默认回车即可
  3. Author:项目作者,默认回车即可
  4. Install vue-router:是否安装vue-router,选择n不安装(后期需要再手动添加)
  5. Use ESLint to lint your code:是否使用ESLint做代码检查,选择n不安装(后期需要再手动添加)
  6. Set up unit tests:单元测试相关,选择n不安装(后期需要再手动添加)
  7. Setupe2etests with Nightwatch:单元测试相关,选择n不安装(后期需要再手动添加)
  8. Should we run npm install for you after the,project has been created:创建完成后直接初始化,选择n,我们手动执行;运行结果

 当出现问题时,它会给出提示我们按照提示来就行

  • 初始化并运行
cd vue-test
# npm install 若是太慢可以使用 cnpm install
npm install
npm run dev

访问地址:http://localhost:8080/

关闭:Ctrl+c

Webpack

什么是webpack?

本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(module
bundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency
graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle.
Webpack是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过loader转换,任何形式的资源都可以当做模块,比如CommonsJS.AMD、ES6、css、JSON、CoffeeScript、LESS等;

安装Webpack

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

安装:

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

测试安装成功:

webpack -v
webpack-cli -v

配置:

创建webpack .config.js配置文件

entry: 入口文件,指定WebPack 用哪个文件作为项目的入口

output:输出,指定WebPack把处理完成的文件放置到指定路径

module:模块,用于处理各种类型的文件

plugins:插件,如:热更新、代码重用等r

resolve:设置路径指向

watch:监听,用于设置文件改动后直接打包
 

  • 创建项目

在自己的目录中,新建文件夹webpack-study,然后用IDEA打开

创建一个名为modules的目录,用于放置JS模块等资源文件
在modules下创建模块文件hello.js
//暴露一个方法:sayHi

//暴露一个方法
exports.sayHi1 =function(){
    document.write("<h1>五十六精研1</h1>");
}
exports.sayHi2 =function(){
    document.write("<h1>五十六精研2</h1>");
}
exports.sayHi3 =function(){
    document.write("<h1>五十六精研3</h1>");
}

在modules下创建一个名为main.js的入口文件main.js,用于打包时设置entry属性
//require 导入一个模块,就可以调用这个模块中的方法了

var hello=require("./hello");//不用写后缀名,因为它是一个模块,就像类的类名一样不用在后面添加.java
hello.sayHi1()

在项目目录下创建webpack.config.js配置文件,

module.exports={
    entry: "./modulse/main.js",/*打包的入口,也就是最开始执行宁的文件*/
    output:{
        filename: "./js/bundle.js"/*包的位置*/
    }
}

再命令行中输入“webpack” 打包,打包成功后会生成一个dist文件夹

打包:

说明:打包如果失败,就用管理员权限运行webpack

  • 在项目目录下创建HTML页面,index.html,通过script导入webpack打包后的JS文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>

</html>

补充:

webpack -watch #这个命令相当于热部署,可以实时更新打包

Vue-router路由

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

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

安装
基于第一个vue-cli进行测试学习; 先查看node modules中是否存在vue-router, vue-router是一个插件包, 所以我们还是需要用npm/cnpm来进行安装的

npm install vue-router --save-dev

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

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

Vue.use(VueRouter);

问题解决

npm run dev时候提示好多警告,Router is not found in vue-router,并且无法加载出页面

原因:vue-router的版本太高

解决方案:更换低版本的vue-router

cnpm install vue-router@3.1.3 --save-dev

测试路由

  • 在src目录下新建cpmponents文件夹用于存放我们自己编写的组件
  • 定义自己的组件Content.vue、Main.vue

Content.vue

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

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

<style scoped>

</style>

Main.vue

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

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

<style scoped>

</style>

新建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
    }
  ]
});

在main.js中配置路由(import路由的时候路径写到文件夹即可,因为写的是index.js会被默认扫描)
main.js

import Vue from 'vue'
import App from './App'
import router from './router'  //自动扫描里面的路由配置
Vue.config.productionTip = false;

//显示声明引用VueRouter
new Vue({
  el: '#app',
  //配置路由
  router,
  components: { App },
  template: '<App/>'
})
  • 在app.vue中使用路由
<template>
  <div id="app">
    <!--
      router-link:默认会被渲染成一个<a>标签,to属性为指定链接
      router-view:用于渲染路由匹配到的组件
    -->
    <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>
  • 通过命令npm run dev运行,通过浏览器进行访问

Vue+ElementUI

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

#进入工程目录
cd hello-vue
#安装vue-routern 
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

npm命令说明:

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

问题解决

在最后npm run dev的时候,出现sass版本问题

解决方案:将package.json文件中的"sass-loader": "^7.3.1"版本改成7.3.1

重新执行以下命令:

npm uninstall node-sass
npm i -D sass
  • 用IDEA打开新建的项目,在src下新建routers、views文件夹
  • 说明:
  1. assets:用于存放资源文件
  2. components:用于存放Vue功能组件
  3. views:用于存放Vue视图组件
  4. router:用于存放vue-router配置
  • 在views文件夹下新建Login.vue和Main.vue组件

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>

Main.vue

<template>
<h1>主页</h1>
</template>

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

<style scoped>

</style>
  • 在routers文件夹下新建index.js文件

index.js

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 : '/main',
      name : 'main',
      component: Main
    },
    {
      path: '/login',
      name: 'login',
      component:Login
    }
  ]
});
  • 在main.js中配置路由
import Vue from 'vue'
import App from './App'
import router from './routers'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false

Vue.use(router)
Vue.use(ElementUI)
new Vue({
  el: '#app',
  router,
  render: h => h(App) //ElementUI

})

路由嵌套

  • 新建views下的子组件,user/List.vue、和/user/Profile.vue

List.vue

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

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

<style scoped>

</style>

Profile.vue

<template>
<h1>个人信息</h1>
</template>

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

<style scoped>

</style>

通过在路由配置组件中配置子元素children属性,实现嵌套

index.js

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

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

//其中UserList 与UserPorfile 可以自己命名
import UserList from "../views/user/List";
import UserPorfile from "../views/user/Porfile";

Vue.use(Router);

export default new Router({
  routes:[
    {
      path: "/main",
      component: Main,//嵌套路由 children
      children: [
        {path: "/user/profile",component: UserPorfile},
        {path: "/user/list",component: UserList}
      ]
    },{
      path: "/login",
      component: Login
    }
  ]
});

更新Main.vue中的内容为侧边栏样式内容

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:

前端通过params传递,中间通过router接收,通过$router.params.id展示

(1)前端通过to属性传递参数(注意:要对to属性进行绑定)

name传组件名,params传递参数,需要对象:v-bind

 <!--name 地址需要传递组件名,params传递参数 需要对象 v-bind绑定-->
<router-link :to="{name:'UserPorfile',params:{id: 1,name:'wsljy'}}">个人信息</router-link>

(2)通过路由(index.js)接收

export default new Router({
  routes:[
    {
      path: "/main",
      component: Main,//嵌套路由 children
      children: [
        {
          path: "/user/profile/:id/:name",//注意:不添加/:id/:name也可以传递参数,只是浏览器上不会显示
          name: "UserPorfile",
          component: UserPorfile
        },
        {
          path: "/user/list",
          component: UserList
        }
      ]
    },{
      path: "/login",
      component: Login
    }
  ]
});

(3)在Profile.vue中显示传递的参数

注意:所有的元素不能直接在根节点下,必须至少有一个div标签包裹,否则出错

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

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

<style scoped>

</style>

参数传递方法2:

使用props减少耦合

再嵌套路由中添加props属性,并将其设置为true

export default new Router({
  routes:[
    {
      path: "/main",
      component: Main,//嵌套路由 children
      children: [
        {
          path: "/user/profile/:id/:name",//注意:不添加/:id/:name也可以传递参数,只是浏览器上不会显示
          name: "UserPorfile",
          component: UserPorfile,
          props: true
        },
        {
          path: "/user/list",
          component: UserList
        }
      ]
    },{
      path: "/login",
      component: Login
    }
  ]
});

再Porfile.vue中添加props

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

<script>
    export default {
        props:["id","name"],//再index.js中开启props后就可以直接用对象访问了
        name: "UserPorfile"
    }
</script>

<style scoped>

</style>

此时就可以直接通过props获取传递的参数了

重定向

Vue 中的重定向是作用在路径不同但组件相同的情况

  • 在router/index.js配置重定向路径
export default new Router({
  routes:[
    {
      path: "/main",
      component: Main,//嵌套路由 children
      children: [
        {
          path: "/user/profile/:id/:name",//注意:不添加/:id/:name也可以传递参数,只是浏览器上不会显示
          name: "UserPorfile",
          component: UserPorfile,
          props: true
        },
        {
          path: "/user/list",
          component: UserList
        },{
          path:"/goHome",
          redirect: "/main"//重定向到 /main
        }
      ]
    },{
      path: "/login",
      component: Login
    }
  ]
});
  • 加入一个模块演示即可完成
           <el-menu-item-group>
              <el-menu-item index="1-1">
                <!--插入的地方-->
                <!--name 地址需要传递组件名,params传递参数 需要对象 v-bind绑定-->
                <router-link :to="{name:'UserPorfile',params:{id: 1,name:'wsljy'}}">个人信息</router-link>
              </el-menu-item>
              <el-menu-item index="1-2">
                <!--插入的地方-->
                <router-link to="/user/list">用户列表</router-link>
              </el-menu-item>
              <el-menu-item index="1-3">
                <!--插入的地方-->
                <router-link to="/goHome">回到首页</router-link>
              </el-menu-item>
            </el-menu-item-group>

路由模式与404

路由模式有两种:

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

修改路由配置

index.js

export default new Router({
  mode: "history",//消除浏览器上的#号,hash:有#,history:消除#号
  routes:[]
}

添加404页面

创建NotFound.vue文件

<template>
  <div>
    <h1>404,你的页面走丢了</h1>
  </div>
</template>

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

<style scoped>

</style>

再index.js中配置

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

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

import UserList from "../views/user/List";
import UserPorfile from "../views/user/Porfile";
import NotFound from "../views/NotFound";

Vue.use(Router);

export default new Router({
  mode: "history",//消除浏览器上的#号,hash:有#,history:消除#号
  routes:[
    {
      path: "/main",
      component: Main,//嵌套路由 children
      props: true,
      children: [
        {
          path: "/user/profile/:id/:name",//注意:不添加/:id/:name也可以传递参数,只是浏览器上不会显示
          name: "UserPorfile",
          component: UserPorfile,
          props: true
        },
        {
          path: "/user/list",
          component: UserList
        },{
          path:"/goHome",
          name:"goHome",
          redirect: "/main"//重定向
        }
      ]
    },{
      path: "/login",
      component: Login
    },{
      path: "*",
      component: NotFound
    }
  ]
});

这样在访问不存在的路径时就会跳转到404页面

路由钩子

除了之前的钩子函数还存在两个钩子函数

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

在Porfile.vue中添加

export default {
        props:["id","name"],//再index.js中开启props后就可以直接用对象访问了
        name: "UserPorfile",
        //过滤器
        // =>就是function的简写
        beforeRouteEnter:(to,from,next)=>{//进入路由之前做什么事情
            console.log("进入路由之前");
            next();
        },
        beforeRouteLeave:(to,from,next)=>{//在路由离开之前做什么事情
            console.log("路由离开之前");
            next();
        }
}

参数说明:

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

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

在钩子函数中进行异步请求

  • 安装axios与vue-axios
cnpm install axios -s
cnpm install --save vue-axios
  • main.js引用 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

准备数据:

data.json

{
  "name": "cqh",
  "age": "18",
  "sex": "男",
  "url":"https://www.baidu.com",
  "address": {
    "street": "缇香郡",
    "city": "宁波",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://www.bilibili.com"
    },
    {
      "name": "baidu",
      "url": "https://www.baidu.com"
    },
    {
      "name": "cqh video",
      "url": "https://www.4399.com"
    }
  ]
}

注意: 静态文件要放在static文件夹下

这个路径可以访问到文件:

http://localhost:8080/static/mock/data.json

  • 在 beforeRouteEnter 中添加异步请求
<script>
    export default {
        props:["id","name"],//再index.js中开启props后就可以直接用对象访问了
        name: "UserPorfile",
        //过滤器
        // =>就是function的简写
        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>

访问Porfile.vue文件即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值