Vue笔记

Vue是什么

  • Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。

  • Vue 只关注视图层, 采用自底向上增量开发的设计。

  • Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

  • MVVM模型

MVVM拆开来即为Model-View-ViewModel,有View,ViewModel,Model三部分组成。View层代表的是视图、模版,负责将数据模型转化为UI展现出来。Model层代表的是模型、数据,可以在Model层中定义数据修改和操作的业务逻辑。ViewModel层连接Model和View。

在MVVM的架构下,View层和Model层并没有直接联系,而是通过ViewModel层进行交互。ViewModel层通过双向数据绑定将View层和Model层连接了起来,使得View层和Model层的同步工作完全是自动的。因此开发者只需关注业务逻辑,无需手动操作DOM,复杂的数据状态维护交给MVVM统一来管理。

Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

Vue安装

  • 独立版本

我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入。

  • 使用 CDN 方法

以下推荐国外比较稳定的两个 CDN,国内还没发现哪一家比较好,目前还是建议下载到本地。

Staticfile CDN(国内) : https://cdn.staticfile.org/vue/2.2.2/vue.min.js
unpkg:https://unpkg.com/vue@2.6.14/dist/vue.min.js。
cdnjs : https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.min.js

  • NPM 方法

通过webpack和CLI的使用

Vue基本语法

v-html 于输出 html 代码

<div id="app">
    <div v-html="message"></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>    
<script>
new Vue({
  el: '#app',
  data: {
    message: '<h1>ws6tg</h1>'
  }
})
</script>

v-bind HTML属性中的值

<div id="app">
  <span v-bind:title="message">这里是message</span>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>   
<script>
new Vue({
    el: '#app',
  data:{
      message: "hhh"
  }
});
</script>

v-if 条件判断

<div id="app">
    <p v-if=ok>可见</p>
    <p v-else>不可见
    
    <p v-if="choose==='A'">A</p>
    <p v-else-if="choose==='B'">B</p>
    <p v-else>O</p>
</div>

<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
    var vm=new Vue({
        el: '#app',
        data: {
            ok: true,
            choose: "A"
        }
    })
</script>

v-for 循环

v-for 指令需要以 item in items形式的特殊语法, items是源数据数组并且 item是数组元素迭代的别名。

<div id="app">
    <li v-for="item in items">
        名字:{{item.name}},信息:{{item.message}}
    </li>
</div>

<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
    var vm=new Vue({
        el: '#app',
        data: {
            items: [
                {name: "item1",message: "message1"},
                {name: "item2",message: "message2"},
                {name: "item3",message: "message3"},
            ]
        }
    })
</script>

v-for还可以迭代对象属性,迭代整数

<li v-for="value in object">
<li v-for="(value, key, index) in object">
<li v-for="n in 10">

v-on 绑定事件

<div id="app">
    <!-- `greet` 是在下面定义的方法名 -->
    <button v-on:click="greet">Greet</button>
</div>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            name: 'Vue.js'
        },
        // 在 `methods` 对象中定义方法
        methods: {
            greet: function (event) {
                // `this` 在方法里指当前 Vue 实例
                alert('Hello ' + this.name + '!')
                // `event` 是原生 DOM 事件
                if (event) {
                    alert(event.target.tagName)
                }
            }
        }
    })
    // 也可以用 JavaScript 直接调用方法
    // app.greet() // -> 'Hello Vue.js!'
</script>

v-model 双向绑定

v-model 会根据控件类型自动选取正确的方法来更新元素。

  • 输入框
<div id="app">
    <p>input 元素:</p>
    <input v-model="message1" placeholder="编辑我……">
    <p>消息是: {{ message1 }}</p>

    <p>textarea 元素:</p>
    <p style="white-space: pre">{{ message2 }}</p>
    <textarea v-model="message2" placeholder="多行文本输入……"></textarea>
</div>

<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            message1: '',
            message2: ''
        }
    })
</script>
  • 复选框
<div id="app">
    <p>单个复选框:</p>
    <input type="checkbox" id="checkbox" v-model="checked">
    <label for="checkbox">{{ checked }}</label>

    <p>多个复选框:</p>
    <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
    <label for="runoob">Runoob</label>
    <input type="checkbox" id="google" value="Google" v-model="checkedNames">
    <label for="google">Google</label>
    <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
    <label for="taobao">taobao</label>
    <br>
    <span>选择的值为: {{ checkedNames }}</span>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            checked : '',
            checkedNames: []
        }
    })
</script>
  • 单选框
<div id="app">
    <input type="radio" id="baidu" value="baidu" v-model="picked">
    <label for="baidu">Baidu</label>
    <br>
    <input type="radio" id="google" value="Google" v-model="picked">
    <label for="google">Google</label>
    <br>
    <span>选中值为: {{ picked }}</span>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            picked : ''
        }
    })
</script>
  • 下拉框
 <div id="app">
    <select v-model="selected" name="fruit">
        <option value="">选择一个网站</option>
        <option value="www.baidu.com">Baidu</option>
        <option value="www.google.com">Google</option>
    </select>

    <div id="output">
        选择的网站是: {{selected}}
    </div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            selected: ''
        }
    })
</script>

Vue组件(component)

在这里插入图片描述

<div id="app">
    <website-item v-for="item in sites" v-bind:website="item"></website-item>
</div>

<script>
    Vue.component('website-item', {
        props: ['website'],
        template: '<li><a v-bind:href="website.url">{{ website.text }}</a></li>'
    })
    new Vue({
        el: '#app',
        data: {
            sites: [
                { text: 'Baidu' ,url: "http://www.baidu.com"},
                { text: 'Google',url: "http://www.google.com" },
                { text: 'Taobao',url: "http://www.taobao.com" }
            ]
        }
    })
</script>

Axios

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

安装方法

  • 使用 cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
  • 使用 npm:
$ npm install axios
  • 使用 bower:
$ bower install axios
  • 使用 yarn:
$ yarn add axios

使用

  • package.json文件
{
  "data": {
    "name": "网站",
    "num": 3,
    "isSuccess": true,
    "sites": [
      {
        "name": "Google",
        "info": [
          "Android",
          "Google 搜索",
          "Google 翻译"
        ]
      },
      {
        "name": "Baidu",
        "info": [
          "搜索",
          "李彦宏",
          "广告"
        ]
      },
      {
        "name": "Taobao",
        "info": [
          "淘宝",
          "网购"
        ]
      }
    ]
  }
}
  • html代码
<div id="app">
    <h1>网站列表</h1>
    <div v-for="site in info">
        {{ site.name }}
        <li v-for="i in site.info">{{i}}</li>
    </div>
</div>

<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<!--导入axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type = "text/javascript">
    new Vue({
        el: '#app',
        data () {
            return {
                info: null
            }
        },
        mounted () {
            axios
                .get('../package.json')
                .then(response => (this.info = response.data.data.sites))
                .catch(function (error) { // 请求失败处理
                    console.log(error);
                });
        }
    })
</script>
  • 效果
    在这里插入图片描述

计算属性

计算属性关键词: computed。
计算属性在处理一些复杂逻辑时是很有用的。

computed vs methods
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
使用

<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
 
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

插槽(内容分发)

<div id="app">
    <todo>
        <todo-title slot="todo-title" v-bind:ptitle="title"></todo-title>
        <todo-items slot="todo-items" v-for="item in todoItems" v-bind:pitem="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>
    //slot 插槽 这个组件要定义在前面不然出不来数据
    Vue.component("todo", {
        template: '<div>\
                    <slot name="todo-title"></slot>\
                    <ul><slot name="todo-items"></slot></ul>\
                    </div>'
    });
    Vue.component("todo-title", {
        //属性
        props:["ptitle"],
        template: '<span>{{ptitle}}</span>'
    });
    Vue.component("todo-items", {
        props: ["pitem"],
        template: '<li>{{pitem}}</li>'
    });
    let vm = new Vue({
        el: "#app",
        data: {
            //标题
            title: "图书馆系列图书",
            //列表
            todoItems: ['三国演义', '红楼梦', '西游记', '水浒传']
        }
    });
</script>

在这里插入图片描述

自定义事件

父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

<div id="app">
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>
 
<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>

vue-cli

什么是vue-cli

vue-cli 官方提供的一个脚手架,用于快速生成一个 vue 的项目模板;
预先定义好的目录结构及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速;

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

需要的环境

Node.js : http://nodejs.cn/download/
Git : https://git-scm.com/downloads
镜像:https://npm.taobao.org/mirrors/git-for-windows/

npm使用

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

npm i module_name

会把moudule_name包安装到node_modules目录中
不会修改package.json
之后运行npm i命令时,不会自动安装moudule_name

npm i module_name -g

安装模块到全局,不会在项目node_modules目录中保存模块包。
不会将模块依赖写入devDependencies或dependencies 节点。
运行 npm i 初始化项目时不会下载模块。

npm i module_name -S(npm i module_name --save)

会把moudule_name包安装到node_modules目录中
会在package.json的dependencies属性下添加moudule_name
之后运行npm i命令时,会自动安装moudule_name到node_modules目录中
之后运行npm i --production或者注明NODE_ENV变量值为production时,会自动安装msbuild到node_modules目录中,即是在线上环境运行时会将包安装

npm i module_name –D(npm i module_name --save-dev)

会把moudule_name包安装到node_modules目录中
会在package.json的devDependencies属性下添加moudule_name
之后运行npm i命令时,会自动安装moudule_name到node_modules目录中
之后运行npm i –production或者注明NODE_ENV变量值为production时,不会自动安装moudule_name到node_modules目录中

安装vue脚手架

npm install vue-cli -g

新建项目

硬盘上找一个文件夹放工程用的,在终端中进入该目录

cd 目录路径

根据模板创建项目并运行(管理员模式)

vue init webpack-simple 工程名字<工程名字不能用中文>
npm install
npm run dev

Webpack

什么是webpack

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

安装webpack

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

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

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

webpack -v
webpack-cli -v

使用Webpack

  • 先创建一个包 交由idea打开 会生成一个.idea文件 那么就说明该文件就交由idea负责

  • 在idea中创建modules包,再创建hello.js,hello.js 暴露接口 相当于Java中的类

//暴露一个方法
exports.sayHi = function () {
    document.write("<h1>hello</h1>>")
}
  • 创建main.js 当作是js主入口 , main.js 请求hello.js 调用sayHi()方法
var hello = require("./hello");
hello.sayHi()
  • 在主目录创建webpack-config.js , webpack-config.js 这个相当于webpack的配置文件
module.exports = {
	//enrty请求main.js的文件
    entry: './modules/main.js',
    //output是输出的位置和名字
    output: {
        filename: './js/bundle.js'
    }
}
  • 在idea命令台输入webpack命令(idea要设置管理员启动)

  • 完成上述操作之后会在主目录生成一个dist文件 生成的js文件夹路径为/ dist/js/bundle.js

  • 在主目录创建index.html 导入bundle.js

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

vue-router路由

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

- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue.js过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的CSS class的链接
- HTML5历史模式或hash模式,在IE9中自动降级
- 自定义的滚动条行为
  • 安装命令
npm install vue-router@3.2.0 --save-dev
  • 项目结构
    在这里插入图片描述

  • index.html(网页入口)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>myvue1</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- 绑定id:app-->
  </body>
</html>
  • main.js
import Vue from 'vue'
import App from './App'//引入App.vue
import router from './router'
// 1.首先寻找目录下有没有router.js或者router.node,如果有就导入
// 2.如果没有看是否有router目录,如果没有就require失败,抛出异常"Cannot find module './router'"
// 3.如果有router目录会在其下寻找package.json文件,如果有则按照package的配置来导入
// 4.如果没有package.json,看是否有index.js或者index.node,如果有就导入没有就失败

Vue.config.productionTip = false

Vue.use(router)//使用路由分发
/* eslint-disable no-new */
new Vue({
  el: '#app',//绑定到index.html
  router,
  components: { App },
  template: '<App/>'
})
  • App.vue文件
<template>
  <div id="app">
    <h1>Vue</h1>
    <!-- 路由分发 to="/main"是router/index.js中的routes的path-->
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {

  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
  • router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Content from "../components/Content";
import Main from "../components/Main";

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

//配置导出路由
export default new VueRouter({
  routes: [
    {
      //路由路径
      path: '/content',
      name: 'content',
      //跳转的组件
      component: Content
    },
    {
      //路由路径
      path: '/main',
      name: 'main',
      //跳转的组件
      component: Main
    }
  ]
})
  • Content.vue(Main.vue)
<template>
  <h1>内容</h1>
</template>

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

Vue+elementUI

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

    版本不兼容报错,使用以下版本

      "sass-loader": "^7.0.3",
      "node-sass": "^4.0.0",
    

    安装modules与nodejs版本不兼容报错,使用nvm管理nodejs版本

    nvm install 7.9.0
    nvm use 7.9.0
    npm install node-sass@4.0.0
    
  • 目录结构
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/013e5dd8a13c449ea4a67b14586b7ba9.png

  • views/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>

  • 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/user/Profile.vue
<template>
  <h1>个人信息</h1>
</template>
<script>
export default {
  name: "UserProfile"
}
</script>
<style scoped>
</style>
  • view/user/List.vue
<template>
  <h1>用户列表</h1>
</template>
<script>
export default {
  name: "UserList"
}
</script>
<style scoped>
</style>
  • router/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 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
    }
  ]
});

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

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

new Vue({
  el: '#app',
  router,
  render: h => h(App),//ElementUI规定这样使用
})
  • App.vue
<template>
  <div id="app">
    <router-link to="/login">login</router-link>
    <router-view></router-view>
  </div>
</template>

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

参数传递

  • 前端传递参数

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

<!--name:传组件名 params:传递参数,需要绑定对象:v-bind-->
<router-link v-bind:to="{name: 'UserProfile', params: {id: 1}}">个人信息</router-link>
  • 修改路由配置,增加props:true属性
    ​ 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符
{
	  path: '/user/profile/:id',
	  name: 'UserProfile',
	  component: UserProfile,
	  props:true
}
  • 前端显示

在要展示的组件Profile.vue中接收参数

<template>
  <div>
    个人信息
    {{ id }}
  </div>
</template>
<script>
    export default {
      props: ['id'],
      name: "UserProfile"
    }
</script>
<style scoped>
</style>
  • 组件重定向

​重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下,比如:

​在router下面index.js的配置

{
  path: '/main',
  name: 'Main',
  component: Main
},
{
  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>

路由钩子与异步请求

  • 路由模式有两种

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

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

export default new Router({
  mode: 'history',
  routes: [
  ]
});
  • 404界面

创建一个NotFound.vue视图组件

<template>
    <div>
      <h1>404,你的页面走丢了</h1>
    </div>
</template>
<script>
    export default {
        name: "NotFound"
    }
</script>
<style scoped>
</style>

修改路由配置index.js

import NotFound from '../views/NotFound'
{
   path: '*',
   component: NotFound
}
  • 路由钩子与异步请求

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

在Profile.vue中写:

export default {
    name: "UserProfile",
    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
cnpm install --save vue-axios
  • main.js引用 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
  • 准备数据
    只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。
    数据和之前用的json数据一样 需要的去上述axios例子里
// 静态数据存放的位置
static/mock/data.json
  • 在 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)
        })
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值