Vue入门

Vue

1、概述

  • 一套用于构建用户界面的渐进式JavaScript框架
  • 自底向上逐层应用
  • Vue 的核心库只关注视图层
  • 核心就是实现了DOM监听与数据绑定
  • 官网:https://cn.vuejs.org/v2/guide/

2、MVVM

  • MVVM(Model-View-ViewModel)是一种软件设计模式
  • 是一种简化用户界面的事件驱动编程方式
  • 源于MVC,核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用
  • Model:模型层, 在这里表示JavaScript对象
  • View:视图层, 在这里表示DOM(HTML操作的元素)
  • ViewModel:连接视图和数据的中间件, Vue.js就是MVVM中的View Model层的实现者
  • ViewModel 层作用:
    • 向上与视图层进行双向数据绑定
    • 向下与Model层通过接口请求进行数据交互
  • 优点:
    • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
    • 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
    • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
    • 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。

在MVVM架构中, 是不允许数据和视图直接通信的, 只能通过ViewModel来通信, 而View Model就是定义了一个Observer观察者

3、HelloVue

3.1、CDN

<script src=“https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js”></script>`
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

3.2、HelloVue.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello,vue!</title>
</head>
<body>
<!--view 层-->
<!--将数据绑定到页面元素-->    
<div id="app">
    {{message}}
</div>
</body>
<!--引入js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
    //Vue实例
    var vm = new Vue({
        el:"#app",//绑定元素id
        //model 层
        data:{
            message:"hello,vue!"//数据对象中有一个名为message的属性,并设置了初值
        }
    });
</script>
</html>

3.3、测试

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

4、基础语法指令

**注意:*使用 v- 属性绑定数据是不需要 双花括号 包裹的

4.1、v-bind

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bind</title>
</head>
<body>
<div id="app">
    <span v-bind:title="message">鼠标悬停查看绑定的提示信息</span>
</div>
</body>
<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: '页面加载于' + new Date().toLocaleString()
        }
    })
</script>
</html>

将这个元素节点的title特性和Vue实例的message属性保持一致

4.2、v-if,v-else

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-if,else</title>
</head>
<body>
<div id="app">
    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data:{
            ok: true
        }
    })
</script>
</html>

控制台可以输入 vm.data.ok/vm.ok 进行改变

4.3、v-else-if

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-else-if</title>
</head>
<body>
<div id="app">
    <h1 v-if="type === 'A'">A</h1>
    <h1 v-else-if="type === 'B'">B</h1>
    <h1 v-else>C</h1>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data:{
            type: ""
        }
    })
</script>
</html>

4.4、v-for

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <li v-for="(item,index) in items">
        {{item.message}}--{{index}}
    </li>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            items:[
                {message:"Java"},
                {message:"Spring"},
                {message:"Vue"}
            ]
        }
    })
</script>
</html>
  • items 是数组,item 是数组元素迭代的别名
  • 控制台输入 vm.items.push({message:‘study’}) 可以追加数据,增加输出

4.5、v-on

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-on</title>
</head>
<body>
<div id="app">
    <button v-on:click="sayHi">点我</button>
</div>
</body>
<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: "hello!"
        },
        methods: {
            sayHi:function (event) {
                //this 指向当前 vue 实例
                alert(this.message);
            }
        }
    })
</script>
</html>
  • v-on监听事件,事件有Vue的事件、和前端页面本身的一些事件
  • 事件绑定到实例的 methods

5、双向绑定

​ 可以用 v-model 指令在表单、及元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇, 但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

​ **注意:**v-model 会忽略所有表单元素的 valuecheckedselected 特性的初始值而总是将 Vue实例的数据作为数据来源。应该通过 JavaScript 在组件的 data 选项中声明初始值!

5.1、单行文本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单行文本</title>
</head>
<body>
<div id="app">
    输入的文本为:<input type="text" v-model="message">{{message}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var cm = new Vue({
        el: "#app",
        data: {
            message: ""
        }
    })
</script>
</html>

5.2、多行文本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多行文本</title>
</head>
<body>
<div id="app">
    多行文本:<textarea type="text" v-model="message"></textarea>
    多行文本是:{{message}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var cm = new Vue({
        el: "#app",
        data: {
            message: "hello"
        }
    })
</script>
</html>

5.3、单复选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单复选框</title>
</head>
<body>
<div id="app">
    单复选框:<input type="checkbox" v-model="checked">{{checked}}
    <label>{{checked}}</label>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var cm = new Vue({
        el: "#app",
        data: {
            checked: true
        }
    })
</script>
</html>

5.4、多复选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多复选框</title>
</head>
<body>
<div id="app">
    多复选框:
    <input type="checkbox" value="Jack" v-model="checkedNames">
    <label>Jack</label>
    <input type="checkbox" value="Join" v-model="checkedNames">
    <label>join</label>
    <input type="checkbox" value="Mike" v-model="checkedNames">
    <label>Mike</label>
    <span>选中的值:{{checkedNames}}</span>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var cm = new Vue({
        el: "#app",
        data: {
            checkedNames: []
        }
    })
</script>
</html>

5.5、单选按钮

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单选按钮</title>
</head>
<body>
<div id="app">
    单选框按钮
    <input type="radio" value="One" v-model="picked">
    <label>One</label>
    <input type="radio" value="Two" v-model="picked">
    <label>Two</label>
    <span>选中的值:{{picked}}</span>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var cm = new Vue({
        el: "#app",
        data: {
            picked:''
        }
    })
</script>
</html>

5.6、下拉框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下拉框</title>
</head>
<body>
<div id="app">
    下拉框:
    <select v-model="pan">
        <option value="" disabled>---请选择---</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>D</option>
    </select>
    <span>value:{{pan}}</span>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var cm = new Vue({
        el: "#app",
        data: {
            pan:""
        }
    })
</script>
</html>

v-model 表达式的初始值未能匹配任何选项,元系将被渲染为“未选中”状态。 在iOS中, 这会使用户无法选择第一个选项,因为这样的情况下,iOS不会触发change事件。因此,添加像上面这样提供一个值为空的禁用选项。

6、component

6.1、第一个 component

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>component</title>
</head>
<body>
<div id="app">
    <yuan></yuan>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //注册组件
    Vue.component("yuan",{
        template: '<li>Hello</li>'
    })
    //实例化vue
    var vm = new Vue({
        el: "#app"
    })
</script>
</html>
  • Vue.component() :注册组件
  • yuan :自定义组件名称
  • template :组件模板

6.2、props 传参

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>props</title>
</head>
<body>
<div id="app">
    <yuan v-for="item in items" v-bind:list="item"></yuan>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //注册组件
    Vue.component("yuan",{
        props: ['list'],
        template: '<li>{{list}}</li>'
    })
    //实例化vue
    var vm = new Vue({
        el: "#app",
        data: {
            items: ["Java","Spring","Vue"]
        }
    })
</script>
</html>

注意:默认规则下props属性里的值不能为大写;

  • **v-for=“item in items”:**遍历 Vue 实例中定义的名为 items 的数组,并创建同等数量的组件
  • **v-bind:list=“item”:**将遍历 item 项绑定到组件中 props 定义名为 list 属性上;= 号左边的 list 为props定义的属性名,右边的为 item in items 中遍历的 item 项的值

7、Axios

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Axios</title>
    <style>
        /*v-cloak解决闪烁问题*/
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="app" v-cloak>
    <div>地名:{{info.name}}</div>
    <div>地址:{{info.address.country}}--{{info.address.city}}--{{info.address.street}}</div>
    <div>链接:<a v-bind:href="info.url">{{info.url}}</a> </div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{},
        data(){
            return{
                info: {
                    name: null,
                    address: {
                        country: null,
                        city: null,
                        street: null
                    },
                    url: null
                }
            }
        },
        //钩子函数
        mounted(){
            axios.get('../data.json').then(reponse=>(
                this.info = reponse.data
            ))
        }
    })
</script>
</html>
  • v-cloak 解决页面闪烁问题(不会出现{{message}}这样的信息)
  • v-bind 将 a:href 的属性值与 Vue 实例中的数据进行绑定

8、生命周期

Vue实例有一个完整的生命周期,也就是从开始创建初始化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
  在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GeawhNtp-1622694026241)(https://z3.ax1x.com/2021/05/12/g0C1Bj.png)]

9、computed

​ 计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),可以想象为缓存

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>compute</title>
</head>
<body>
<div id="app">
    <p>currentTime1:{{currentTime1()}}</p>
    <p>currentTime2:{{currentTime2}}</p>
</div>
</body>
<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: "message"
        },
        methods:{
            currentTime1:function () {
                return Date.now();
            }
        },
        computed:{
            currentTime2:function () {
                this.message;
                return Date.now();
            }
        }
    })
</script>
</html>
  • methods :方法
  • computed :属性,this.message是为了能够让currentTime2观察到数据变化而变化
  • 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用 vm.message=”xxx", 改变下数据的值,再次测试观察效果
  • 调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销

10、slot

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Slot</title>
</head>
<body>
    <div id="app">
        <yuan>
            <yuan-title slot="yuan-title" :title="study"></yuan-title>
            <yuan-items slot="yuan-items" v-for="(item,index) in yuanItems" v-bind:item="item" v-bind:index="index"></yuan-items>
            <!--简写-->
            <yuan-items slot="yuan-items" v-for="(item,index) in yuanItems" :item="item" :index="index"></yuan-items>
        </yuan>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //插槽组件
    Vue.component('yuan',{
        template:'<div>\
                        <slot name="yuan-title"></slot>\
                        <ul>\
                            <slot name="yuan-items"></slot>\
                        </ul>\
                  </div>'
    });
    //标题组件
    Vue.component('yuan-title',{
        props: ['title'],
        template: '<div>{{title}}</div>'
    });
    //内容组件
    Vue.component('yuan-items',{
        props: ['item','index'],
        template:"<li>{{index+1}},{{item}}</li>"
    });
    //实例化Vue初始化数据
    var vm = new Vue({
        el: "#app",
        data: {
            study: 'goodstudy',
            yuanItems:['Java','Spring','Vue']
        }
    })
</script>
</html>

11、emit

​ 组件删除 Vue 实例数据,this.$emit(‘事件名’,参数)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>emit</title>
</head>
<body>
    <div id="app">
        <yuan>
            <yuan-title slot="yuan-title" :title="study"></yuan-title>
            <!--<yuan-items slot="yuan-items" v-for="(item,index) in yuanItems" v-bind:item="item" v-bind:index="index"></yuan-items>-->
            <!--简写-->
            <yuan-items slot="yuan-items"
                        v-for="(item,index) in yuanItems"
                        :item="item" :index="index" :key="index"
                        @remove="removeItem(index)"></yuan-items>
            <!--@remove 绑定自定义事件 @ = v:on -->
        </yuan>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    //插槽组件
    Vue.component('yuan',{
        template:'<div>\
                        <slot name="yuan-title"></slot>\
                        <ul>\
                            <slot name="yuan-items"></slot>\
                        </ul>\
                  </div>'
    });
    //标题组件
    Vue.component('yuan-title',{
        props: ['title'],
        template: '<div>{{title}}</div>'
    });
    //内容组件
    Vue.component('yuan-items',{
        props: ['index','item'],
        template:`<li>{{index}}——{{item}}<button @click="remove">删除</button></li>`,
        methods: {
            remove:function (index){
                //调用自定义事件方法
                //remove为自定义方法名
                this.$emit('remove',index)
            }
        }

    });
    var vm = new Vue({
        el: "#app",
        data: {
            study: 'goodstudy',
            yuanItems:['Java','Spring','Vue']
        },
        methods: {
            removeItem:function (index){
                console.log("删除了" + this.yuanItems[index])
                this.yuanItems.splice(index,1);
            }
        }
    })
</script>
</html>

gD9bng.png

12、vue-cli

12.1、安装

  1. 安装 nodejs:http://nodejs.cn/download/

  2. node-v , npm-v 测试

  3. 环境配置:

    • 这里的环境配置主要配置的是npm安装的全局模块所在的路径,以及缓存cache的路径,之所以要配置,是因为以后在执行类似:npm install express [-g] (后面的可选参数-g,g代表global全局安装的意思)的安装语句时,会将安装的模块安装到【C:\Users\用户名\AppData\Roaming\npm】路径中,占C盘空间

    • 在 D:\nodejs 下创建两个文件夹 【node_global】及【node_cache】

    • 输入命令:

      npm config set prefix "D:\nodejs\node_global"
      npm config set cache "D:\nodejs\node_cache"
      
    • 配置环境变量:

      • 新建系统变量:NODE_PATH:D:\nodejs\node_global\node_modules
      • 将用户变量 Path 修改为 D:\nodejs\node_global
      • 添加变量 Path :D:\nodejs\node_global
  4. 安装淘宝镜像加速器 Cnpm:npm install cnpm -g

  5. 安装 vue-cli:cnpm install vue-cli -g

  6. vue-list 测试

12.2、使用

  • 创建一个基于webpack模板的vue应用程序:vue init webpack myvue

说明:

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

初始化:

cd myvue
npm install

运行:

npm run dev

13、webpack

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

13.1、安装

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

13.2、使用

  1. 建一个项目

  2. 建一个 modules 包

  3. hello.js

    //暴露方法
    exports.sayHi = function () {
        document.write("<h1>webpack</h1>")
    }
    
  4. main.js

    //require 导入一个模块,就可以调用该模块的方法
    var hello = require("./hello");
    hello.sayHi();
    
  5. webpack.config.js

    module.exports = {
        entry:'./modules/main.js',
        output:{
            filename: "./js/bundle.js"
        }
    };
    
  6. webpack打包

    生成 dist/js/bundle.js 文件

  7. index.html

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

14、vue-router

​ 路由管理器

14.1、安装

  1. 先查看 node modules 中是否存在 vue-router

  2. 在当前目录下进行安装该插件

    npm install vue-router --save-dev
    

14.2、使用

  • 新建 components 文件夹,创建组件

Main.vue

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

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

<style scoped>

</style>

Content.vue

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

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

<style scoped>

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

  • main.js 使用路由
import Vue from 'vue'
import App from './App'
import VueRouter from "vue-router";
import router from './router'//自动扫描里面路由配置

Vue.config.productionTip = false

//使用路由
Vue.use(VueRouter)
new Vue({
  el: '#app',
  //配置路由
  router,
  components: { App },
  template: '<App/>'
})
  • App.vue 使用组件
<template>
  <div id="app">
    <h1>Vue</h1>
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <!--展示视图-->
    <router-view></router-view>
  </div>
</template>
<script>
import Content from "./components/Content";
import Main from "./components/Main";
export default {
  name: 'App',
  components:{
    Content,
    Main
  }
}
</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>

15、elementUI

依赖

#进入工程目录
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

启动失败,可能是 sass-loader 版本过高,需要回退版本,修改 package.json 文件 “sass-loader”: “^7.3.1”,重新 install

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为该命令的缩写

15.1、Views

15.1.1、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%">
      <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>
15.1.2、Main.vue
<template>
  <h1>首页</h1>
</template>

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

<style scoped>

</style>

15.2、router

index.js

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

import Main from "../views/Main";
import Login from "../views/Login";
Vue.use(VueRouter);

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

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

15.4、main.js

import Vue from 'vue'
import App from './App'

import router from './router'//自动扫描里面路由配置
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

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

地址栏输入 login 进入

16、路由嵌套

routes:[
    {
      path: '/main',
      component: Main,
      //嵌套路由
      children: [
        {
          path: '/user/profile',
          name: 'UserProFile',
          component:UserProFile,
        },
        {
          path: '/user/List',
          component: UserList}
      ]
    },
    {
      path: '/login',
      component: Login
    },
    //重定向
    {
      path: '/goHome',
      redirect: '/main'
    }
  ]

17、参数传递

17.1、第一种方式

Main.Vue

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

index.js

path: '/main',
      component: Main,
      //嵌套路由
      children: [
        {
          path: '/user/profile/:id',
          name: 'UserProFile',
          component:UserProFile,
        },
        {
          path: '/user/List',
          component: UserList}
      ]

ProFile.Vue

<template>
  <div>
    <h1>个人信息</h1>
    {{$route.params.id}}
  </div>
</template>
<script>
export default {
  name: "UserProFile"
}
</script>

<style scoped>

</style>

17.2、第二种方式

Main.Vue

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

index.js

path: '/main',
      component: Main,
      //嵌套路由
      children: [
        {
          path: '/user/profile',
          name: 'UserProFile',
          component:UserProFile,
          props: true
        },
        {
          path: '/user/List',
          component: UserList}
      ]

ProFile.Vue

<template>
  <div>
    <h1>个人信息</h1>
    {{id}}
  </div>

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

<style scoped>

</style>

18、路由模式

18.1、hash

  • 默认方式,路径带 # 符号,如 http://localhost/#/login

18.2、history

  • 路径不带 # 符号,如 http://localhost/login
export default new Router({
  mode: 'history',
  routes: []
})

19、404

创建 NotFound.vue 视图组件

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

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

<style scoped>

</style>

修改路由配置文件

import NotFound from "../views/NotFound";

    //404
    {
      path: '*',
      component: NotFound
    }

20、路由钩子

20.1、参数方法

**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 是组件实例

20.2、异步请求

  1. 安装 Axios:cnpm install --save vue-axios

  2. 引用 Axios:

    import axios from 'axios'
    import VueAxios from 'vue-axios'
    
    Vue.use(VueAxios, axios)
    
  3. 准备数据,放入 static/mock/data.json

    {
      "name": "Java",
      "url": "https://blog.kuangstudy.com",
      "page": 1,
      "isNonProfit": true,
      "address": {
        "street": "含光门",
        "city": "陕西西安",
        "country": "中国"
      },
      "links": [
        {
          "name": "bilibili",
          "url": "https://space.bilibili.com/95256449"
        },
        {
          "name": "Java",
          "url": "https://blog.kuangstudy.com"
        },
        {
          "name": "百度",
          "url": "https://www.baidu.com/"
        }
      ]
    }
    
  4. 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() {
          this.axios({
            method: 'get',
            url: 'http://localhost:8080/static/mock/data.json'
          }).then((response) => {
            console.log(response)
          })
        }
      }
    }
    </script>
    

beforeRouteEnter 中可用,vm 是组件实例

20.2、异步请求

  1. 安装 Axios:cnpm install --save vue-axios

  2. 引用 Axios:

    import axios from 'axios'
    import VueAxios from 'vue-axios'
    
    Vue.use(VueAxios, axios)
    
  3. 准备数据,放入 static/mock/data.json

    {
      "name": "Java",
      "url": "https://blog.kuangstudy.com",
      "page": 1,
      "isNonProfit": true,
      "address": {
        "street": "含光门",
        "city": "陕西西安",
        "country": "中国"
      },
      "links": [
        {
          "name": "bilibili",
          "url": "https://space.bilibili.com/95256449"
        },
        {
          "name": "Java",
          "url": "https://blog.kuangstudy.com"
        },
        {
          "name": "百度",
          "url": "https://www.baidu.com/"
        }
      ]
    }
    
  4. 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() {
          this.axios({
            method: 'get',
            url: 'http://localhost:8080/static/mock/data.json'
          }).then((response) => {
            console.log(response)
          })
        }
      }
    }
    </script>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值