Vue 刷课笔记
作者:互联网
Vue 笔记
什么是Vue?
- Vue 是一套用于构建用户界面的渐进式JavaScript框架。
- Vue 被设计为可以自底向上逐层应用。
- Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。
- Vue 完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用。
- Vue综合了 Angular(模块化)和 React(虚拟DOM)的优点。
Vue MVVM 模式实现者
- Model: 模型层,在这里表示JavaScript对象
- View: 视图层,在这里表示DOM (HTML 操作的元素)
- ViewModel: 连接视图和数据的中间件,Vue.js 就是 MVVM 中的ViewModel层的实现者
在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个 Observer 观察者
- ViewModel能够观察到数据的变化,并对视图对应的内容进行更新
- ViewModel能够监听到视图的变化,并能够通知数据发生改变
至此,我们就明白了,Vue.js 就是一个 MVVM的实现者,他的核心就是实现了DOM监听与数据绑定
其它
网络通信:axios(前端的通信框架)
页面跳转:vue-router
状态管理:vuex
Vue-UI: ICE
前端三要素:结构层(HTML)、 表现层(CSS)、行为层(JavaScript)
JavaScript 构建工具
webpack ( 模块打包器,主要作用是打包、压缩、合并及按序加载 )
UI 框架
Ant-Design ( 阿里巴巴出品,基于React的框 )
Element UI ( 饿了么出品,基于Vue的UI框架 ) ( 桌面端支持较多 )
Bootstrap ( Twitter 推出的用于前端开发的开源工具包 )
Amaze ~ 妹子 UI ( 中国首个开源 HTML5 跨屏前端框架 )
iView (View UI,即原先的 iView,是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品。) ( 移动端支持比较多 )
vue-element-admin
vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui 实现。
一、第一个Vue程序
【说明】 IDEA 安装 Vue 插件!
第一个Vue程序:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- View层 -->
<div id="app">
{{message}}
</div>
<!-- 1.导入Vue.js -->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
// Model : 数据
data: {
message: "Hello Vue~"
}
});
</script>
</body>
</html>
测试:在控制台输入 vm.message = “Hello World!”,显示的内容会改变为"Hello World!"。
此时就可以在控制台直接输入vm.message来修改值,中间是可以省略data的,
在这个操作中,我并没有主动操作DOM,就让页面的内容发生了变化,这就是借助了Vue的数据绑定功能实现的;
MVVM模式中要求ViewModel层就是使用观察者模式来实现数据的监听与绑定,以做到数据与视图的快速响应。
二、Vue基本语法
v-bind attribute 被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute。
它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的 title attribute 和 Vue 实例的 message property 保持一致”。
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
条件与循环
- v-if
<!-- View层 -->
<div id="app">
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
<h1 v-if="type === 'A'">A</h1>
<h1 v-else-if="typr === 'B'">B</h1>
<h1 v-else="type === 'c'">C</h1>
</div>
<!-- 1.导入Vue.js -->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
// Model : 数据
data: {
ok: true,
type: 'A'
}
});
</script>
- v-for
<!-- View层 -->
<div id="app">
<li v-for="item in items">
{{item.message}}
</li>
<li v-for="(item, index) in items">
{{index}} --> {{item.message}}
</li>
</div>
<!-- 1.导入Vue.js -->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
// Model : 数据
data: {
items: [
{message: "从入门到放弃"},
{message: "从删库到跑路"},
{message: "有手就行"}
]
}
});
</script>
绑定事件
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<!-- View层 -->
<div id="app">
<button v-on:click="sayHi">点击我</button>
</div>
<!-- 1.导入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "Hello World! 程序员"
},
methods: { // 方法必须定义在Vue 的 methods 对象中
sayHi: function () {
alert(this.message);
}
}
});
</script>
三、 双向绑定、组件
什么是数据双向绑定?
Vue.js是一个 MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue.js 的精髓之处了。
在表单中使用数据双向绑定
你可以用 v-model 指令在表单<input>
、 <textarea>
及<select>
元素上创建双向数据绑定。
它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。
它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
注意: v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!
<!-- View层 -->
<div id="app">
<!-- 输入框 -->
<div>
输入的文本:<input type="text" v-model="message"> {{message}}
</div>
<!-- 单选框 -->
<div> 性别:
<input type="radio" name="sex" value="男" v-model="sex">男
<input type="radio" name="sex" value="女" v-model="sex">女
<p>
选中了谁: {{sex}}
</p>
</div>
<!-- 下拉框 -->
<div>下拉框:
<select v-model="selected">
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>
选中了谁: {{selected}}
</p>
</div>
</div>
<!-- 1.导入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "...",
checked: false,
sex: "",
selected: ''
},
});
</script>
Vue 组件
prop 是你可以在组件上注册的一些自定义 attribute。
当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
为了给博文组件传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样。
一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来:
<blog-post title="My journey with Vue"></blog-post>
测试代码:
<!-- View层 -->
<div id="app">
<!-- 组件:传递给组件中的值:props (理解:mianbao是形参,item是实参)-->
<my-component v-for="item in items" v-bind:mianbao="item"></my-component>
</div>
<!-- 1.导入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 定义一个Vue 的组件 component
Vue.component('my-component', {
props: ['mianbao'],
template: '<li>{{mianbao}}</li>'
});
let vm = new Vue({
el: "#app",
data: {
items: ["Java", "Mysql", "Spring"]
}
});
</script>
四、 Axios异步通信
什么是 axios?
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特性:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
为什么要使用Axios?
由于Vue.js 是一个视图层框架并且作者(尤雨溪)严格准守SoC (关注度分离原则),所以Vue.js 并不包含AJAX的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource的插件,不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery,因为它操作Dom太频繁!
第一个 Axios 程序
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。
同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
测试:
json例子:
{
"name":"面包学java",
"url": "http://baidu.com",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "破漏山村",
"city":"广西百色",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
<div id="vue">
<div>{{info.address}}</div>
<a v-bind:href="info.url">点我</a>
</div>
<!-- 引入 JS 文件 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#vue",
data() {
return {
// 请求的返回参数格式,必须和json字符串一样
info: {
name: null,
address: {
country: null,
city: null,
street: null
},
url: null
}
}
},
mounted() { // 钩子函数 ES6新特性
axios.get('../data.json').then(response => (this.info = response.data));
}
});
</script>
五、 计算属性
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:
computed: {
now: function () {
return Date.now()
}
}
可以理解为缓存
六、 slot插槽
具名插槽
官网例子:
<div class="container">
<header>
<!-- 我们希望把页头放这里 -->
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
</main>
<footer>
<!-- 我们希望把页脚放这里 -->
</footer>
</div>
对于这样的情况, 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
一个不带 name 的 出口会带有隐含的名字“default”。
在向具名插槽提供内容的时候,我们可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
自己测试代码:
<!-- View层 -->
<div id="app">
<!-- 实现的列表 -->
<p>列表书籍</p>
<ul>
<li>Java</li>
<li>Mysql</li>
<li>Spring</li>
</ul>
<!-- 插槽实现 -->
<todo>
<todo-title slot="todo-title" v-bind:title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" :items="item"></todo-items>
</todo>
</div>
<!-- 1.导入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.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: ['items'],
template: '<li>{{items}}</li>'
});
let vm = new Vue({
el: "#app",
// Model : 数据
data: {
title: "面包列表",
todoItems: ['Java', 'Mysql', 'Vue']
}
});
</script>
七、 自定义事件内容分发(待加深理解)
弹幕提示(拿过来理解):
bind: 绑定前端与vue的数据。props: 绑定前端与组件的数据。
this.$emit 将事件分发回前端,前端 v–on:remove 再将事件给 removeItems(处理)
测试案例:
<!-- View层 -->
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item, index) in todoItems" :items="item" v-bind:index="index" v-on:remove="removeItem(index)"></todo-items>
</todo>
</div>
<!-- 1.导入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.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: ['items', 'index'],
template: ' <li>{{index}} ===> {{items}} <button @click="remove">删除</button></li>',
// 只能绑定当前组件的方法
methods: {
remove: function (index) {
// this.$emit 自定义事件
this.$emit("remove", index);
}
}
});
let vm = new Vue({
el: "#app",
// Model : 数据
data: {
title: "面包列表",
todoItems: ['Java', 'Mysql', 'Vue']
},
methods: {
removeItem: function (index) {
console.log("删除了"+ this.todoItems[index] + "OK");
this.todoItems.splice(index, 1); // 一次删除一个元素
}
}
});
</script>
第一个 Vue-cli 项目
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。用于生成一个 Vue 项目模板。好比在创建 Maven 项目时可以选择一个骨架。
Vue CLI 提供:
- 通过 @vue/cli 实现的交互式的项目脚手架。
- 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
- 一个运行时依赖 (@vue/cli-service),该依赖:
- 可升级;
- 基于 webpack 构建,并带有合理的默认配置;
- 可以通过项目内的配置文件进行配置;
- 可以通过插件进行扩展。
- 一个丰富的官方插件集合,集成了前端生态中最好的工具。
- 一套完全图形化的创建和管理 Vue.js 项目的用户界面。
1. 需要的环境
Node.js: https://nodejs.org/zh-cn/
Git : https://git-scm.com/downloads
node.js下载后无脑安装, 确认nodejs安装成功:
- cmd 下输入node -v ,查看是否能够正确打印出版本号即可!.
- cmd 下输入npm-v ,查看是否能够正确打印出版本号即可!
这个npm,就是一个软件包管理工具,就和 linux 下的 apt 软件安装差不多!
安装 Node.js 淘宝镜像加速器 ( cnpm )
这样子下载会快很多~
# -g 就是全局安装
npm install cnpm -g
# 或者使用如下语句解决 npm 速度慢的问题
npm install --registry=https://registry.npm.taobao.org
安装位置:
C:\Users\17521\AppData\Roaming\npm
安装 Vue-cli
cnpm install vue-cli -g
# 测试是否安装成功
# 查看可以基于哪些模板创建 vue 应用程序,通常我们选择 webpack
vue list
2. 新建 vue-cli 程序
2.1 创建一个基于 webpack 模板的 vue 程序(自己选择项目路径)
# myvue 为项目名
vue init webpack myvue
一路都选择 no
说明:
- Project name: 项目名称,默认回车即可
- Project description: 项目描述,默认回车即可
- Author: 项目作者,默认回车即可
- Install vue-router: 是否安装
- vue-router,选择n不安装(后期需要再手动添加 )
- Use ESLint to lint your code: 是否使用 ESLint 做代码检查,选择n不安装(后期需要再手动添加)
- Set up unit tests: 单元测试相关,选择n不安装(后期需要再手动添加)
- Setup e2e tests with Nightwatch: 单元测试相关,选择n不安装(后期需要再手动添加)
- Should we run npm install for you after the project has been created: 创建完成后直接初始化,选择n,我们手动执行;
运行结果!
2.2 初始化并运行
cd myvue
npm install # 根据项目下的 package.json 安装依赖 安装到项目 node_modules 目录
npm run dev
安装依赖如果有错误,vue会提示,例如:
found 17 vulnerabilities (3 low, 8 moderate, 6 high)
run `npm audit fix` to fix them, or `npm audit` for details
webpack 学习使用
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。
当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
安装 webpack
安装命令:
npm install webpack -g
npm install webpack-cli -g
测试安装成功命令:
webpack -v
webpack-cli -v
配置
创建webpack .config.js
配置文件
- entry: 入口文件,指定WebPack 用哪个文件作为项目的入口.
- output: 输出,指定WebPack 把处理完成的文件放置到指定路径
- module: 模块,用于处理各种类型的文件
- plugins: 插件,如:热更新、代码重用等
- resolve: 设置路径指向
- watch: 监听,用于设置文件改动后直接打包
使用 webpack
1、 创建项目
新建文件夹:webpack-study ;然后用IDEA打开
2、 新建 modules 文件目录,用于放置 JS 模块等资源文件
3、 在 modules 目录中新建 hello.js 文件和 main.js 文件
hello.js
// 暴露一个方法
exports.sayHi = function () {
document.write("<h1>面包学JAVA</h1>");
};
main.js
// require:导入一个模块就可以调用这个模块下的方法了
let hello = require("./hello");
hello.sayHi();
4、 项目目录下新建 webpack.config.js 文件
module.exports = {
entry: './modules/main.js',
output: {
filename: "./js/bundle.js"
}
};
5、 在 IDEA 的 Terminal 中输入命令: webpack. (管理员运行IDEA)
可以看到项目中生成 dist/js/bundle.js 文件
6、 新建 index.html 使用打包后的 bundle.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>
vue-router 路由
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
安装
基于第一个 vue-cli 进行测试学习;先查看 node_modules 中是否存在 vue-router
vue-router 是一个插件包,所以我们还是需要用npm/cnpm来进行安装的。
打开命令行工具,进入你的项目目录,输入下面命令。
npm install vue-router --save-dev
如果要在一个模块化工程中使用它,必须要通过 Vue.use() 明确的安装路由
import VueRouter from "vue-router";
// 显示声明使用VueRouter
Vue.use(VueRouter);
测试
1、 在 components 目录下新建两个组件
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>
2、 src 目录下新建一个 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
}
]
})
3、 在 main.js 中配置
import Vue from 'vue'
import App from './App'
import router from './router' // 自动扫描里面的路由配置
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
// 配置路由
router,
components: { App },
template: '<App/>'
})
4、 在 APP.vue 中使用
<template>
<div id="app">
<h1>Vue-router</h1>
<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>
....
</style>
vue + elementUI
以管理员的身份运行 cmd
1、 创建工程 hello-vue : vue init webpack hello-vue
2、 安装依赖
# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element ui ; https://element.eleme.cn/#/zh-CN/component/installation
npm i element-ui -S
# 安装所有的依赖
npm install
# 安装 SASS 加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev
3、 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 为该命令的缩写
4、 用 IDEA 打开工程
5、 在 src 下创建 view 目录,新建 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;
}
});
},
handleClose: function () {
console.log("Handle Close,空函数");
}
}
}
</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;
}
.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>
6、 在 src 下创建 router 目录,新建 index.js:
import Vue from 'vue';
import VueRouter from "vue-router";
import Login from "../view/Login";
import Main from "../view/Main";
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: '/main',
component: Main
},
{
path: '/login',
component: Login
}
]
})
7、 main.js 配置
import Vue from 'vue'
import App from './App'
// 路由
import router from './router'
// 引入 Element UI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(router);
Vue.use(ElementUI);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App) // Element UI
});
8、 App.vue 添加代码: router-view 标签展示路由页面
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
9、 运行 npm run dev
-
如果出错,在 package.json 降低 “sass-loader” 的版本为 ^7.3.1
-
再次运行报错:
Error:Node Sass version 5.0.0 is incompatible with ^4.0.0
: 在 package.json 降低 “node-sass” 的版本为 ^4.14.1工程目录
嵌套路由
1、 编写 Main.vue
<template>
<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></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped lang="scss">
.el-header {
background-color: #048bd1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
2、 在 view 目录下新建 user 目录, 新建 List.vue 和 Profile.vue
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style>
<template>
<h1>个人信息</h1>
</template>
<script>
export default {
name: "UserProfile"
}
</script>
<style scoped>
</style>
3、 在 router 的 index.js 中配置
...
routes: [
{
path: '/main',
component: Main,
// 嵌套路由
children: [
{ path: '/user/profile', component: UserProfile },
{ path: '/user/list', component: UserList }
]
},
...
4、 运行并测试
…
参数传递及重定向
修改 Main.vue
...
<!-- name: 组件名字 params: 参数 需要对象:v-bind -->
<router-link :to="{name: 'UserProfile', params: {id: 1}}">个人信息</router-link>
...
路由配置 index.js
...
children: [
{ path: '/user/profile/:id', name: 'UserProfile', component: UserProfile },
...
修改 Profile.vue
<template>
<!-- 所有的元素,不能直接在根节点下 -->
<div>
<h1>个人信息</h1>
{{ $route.params.id }}
</div>
</template>
测试
通过 props 解耦
开启 props: true
...
children: [
{ path: '/user/profile/:id', name: 'UserProfile', component: UserProfile, props: true },
...
Main.vue 不变, 修改 Profile.vue : 增加 props: [‘id’], 就可以直接使用 {{id}}
<template>
<!-- 所有的元素,不能直接在根节点下 -->
<div>
<h1>个人信息</h1>
<!-- {{ $route.params.id }}-->
{{id}}
</div>
</template>
<script>
export default {
props: ['id'],
name: "UserProfile"
}
</script>
重定向
...
{
path: "/goHome",
redirect: '/main'
}
路由钩子和404
路由模式
路由模式有两种:
- hash : 路径带 # 符号。 如: http://localhost:8080/#/login
- history: 路径不带 # 符号。 如:http://localhost:8080/login
修改路由配置:
export default new VueRouter({
mode: 'history',
routes: [
...
404
处理 404 创建一个名为 NotFound.vue 的视图,代码如下:
<template>
<div>
<h1>404, 你找的页面走丢了...</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
路由配置 index.js
import NotFound from "../view/NotFound";
...
{
path: '*',
component: NotFound
}
路由钩子
beforeRouteEnter:
在进入路由之前执行beforeRouteLeave:
在离开路由之前执行
<script>
export default {
props: ['id'],
name: "UserProfile",
// 拦截器 request->to, response->form, chain->next
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是组件实例
在钩子函数中使用功一步请求
1、 安装 Axios npm install axios -s
2、 在 main.js 中引用 Axios
// Axios
import axios from 'axios';
import VueAxios from 'vue-axios';
Vue.use(VueAxios, axios);
3、 在 static 新建 mock 目录,并编写data.json
{
"name":"面包学java",
"url": "http://baidu.com",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "破漏山村",
"city":"广西百色",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
4、 编写路由钩子函数
<script>
export default {
props: ['id'],
name: "UserProfile",
// 拦截器 request->to, response->form, chain->next
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 (res) {
console.log(res);
});
}
}
}
</script>
5、 运行测试,查看控制台输出
…
标签:npm,Vue,name,笔记,js,vue,刷课,路由 来源: https://blog.csdn.net/weixin_43989102/article/details/109955597