Bootstrap

Vue笔记基础

Vue

0、前言

​ 概念:一款渐进式 JavaScript 框架、所谓渐进式就是逐步实现新特性的意思、如实现模块化开发、路由、状态管理新特性。其特点是综合了Angular(模块化)和 React (虚拟DOM)的优点

​ 注:Vue处理DOM、Axios处理前端通信框架、类似于AJAX与服务器进行交互、也可使用原生的jQuery的ajax进行通信。

0.1、UI框架

  • Ant-Design:阿里巴巴出品,基于React
  • ElementUI、iview、ice:饿了么出品,基于 Vue 的 UI 框架
  • Bootstrap:Twitter推出的用于前端开发的开源工具包
  • AmazeUI:HTML5跨屏前端框架(常用)

0.2、JavaScript构建工具

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

0.3、ElementUI

  • vue-element-admin(掌握)

0.4、MVVM

异步通信为主、Model、View、ViewModel

0.5、Vue开发

​ 基于NodesJs,实际开发采用 vue-cli 脚手架,vue-router 路由(页面跳转),vuex做状态管理(类似于cookie),Vue UI 界面一般使用 ElementUI或者ICE。

1、第一个vue

vue分为三层、View、ViewModel(连接视图和数据的中间件)、Model(模型层,表示js中的对象)

双向数据绑定:ViewModel可以监听Model里面的对象,如果里面对象值发生改变,能够立即反馈到View层并显示。

即、如果在浏览器的控制台中输入vm.message="1111"那么页面上的hello,vue会变成1111且不需要刷新页面。

好处:解耦了前端与后端,且可以在模型层中模拟后端的数据。

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

<div id="app">
    {{message}}
</div>

<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            message:"hello,vue!"
        }
    });
</script>
</body>
</html>

2、v-bind

作用:相当于代替了{{}}

<div id="app">
    <span v-bind:title="message">
        鼠标悬停几秒钟查看此处动态绑定的提示信息!
    </span>
</div>

<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            message:"hello,vue!"
        }
    });
</script>

3、v-if、v-else、v-else-if

<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>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            type: 'A'
        }
    });
</script>
</body>




4、v-for

<body>
<div id="app">
    <li v-for="(item,index) in items">
        {{item.message}}--{{index}}
    </li>
</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            items: [
                {message:'邹某1'},
                {message:'邹某2'},
                {message:'邹某3'}
            ]
        }
    });
</script>
</body>

5、事件绑定:v-on:click

1、click是按钮点击事件、可在https://www.jquery123.com/jQuery中文文档中查看相应的事件

<body>
<div id="app">
   <button v-on:click="sayHi">点击</button>
</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            message: "1111"
        },
        methods: {
            // 方法必须绑定在 Vue 的 methods 对象中,v-on:事件
            sayHi: function (){
                alert(this.message);
            }
        }
    });
</script>
</body>

6、表单的双向绑定

​ 含义:如在输入框中输入数据,此数据会实时赋值给已绑定的变量

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

6.1、文本框绑定

<body>
<div id="app">
    单行文本:<input type="text" v-model="message" value="hello"/>{{message}}
</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            message: ""
        },

    });
</script>
</body>

在这里插入图片描述

6.2、下拉框绑定

注:在苹果系统中如果v-model表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。这会使第一项无法被选中,因为此情况下,ios不会触发change事件,所以我们需要给下拉框指定初始值(disabled)并将初始值置空(让用户无法选择此项)

<body>
<div id="app">
    下拉框:
    <select v-model="message">
        <option value="" disabled>--请选择--</option>
        <option>--A--</option>
        <option>--B--</option>
        <option>--C--</option>
    </select>
    <span>value:{{message}}</span>
</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            message: ""
        },

    });
</script>
</body>

在这里插入图片描述

7、组件(即标签)

**props:[‘z’]**参数传递

template: '<li>{{z}}</li>' :自定义标签

el:"#app" :绑定标签的id

data: {items: ["java","Linux","前端"]} : 数据域

data(){return{}}:数据方法,里面存放与数据有关的方法,return是返回值方法

methods: {}:存放方法的地方

computed: {} :存放计算属性的地方

可以任意创建标签(即组件),让标签映射在vue中。

通过 Vue.component创建组件zou后、我们想遍历输出items中的值,可以利用v-for设置在组件 zou 中,然后将组件 zou 与变量 z 绑定、通过 props 可以获取到 z 的值,即每一个遍历出来的 item 的值都传给了z ,然后获取z 的值 放入我们设置好的 template组件中。

<body>
<div id="app">

    <zou v-for="item in items" v-bind:z="item"></zou>

</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    Vue.component("zou",{
        props: ['z'],
        template: '<li>{{z}}</li>'
    });
    var vm = new Vue({
        el:"#app",
        data: {
            items: ["java","Linux","前端"]
        }
    });
</script>
</body>

在这里插入图片描述

8、Axios异步通信

​ 是一个开源的可以用在浏览器端和NodeJS的异步通信框架 ,它的主要作用就是实现AJAX异步通信,其功能特点如下:

  • 从浏览器中创建XMLHttpRequests

  • 从 node.js 创建 http 请求

  • 支持 Promise API [JS中链式编程]

  • 拦截请求和响应

  • 转换请求数据和响应数据

  • 取消请求

  • 自动转换 JSON 数据

  • 客户端支持防御 XSRF (跨站请求伪造)

    中文文档:http://www.axios-js.com

​ 一般开发采用json格式,所以我们模拟一段json数据

{
  "name": "zou",
  "url": "https://blog.csdn.net/qq_43483251?orderby=ViewCount",
  "address": {
    "street": "含光门",
    "city": "2",
    "country": "1"
  }
}

需要添加在线的或者下载

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--v-clock:解决闪烁问题-->
    <!--在v-clock绑定的标签上执行,如果未加载完则一直显示白板,直到加载完成-->
    <style>
        [v-clock]{
            display: none;
        }
    </style>
</head>
<body>
<div id="app" v-clock>

    <div>{{info.name}}</div>
    <div>{{info.address.street}}</div>
    <a v-bind:href="info.url">点我</a>

</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        // data是属性,下面这个是方法,可以接受异步通信的返回值,要ES6.0才行,5.1报错
        data(){
            return{
                // 请求的返回值参数合适、必须和json字符串一样
                info:{
                    name: null,
                    address: {
                        street: null,
                        city: null,
                        country: null
                    },
                    url: null
                }
            }
        },
        // 在vue生命周期内的钩子函数
        mounted(){
            // 链式编程、ES6新特性
            // 从文件data.json中取出值放入response中然后通过response.data赋值给this.info
            axios.get('../data.json').then(response=>(this.info=response.data));
        }
    });
</script>
</body>

在这里插入图片描述

9、计算属性

computed

​ 1、第一次调用 currencyTime02 它会运行,并返回结果,但是第二次调用且里面数据未发生变化时,是直接在内存中获取值。即,运行第一次后会将运行结果存放在内存中,如果在第二次调用前,方法中的数据未被更改,则直接从内存中取出值进行返回(相当于缓存概念),如果数据发送过改变,则会重新运行方法并返回和再次存储结果。

​ 2、methods 的调用只能是以方法的形式:{{currencyTime01()}}

​ 3、computed 的调用只能以变量的形式:{{currencyTime02}}

<body>
<div id="app">
    <p>1: {{currencyTime01()}}</p>
    <p>2: {{currencyTime02}}</p>

</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
    var vm = new Vue({
        el:"#app",
        data: {
            message: "zou"
        },
        // 使用方法方式且有返回值
        methods: {
            currencyTime01: function () {
              return Date.now() // 获得当前时间戳
          }
        },
        // 使用计算属性的方式、俩方式中的方法名不能相同、重名之后只会调用methods的
        computed: {
            currencyTime02: function () {
                this.message;
                return Date.now();
            }
        }
    });
</script>
</body>

第一次结果:

在这里插入图片描述

第二次结果:即手动改变 currencyTime02 中的 message 值再调用两个方法

在这里插入图片描述

第三次,不改变任何数据只是重新调用两方法

可以看到(看右边的控制台输出),第一个方法重新获取了时间戳、第二个方法是返回的原来时间戳

在这里插入图片描述

10 、插槽

定义:利用类似占位符的效果,暂时占据一个位置,这个位置可之后编写一段内容后替换此占位符,一定程度上可以有复用的效果

<body>
<div id="app">

    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <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/[email protected]/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: ['title'],
        template: '<div>{{title}}</div>'
    });

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

    var vm = new Vue({
        el:"#app",
        data: {
            title: "zou",
            todoItems: ["1","2","3"]
        }
    });
</script>
</body>

在这里插入图片描述

11、自定义事件内容分发

​ (此下内容是上面内容的引申)当我们需要删除上面列表中的1 2 3时,因为作用域问题,即想要删除的数据与插槽定义的地方不一样,所以定义插槽的地方不能直接拿到数据并删除,所以我们需要将数据与todo 标签双向绑定,且将删除按钮作为 v-on 的参数形成另一种按钮绑定事件 v-on:remove 即 remove 相当于 click 。后面的

removeItems(index) 相当于当点击删除按钮时,删除按钮自身通过双向绑定机制通知 v-on:remove 标签,然后标签 调用 removeItems(index) 方法用来达到删除的目的,而上述删除按钮反馈给标签的代码是 this.$emit('remove',index) :自定义事件分发

<body>
<div id="app">

    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item="item" :index="index" v-on:remove="removeItems(index)"></todo-items>
    </todo>

</div>
<!--1、导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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: ['title'],
        template: '<div>{{title}}</div>'
    });

    Vue.component("todo-items",{
        props: ['item','index'],
        template: '<li>{{item}}---{{index}}<button @click="remove">删除</button> </li>',
        methods: {
            remove: function (index) {
                // this.$emit 自定义事件分发
                // 这个remove是绑定上面的 removeItems(index),当按钮被点击,此方法被触发,因为有双向响应机制,
                // 所以上面的remove会知道并通知下面的 removeItems 方法并运行下面的方法以达到删除目的
                this.$emit('remove',index)
            }
        }

    });

    var vm = new Vue({
        el:"#app",
        data: {
            title: "zou",
            todoItems: ["11","21","31"]
        },
        methods: {
            removeItems: function (index) {
                console.log("删除了: "+ this.todoItems[index])
                this.todoItems.splice(index,1) // 删除数组中第index索引后的 1 个数(从此索引开始删除)
            }
        }

    });
</script>
</body>

在这里插入图片描述

12、vue-cli

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

​ 脚手架:已经写好了目录结构和基础代码。

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

12.1、需要的环境

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

确认nodejs安装成功

  • cmd下输入 node -v,会打印版本号

  • npm -v

npm 一个软件包管理工具,和Linux下的apt软件按钮差不多

安装 Node.js 淘宝镜像加速器(cnpm)

# -g 全局安装
npm install cnpm -g

# 可使用如下语句解决 npm 速度慢问题
npm install --registry = https://registry.npm.taobao.org

(一)npm国内淘宝npm镜像的使用
1.临时使用 npm --registry https://registry.npm.taobao.org install express

2.持久使用 npm config set registry https://registry.npm.taobao.org

3.检查配置是否成功 npm config get registry


4.通过cnpm使用 npm install -g cnpm --registry=https://registry.npm.taobao.org

安装路径:C:\Users\邹飞鸣\AppData\Roaming\npm

安装vue-cli

cnpm install vue-cli -g

# 测试
# 查看有哪些模板、通常44使用 webpack
vue list

执行上述两步后的截图

在这里插入图片描述

12.2、第一个vue-cli应用程序

1、选择一个文件夹E:\vue代码

2、管理员运行cmd、cd 到上面目录下、执行:

# myvue 是项目名字、下面是创建一个webpack类型的脚手架
vue init webpack myvue

vue build standalone:表示运行时编译

在这里插入图片描述

在这里插入图片描述

3、初始化并运行

cd myvue	 # 进入目录
npm install  # 下载依赖
npm run dev  # 运行项目
ctrl+c		 #退出

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • build:构建目录、一些打包工具
  • config:里面的index.js 有启动后项目运行的网址和端口号,可修改
  • node_modules:存放依赖
  • src:编写代码的地方
  • static:静态资源存放处、只有放入此处才能访问到
  • index.html:程序入口,里面东西一般不需要改变
  • package.json:打包需要构建的版本,无则打包失败

13、webpack学习

​ 一个现代JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归的构建一个依赖关系图(dependency graph),其中包含应用程序需要的每一个模块,然后将所有模块打包成一个或多个 bundle

13.1、安装Webpack

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

安装

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

测试

webpack -v

创建 webpack.config.js 配置文件

  • entry :入口文件,指定 WebPack 用哪个文件作为项目的入口
  • output:输出,指定 WebPack 把处理完的文件放置到指定路径
  • module:模块,用于处理各种类型的文件
  • plugins:插件,如:热更新、代码重用等
  • resolve:设置路径指向
  • watch:监听,用于设置文件改动后直接打包

使用webpack

1、创建项目、idea创建或者手动创建文件夹并用idea打开

2、创建一个名为 modules 的目录,用于放置 JS 模块等资源文件

3、在 modules 下创建模块文件,如 hello.js,用于编写 JS 模块相关代码

// 暴露一个方法:sayHi
exports.sayHi = function () {
    document.write("<h1>邹飞鸣</h1>")
}

4、在 modules 下创建 main.js 的入口文件,用于打包时设置 entry 属性

// require 导入一个模块
var hello = require("./hello");// 接收hello.js文件暴露的方法,相当于一个类的对象引用变量
hello.sayHi();

5、在项目目录下创建 webpack.config.js 配置文件,使用 webpack 命令打包

module.exports = {
    entry: './modules/main.js',  // 程序入口即要打包的地方
    output: {
        filename: "./js/bundle.js"  // 程序出口,即将打包后的文件存放的地方
    }
}

6、在命令行执行打包命令(有可能需要管理员模式)

在这里插入图片描述

此时在项目根目录下会生成文件夹 dist 文件夹下的 bundle.js 就是打包后的文件

在这里插入图片描述

7、在根目录定义 index.html 文件,里面只使用 script 标签引入 bundle.js 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--将打包后的文件引入,这也是为什么模块化开发只需要一个简单的index界面原因-->
<script src="dist/js/bundle.js"></script>
</body>
</html>

8、浏览器运行

在这里插入图片描述

注:可在命令行执行 webpack --watch 进行热部署,即一直监听你有没有改变代码,改变了就自动重新打包

14、Vue Router(路由)

​ 是 Vue.js 官方路由管理器,与 Vue.js 深度集成,让构件单页面应用变的易如反掌。功能如下:

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

作用:在单页面下不通过网页跳转进行网页内容变更(有点像内嵌网页)

如:轮播图的实现,一定时间后换一页,但是网页又不能跳转,我们就可以使用路由功能,通过路径自动展示需要的图片

14.1、安装

直接下载 / CDN

https://unpkg.com/vue-router@4

Unpkg.com基于 npm 的 CDN。上面的链接将提供指向 npm 上的最新链接。你也可以通过像https://unpkg.com/[email protected]/dist/vue-router.global.js这样的 URL 来使用某个版本的版本或标签。

npm

npm install vue-router@4

注:上面是最新版下载方法,会与旧版不兼容

步骤:

基于第一个 vue-cli 进行测试学习,先查看node_modules 文件夹中是否存在 vue-router

​ vue-router 是一个插件包,所以我们还是需要用 npm/cnpm 来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。

npm install vue-router --save-dev

报错信息:
npm错误!代码解析
npm错误!ERESOLVE无法解析依赖关系树 
...

注:如果上述命令报错可尝试如下命令:
npm install vue-router --legacy-peer-deps

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

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

// 显示声明使用VueRouter
Vue.use(VueRouter);

14.2、使用:

以一个简单的例子展示,一个单页面,点击不同文字,在此页面内展现文字代表的 网页 ,且网页不发生跳转行为。

项目结构:箭头指向的才是需要的文件,node_modules中存放依赖文件

在这里插入图片描述

1、定义 index.heml 即网页入口文件,一般的vue项目,这个文件是不变的。

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

2、定义 index.html 文件的 div 标签对应 id 的 vue 文件 app.vue 、这里面用来写第一个页面

<template>
  <div id="app">
      <!--点击文字会通过to标签的值去找相应的映射地址,元素文件一般在 router文件下的index.js文件中-->
      <router-link to="/main">首页</router-link>
      <router-link to="/Content">内容页</router-link>
      <!--显示跳转页的内容-->
      <router-view></router-view>

  </div>
</template>

<script>
// 对外面暴露一个接口,外面可通过App这个名字使用此网页
export default {
  name: 'App',
  comments: {

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

3、写 App.vue 对应的 js 文件:main.js 里面存放 关于App.vue的一些vue信息

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


Vue.config.productionTip = false

new Vue({
  el: '#app',
  // 配置路由
  router,
  components: { App },
  template: '<App/>'
})

4、编写 首页 和 内容页 的内容

首页: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>

5、编写路由信息的映射,index.js

// 一般存放路由信息,router文件夹下也是存放路由的相关文件
import Vue from 'vue';
//import * as VueRouter from 'vue-router',这是版本4的写法,下面的是3的写法
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',
      // 跳转的组件
      component: Content
    },
    {
      // 路由路径
      path: '/main',
      // 跳转的组件
      component: Main
    }
  ]
});

效果:

在这里插入图片描述

注:此时可能出现的错误,

错误信息:

"export 'default' (imported as 'VueRouter') was not found in 'vue-router'

可能情况:

第一种cli4和cli3不太一样 需要引用相对应的使用的东西,

第二种是vue-router版本太高,

这种情况一般是运行npm install vue-router --save-dev 后启动报错,这是因为安装的时候默认安装最新版本可能与其他插件不兼容,重新安装旧版本即可

解决方法:

命令:cnpm install vue-router@+版本号 --save-dev

实例:cnpm install [email protected] --save-dev

15、实例

​ 结合 ElementUI 组件库

15.1、Element使用

注:将Element的代码复制粘贴过来后需要将html的内容放在<template ></template>里面才能用

安装

npm 安装

推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。

npm i element-ui -S

CDN

目前可以通过 unpkg.com/element-ui 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

引入 Element(针对npm安装)

完整引入

1、在引入 Element 时,可以传入一个全局配置对象。该对象目前支持 sizezIndex 字段。size 用于改变组件的默认尺寸,zIndex 设置弹框的初始 z-index(默认值:2000)。

在 main.js 中写入以下内容:

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

//Vue.use(Element, { size: 'small', zIndex: 3000 });

Vue.use(ElementUI);


new Vue({
  el: '#app',
  render: h => h(App)
});

以上代码便完成了 Element 的引入。需要注意的是,样式文件需要单独引入。

15.2、完整建立VUE项目步骤

1、创建名为 hello-vue 的工程 ,选择一个文件夹 在文件夹对应的路径下运行命令行命令vue init webpack hello-vue
在这里插入图片描述

2、之后手动安装依赖,可选择自动安装。

// 如果npm出错可以用cnpm
// 进入工程目录
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

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

只要不出现错误就不管,警告没事!**

在这里插入图片描述

在这里插入图片描述

访问 http://localhost:8080/ 显示页面,说明创建成功
在这里插入图片描述

3、使用idea打开项目并删除多余文件与新建必要文件

如:删除logo文件,

在这里插入图片描述

4、创建首页视图:Main.vue

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

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

<style scoped>

</style>

5、创建登陆视图: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="dialogVisiable" 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>

6、编写路由映射文件:index.js

//导入vue
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
    },
  ]

})

7、mian.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(ElementUI);
Vue.use(router);


/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>',
  router,
  render: h => h(App) // ElementUI需要的
})

8、App.vue

<template>
  <div id="app">
    <router-link to="/main">首页</router-link>
    <router-link to="/login">登陆</router-link>
  <router-view></router-view>

  </div>
</template>

<script>


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

  }
}
</script>

9、index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>hello-vue</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

10、项目框架

在这里插入图片描述

11、运行截图
在这里插入图片描述

Vue.use():注册全局插件的意思

也就是为什么vue文件没有类似 import 的引用还能使用一些东西。

问题:

1、关于我们引用element组件时,在任何js文件中都行,只要最后通过Vue.use(ElementUI);进行全局插件注册即可全局使用

2、关于为什么App.vue中内容能在index.html中显示问题。

​ 1、index.html中 div 的 id 与 main.js 中的 el 参数进行绑定,又因为 App 暴露了自身,所以main.js可以通过components组件获取App内容。(大致,待完善)

16、路由嵌套

即在路由中添加子路由,因为路由类似内嵌网页,所以子路由可理解为在嵌套的网页中嵌套网页。

在上面项目基础上更改:箭头指向的都是有更改的

项目结构

在这里插入图片描述

注:路由也需要改,未指出。

Main.vue

<template >
  <el-container class="login-box" style="height: 500px;width: 1000px; border: 1px solid #eee;">
    <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
      <el-menu :default-openeds="['1', '3']">
        <el-submenu index="1">
          <template slot="title"><i class="el-icon-message"></i>用户设置</template>
          <el-menu-item-group>
            <el-menu-item index="1-1" ><router-link to="/user/userName">用户名字</router-link></el-menu-item>
            <el-menu-item index="1-2"><router-link to="/user/userOperation">用户操作</router-link></el-menu-item>
          </el-menu-item-group>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title"><i class="el-icon-menu"></i>系统设置</template>
          <el-menu-item-group>
            <el-menu-item index="2-1"><router-link to="/userOperation">系统音量</router-link></el-menu-item>
            <el-menu-item index="2-2">系统字体</el-menu-item>
          </el-menu-item-group>
        </el-submenu>
        <el-submenu index="3">
          <template slot="title"><i class="el-icon-setting"></i>小板凳</template>
          <el-menu-item-group>
            <el-menu-item index="3-1">小大板凳</el-menu-item>
            <el-menu-item index="3-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-item>删除</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <span>邹飞鸣</span>
      </el-header>

      <el-main>
        <router-view></router-view>
      </el-main>
    </el-container>
  </el-container>
</template>
<style>
.el-header {
  background-color: #3795f3;
  color: #333;
  line-height: 60px;
}
.login-box{
  border:1px solid #DCDFE6;
  margin: 100px auto;
  padding: 35px 35px 15px 35px;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  box-shadow: 0 0 25px #909399;
}
</style>
<script>
export default {
  name: "Main"
};
</script>

index.js

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";

// 导入用户操作组件
import userName from "../views/userviews/userName";
import userOperation from "../views/userviews/userOperation";
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
     //首页
      path: '/main',
      component: Main,
      // 设置孩子路由的关键字
      children: [
        {path: '/user/userName',component:userName},
        {path: '/user/userOperation',component:userOperation}
      ]
    },

    { //登录页
      path: '/login',
      component: Login
    }
,
    {
      path: '/userOperation',
      component:userOperation
    }
  ]

})

userName.vue

<template>
<h1>名字设置</h1>
</template>

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

<style scoped>

</style>

userOperation.vue

<template>
<h1>用户操作</h1>
</template>

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

<style scoped>

</style>

**效果:**点击用户名字后显示的效果,可以看到是在组件的里面显示组件,如果不使用子路由那么页面将只显示名字设置这四个字(原来的首页,登陆按钮是不变的)

在这里插入图片描述

17、路由传参

即在使用路由转发时可以携带参数,有几种携带参数的方法,以下代码均由上面代码修改而来

17.1、耦合度较高的方法

我们需要修改三处地方,分别对应,路由转发时要携带的参数,路由信息修改,显示参数需要修改的文件。

我们以传递用户名字为例:

第一步:修改首页文件(Main.vue)中关于用户名字的 to 属性参数

注:变量名最好不能和vue中类似于关键字的东西重名,如最好不起 name 作为参数的变量名,会有冲突。

原来的:
<!--<el-menu-item index="1-1" ><router-link to="/user/userName/">用户名字</router-link></el-menu-item>-->
    
现在的:name:参数为路由中的name参数名,params:是我们要传递参数的一个集合,Name:我们传递参数的变量名
<el-menu-item index="1-1" ><router-link :to="{name:'userName',params:{Name:'邹飞鸣'}}">用户名字</router-link></el-menu-item>

第二步:修改路由信息(index.js)

原来的:
{path: '/user/userName',component:userName},
// 将上面更改为下面的以达到路由跳转时传递参数、我们在 <router-link> 标签中的 to 参数的值一定是 下面的 name 值。
    
现在的:
{path: '/user/userName/:Name',component:userName,name:'userName'},

第三步:在 userName.vue 文件中修改为:

注:所有的变量一定不能在根标签下,下面的 <template> 就类似于根标签,一定在外面加一层标签,不然会出错

<template>
<div>
  <h1>名字设置</h1>
  {{ $route.params.Name }}
</div>
</template>

第四步:效果
在这里插入图片描述

17.2、解耦的写法(标准)

第一步:修改首页文件(Main.vue)中关于用户操作的 to 属性参数

原来的:
<!--<el-menu-item index="1-2"><router-link to="/user/userOperation">用户操作</router-link></el-menu-item>-->

现在的:
<el-menu-item index="1-2"><router-link :to="{name:'userOperation',params:{id:1}}">用户操作</router-link></el-menu-item>

第二步:修改路由信息(index.js)

原来的:
{path: '/user/userOperation/',component:userOperation}

现在的:我们要将props开启
{path: '/user/userOperation/:id',component:userOperation,name:'userOperation',props: true}

第三步:在 userOperation.vue 文件中修改为:

<template>
  <div>
    <h1>用户操作</h1>
    {{id}}
  </div>

</template>

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

</script>

第四步:效果
在这里插入图片描述

17.3、完整代码

注:只展示被修改过的文件的完整代码,其余未修改的文件上一个板块有

index.js

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";

// 导入用户操作组件
import userName from "../views/userviews/userName";
import userOperation from "../views/userviews/userOperation";
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
     //首页
      path: '/main',
      component: Main,
      // 设置孩子路由的关键字
      children: [
        //{path: '/user/userName',component:userName},
        // 将上面更改为下面的以达到路由跳转时传递参数、我们在 <router-link> 标签中的 to 参数的值一定是 下面的 name 值。
        {path: '/user/userName/:Name',component:userName,name:'userName'},
        //{path: '/user/userOperation/',component:userOperation}
        {path: '/user/userOperation/:id',component:userOperation,name:'userOperation',props: true}
      ]
    },

    { //登录页
      path: '/login',
      component: Login
    }
,
    {
      path: '/userOperation',
      component:userOperation
    }
  ]

})

Main.vue

<template >
  <el-container class="login-box" style="height: 500px;width: 1000px; border: 1px solid #eee;">
    <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
      <el-menu :default-openeds="['1', '3']">
        <el-submenu index="1">
          <template slot="title"><i class="el-icon-message"></i>用户设置</template>
          <el-menu-item-group>

            <!--<el-menu-item index="1-1" ><router-link to="/user/userName/">用户名字</router-link></el-menu-item>-->
            <el-menu-item index="1-1" ><router-link :to="{name:'userName',params:{Name:'邹飞鸣'}}">用户名字</router-link></el-menu-item>

            <!--<el-menu-item index="1-2"><router-link to="/user/userOperation">用户操作</router-link></el-menu-item>-->
            <el-menu-item index="1-2"><router-link :to="{name:'userOperation',params:{id:1}}">用户操作</router-link></el-menu-item>

          </el-menu-item-group>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title"><i class="el-icon-menu"></i>系统设置</template>
          <el-menu-item-group>
            <el-menu-item index="2-1"><router-link to="/userOperation">系统音量</router-link></el-menu-item>
            <el-menu-item index="2-2">系统字体</el-menu-item>
          </el-menu-item-group>
        </el-submenu>
        <el-submenu index="3">
          <template slot="title"><i class="el-icon-setting"></i>小板凳</template>
          <el-menu-item-group>
            <el-menu-item index="3-1">小大板凳</el-menu-item>
            <el-menu-item index="3-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-item>删除</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <span>邹飞鸣</span>
      </el-header>

      <el-main>
        <router-view></router-view>
      </el-main>
    </el-container>
  </el-container>
</template>
<style>
.el-header {
  background-color: #3795f3;
  color: #333;
  line-height: 60px;
}
.login-box{
  border:1px solid #DCDFE6;
  margin: 100px auto;
  padding: 35px 35px 15px 35px;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  box-shadow: 0 0 25px #909399;
}
</style>
<script>
export default {
  name: "Main"
};
</script>

userName.vue

<template>
<div>
  <h1>名字设置</h1>
  {{ $route.params.Name }}
</div>
</template>

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

<style scoped>

</style>

userOperation.vue

<template>
  <div>
    <h1>用户操作</h1>
    {{id}}
  </div>

</template>

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

</script>

<style scoped>

</style>

18、重定向

​ 什么叫重定向:就是你跳转地址 A 它会自动帮你跳转到 B ,作用:如果某个旧网页废弃,但还有用户访问,就会造成404,为了避免,我们可使用重定向跳转到我们想要跳转的页面。

​ 因为是 vue 所以这里的跳转不是请求服务器然后跳转的,因为 vue 是单页面应用,所以跳转就是更换了一个组件而言,并没有发送真正意义上的跳转,

步骤:

1、编写路由在原来路由上添加:

//访问 /a,重定向到 :/userOperation
{ path: '/a', redirect: '/userOperation' }

2、启动项目后访问 http://localhost:8080/#/a

此时会看到访问的地址最终变成 http://localhost:8080/#/userOperation

不好截图,就不截图了。

19、路由模式

路由模式有两种:

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

可修改路由配置以达到无 # 。

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

20、处理404

用户访问的地址如果没有,那么我们可以统一跳转的一个页面来表示404

步骤:

1、新建一个vue文件,用来显示404的界面

2、配置路由,让所有访问不到的页面就走上面这个文件

注:这里只展示路由配置信息

path: '*', // * 号代表,只要要跳转的地址在路由中找不到,就跳转到这个文件
component:NotFound // 这里NotFound就是我们创建的404页面文件

21、路由钩子与异步请求

beforeRouteEnter:进入路由前执行

beforRouteLeave:离开路由前执行

代码:

<script>
export default {
  name: "userOperation",
  props:['id'],
  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)=>{}) 仅在 beforeRouterEnter 中可用,vm 是组件实例

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

1、安装 Axios cnpm install axios -s npm install --save vue-axios

2、main.js 引用 Axios

import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

3、准备数据:只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。

// 静态数据存放的位置
static/mock/data.json
// 静态数据的数据
{
  "name": "zou",
  "url": "https://blog.csdn.net/qq_43483251?orderby=ViewCount",
  "address": {
    "street": "含光门",
    "city": "2",
    "country": "1"
  }
}

4、在 userOperation.vue 文件中编写

<template>
  <div>
    <h1>用户操作</h1>
    {{id}}
  </div>

</template>

<script>
export default {
  name: "userOperation",
  props:['id'],
  beforeRouteEnter:(to,from,next)=>{
    console.log("进入路由之前");
    next(vm => {
      vm.getData();//进入路由之前执行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>

<style scoped>

</style>

5、配置路由信息,路由信息和上面一样不需要变更。所以此处不多写一遍

6、点击用户操作时显示:
在这里插入图片描述

;