Vue.js快速入门
一、前端技术栈
1、HTML:超文本标记语言。
2、CSS:样式层叠器。
3、javaScript:弱类型脚本语言,常用于动态DOM操作。
常用:ES5(所有浏览器支持)、ES6(主流使用,主流浏览器支持,可通过WebPack脚手架编译成ES5语法)。
4、JQuery:大家熟知的 JavaScript 框架,优点是简化了 DOM 操作,缺点 是 DOM 操作太频繁,影响前端性能;在前端眼里使用它仅仅是为了兼容IE6、7、8。
5、React:Facebook 出品,一款高性能的 JS 前端框架;特点是提出了新概念 【虚拟 DOM】 用于减少真实 DOM 操作,在内存中模拟 DOM 操作,有效的提升了前端渲染效率;缺点是使用复杂,因为需要额外学习一门 【JSX】 语言;
6、less:基于 NodeJS,通过客户端处理,使用简单。功能比 SASS 简单,解析效率也低于 SASS,但在实际开发中足够了,所以我们后台人员如果需要的话,建议使用 LESS。
7、sass:基于 Ruby,通过服务端处理,功能强大。解析效率高。需要学习 Ruby 语言,上手难度高于LESS。
8、Ant-design:阿里巴巴出品,基于 React的UI 框架。
9、Anglar:Google 收购的前端框架,由一群 Java 程序员开发,其特点是将后台的 MVC 模式搬到了前端并增加了模块化开发的理念,与微软合作,采TypeScript 语法开发;对后台程序员友好,对前端程序员不太友好;最大的缺点是版本迭代不合理(如:1代 -> 2代,除了名字,基本就是两个东西)。
10、ElementUI:饿了么出品,基于 Vue 的 UI 框架。
11、Bootstrap:Twitter 推出的一个用于前端开发的开源工具包。
12、AmazeUI:又叫“妹子 UI”,一款 HTML5 跨屏前端框架。
13、TypeScript:微软开源创立的,该语言的特点就是除了具备 ES 的特性之外还纳入了许多不在标准范围内的新特性,所以会导致很多浏览器不能直接支持TypeScript 语法,需要编译后(编译成 JS)才能被浏览器正确执行。
js编译工具:webpack、babel,其中babel用于编译TypeScript语法,把typeScript编译成浏览器可解释的ES5语法。
二、前端架构的演变
从MVC后端时代,页面跳转要依赖于后端环境,到Ajax异步请求时代,但是ajax需要规定接口规则,遇到大量javascript代码的情况,会出现view绑定不方便,再到前端为主的MVC、MVP(异步通信)、MVVM(异步通信),性能不是最好,前端校验代码不能复用,全异步对SEO降级操作不利,到最后的NodeJS时代,NodeJs时代,以前历史遗留问题未解决,前端开发人员需要懂运维、网络通信等基本知识。
三、MVVM模式
事件驱动编程,视图层与viewModel层进行双向绑定,ViewModel层获取后端发生的数据变化,视图层自动变化,view层不直接与后端的模型层交互,而是与viewModel层交互,实现了视图层与模型层的解耦。
需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的,前端不用再去频繁操作DOM去更新数据,提升了程序的效率,程序员只需要维护ViewModel层行为和状态,视图层会自动更新。
四、Vue.js优点
Vue是一款渐进式前端js开源框架,与大型框架的不同的是Vue只关心视图层,自底向上逐层应用,还支持第三方插件类库使用,当结合使用时Vue也能为复杂的单页面应用提供驱动。
Vue也是ViewModel层的实现者,Model层不允许直接与view通信,要经过ViewModel进行数据监听通信,而ViewModel就定义个Observer观察者,ViewModel能监听数据和视图的改变,并通知视图层进行更新,因此ViewModel的功能就是事件监听和数据绑定。
其他MVVM实现者:微信小程序、React.js、Angular.js。
Vue吸收了Angular模块化以及React虚拟Dom优点,轻量级,体积小,简单容易,能够快速上手。
支持IE9及以上版本
Vue.js核心两大功能:数据驱动、组件化
五、Vue.js快速入门
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app">{{message}}</div>
<script type="text/javascript">
var vm=new Vue({
//挂载元素 element
el:'#app',
//组件内部数据
data:{
message:'hello Vuezzz!'
}
});
</script>
</body>
六、Vue生命周期
如图所示,Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载 DOM、渲染→更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。
重点关注元素加载完毕后执行的钩子函数:mounted(),可以在该函数请求异步数据。
5.2.1. beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。5.2.2. created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方
法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。5.2.3. beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。5.2.4. mounted(相当于js中的document.ready())
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。5.2.5. beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,
这不会触发附加的重渲染过程。5.2.6. updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情
况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不
被调用。5.2.7. beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。5.2.8. destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有
的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
七、条件判断渲染
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<ul id="app">
<li v-if="flag==='A'">蔬菜</li>
<li v-else-if="flag==='B'">肉类</li>
<li v-else="flag==='C'">不是食物</li>
</ul>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
flag:"B"
}
});
</script>
</body>
八、数组遍历
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<ul id="app">
<li v-for="item in msg">{{item}}</li>
</ul>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
msg:["one","two","three","four","five"]
}
});
</script>
</body>
九、事件监听
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--v-on:等价于@ @click-->
<button v-on:click="msg">点击一下</button>
值:{{info}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
info:"hello Vue"
},
methods:{
msg:function(event){
this.info="你点击一下!";
}
}
});
</script>
</body>
十、表单元素的动态监听
表单元素的动态监听:会忽略表单元素的value 、 checked 、 selected 属性值,JavaScript 在组件的 data 选项中声明初始值。
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" value="你好" v-model="message"/>
表单输入的值:{{message}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
message:""
}
});
</script>
</body>
- 下拉框
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app">
<select v-model="selected">
<!--
如果 v-model 表达式的初始值未能匹配任何选项, <select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因 此,更推荐像上面这样提供一个值为空的禁用选项。
-->
<option value="" disabled>请选择****</option>
<option value="sh" >上海</option>
<option value="hz">杭州</option>
<option value="gz" >广州</option>
<option value="sz">深圳</option>
</select>
selected:{{selected}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
selected:""
}
});
</script>
</body>
十一、Axios(异步通信)
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF (跨站请求伪造)
- 数据源
{
"name":"张三",
"age":"22",
"hoddy":["打羽毛球","跑步","游泳"],
"classInfo":{
"cno":"1101",
"cname":"体育课",
"teacher":"姚明"
}
}
- 测试代码
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<ul>
姓名:{{info.name}}---->年龄:{{info.age}}
爱好:
<li v-for="item in info.hoddy">{{item}}</li>
课程:{
课程号:{{info.classInfo.cno}},
课程名:{{info.classInfo.cname}},
老师:{{info.classInfo.teacher}}
}
</ul>
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data(){
return{
//info中格式要与后台传送的json数据格式一致
info:{
name:"",
age:" ",
hoddy:[],
classInfo:{
cno:"",
cname:"",
teacher:""
}
}
}
},
mounted(){
// alert("钩子函数生效了!");
axios.get("data.json").then(response=>{
// console.log(response.data);
this.info=response.data;
});
}
});
</script>
</body>
十二、组件化开发
组件是可复用的 Vue 实例,说白了就是一组可以重复使用的模板,跟 JSTL 的自定义标签、Thymeleaf 的th:fragment 以及 Sitemesh3 框架有着异曲同工之妙。通常一个应用会以一棵嵌套的组件树的形式来组织.
- 测试代码
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<!-- 以下代码只是为了更好了解Vue组件化开发,实际开发不是这样使用! -->
<div id="app">
<ul>
<my-component v-for="items in name" v-bind:item="items"></my-component>
</ul>
</div>
<script type="text/javascript">
Vue.component("my-component",{
props:["item"],
template:"<li>{{item}}</li>"
});
var vm=new Vue({
el:'#app',
data:{
name:["西施","貂蝉","王昭君","杨玉环"]
}
});
</script>
</body>
十三、计算属性
计算属性实际上就是把程序不常改变的运行结果放进一个缓存中,变成静态变量,节省系统的开销,用于程序使用,而方法就是可以反复执行,大大消耗系统开销。
- 测试代码
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<!-- 以下代码只是为了更好了解Vue组件化开发,实际开发不是这样使用! -->
<div id="app">
方法函数执行:{{dataTime1()}}
计算属性函数执行:{{dataTime2}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
methods:{
dataTime1:function(){
return Date.now();
}
},
//计算属性
computed:{
dataTime2:function(){
return Date.now();
}
}
});
</script>
</body>
十四、插槽与自定义事件(slot)
<head>
<title>Vue快速入门</title>
<!-- 导入Vue第三方库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<!-- 以下代码只是为了更好了解Vue组件化开发,实际开发不是这样使用! -->
<div id="app">
<todo>
<!-- 把组件todo-title中模板插入slot名为title的插槽中 -->
<todo-title slot="title" v-bind:title="title"></todo-title>
<!-- :key 等价于v-bind:key 把index当做组件传递给函数进行操作 v-bind绑定props中的属性名,把组件中的props属性与组件模板插值表达式相关联 -->
<todo-content slot="content" v-for="(item,index) in list" v-bind:item="item" :key="index" @remove1="removeMake(index)"></todo-content> <!--@remove1自定义事件-->
</todo>
</div>
<script type="text/javascript">
//插槽就是用来组件之间的插入
//定义一个大组件
Vue.component("todo",{
//在模板中定义插槽
template:"<div><slot name='title'></slot><ul><slot name='content'></slot></ul></div>"
});
Vue.component("todo-title",{
props:["title"],
template:"<p>{{title}}</p>"
});
Vue.component("todo-content",{
props:["item"],
template:"<li>{{item}}<button @click='remove'>删除</button></li>",
methods:{
remove:function(){
// alert("删除操作!");
this.$emit("remove1"); //绑定自定义事件
}
}
});
var vm=new Vue({
el:'#app',
data:{
title:"number",
list:["one","two","three","four"]
},
methods:{
removeMake:function(index){
// console.log(index);
this.list.splice(index,1); //根据索引删除数组
}
}
});
</script>
十五、脚手架初始化Vue项目
vue-cli 官方提供的一个脚手架(预先定义好的目录结构及基础代码,咱们在创建 Maven 项目时可以
选择创建一个骨架项目,这个骨架项目就是脚手架),用于快速生成一个 vue 的项目模板
功能:
统一的目录结构
本地调试
热部署
单元测试
集成打包上线
- 安装NodeJs并配置
1、安装NodeJs软件 官网:https://nodejs.org/en 在https://www.npmjs.com/搜索想要的插件进行npm安装
2、配置淘宝镜像:npm config set registry https://registry.npmmirror.com (尽量使用最新镜像本镜像)
3、查看配置是否成功:npm config get registry
4、npm install -g [脚手架名] 全局安装脚手架 npm install -g vue-cli 全局安装vue-cli脚手架
5、npm uninstall -g [脚手架名] 全局卸载脚手架
5、npm cache clean --force 清除npm缓存
如果碰到安装错误可以在隐藏文件目录:C:\Users\Administrator\AppData\Roaming\npm\下查看npm安装的所有全局插件,进行删除重新安装。
- 使用脚手架创建一个项目
vue init webpack [项目名] #初始化Vue项目 项目名不能用大写字母
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 ,我们手动执行
cd 进行项目根目录
npm install 安装环境
npm run dev或者npm run start 运行项目
十六、Vue项目目录分析
build 和 config:WebPack 配置文件
node_modules:用于存放 npm install 安装的依赖文件
src: 项目源码目录
static:静态资源文件
.babelrc:Babel 配置文件,主要作用是将 ES6 转换为 ES5
.editorconfig:编辑器配置
eslintignore:需要忽略的语法检查配置文件
.gitignore:git 忽略的配置文件
.postcssrc.js:css 相关配置文件,其中内部的 module.exports 是 NodeJS 模块化语法
index.html:首页,仅作为模板页,实际开发时不使用
package.json:项目的配置文件
name:项目名称
version:项目版本
description:项目描述
author:项目作者
scripts:封装常用命令
dependencies:生产环境依赖
devDependencies:开发环境依赖
十七、Webpack脚手架
npm install webpack webpack-cli -g #安装webpack脚手架
- 自定义webpack项目
//test.js 导出文件 ES6语法
exports.say=function(){
document.write("hello webpack!6666");
}
//导入函数 main.js
var demo=require("./test")
demo.say();
//配置文件
module.exports = {
entry:"./modules/main.js", //出口文件
output: {
filename: "./js/bund.js" //打包的文件路径及文件名 ./表示文件当前目录
},
watch: true
};
//进行打包
webpack #Dos命令
//引入静态页面中进行执行
<!DOCTYPE html>
<html>
<head>
<script src="./dist/js/bund.js"></script>
</head>
<body>
</body>
</html>
十八、vue-route(路由)
主要作用是进行页面之间跳转!
npm install [email protected] --save-dev #安装在vue项目中的生产环境中!
安装好了在package.json的开发依赖中会添加.
在main.js页面注册路由时,严格使用router关键字,区别大小写!
vue2版本搭配[email protected]安装,$同时注意vue-router不是vue-route。
- 测试代码(main.js)
import Vue from 'vue'
import App from './App' // ./表示当前项目 导入App.vue组件 //导入路由 vue-route依赖
import router from './route'
Vue.config.productionTip = false //抑制警告
//使用路由//使用路由
/* eslint-disable no-new */
new Vue({
router, //严格使用router关键字 不能使用任何关键字
el: '#app',
components: { App }, //定义这是一个组件 如果使用html标签不用定义 直接在template使用 //注册自定义路由
template: '<App/>' //把组件当做模板 覆盖index.html中id="app"的div
})
- 测试代码 (./router/index.js)
//导入vue
import Vue from 'vue'
import Router from 'vue-router'
import hello from '../components/hello'
import index from '../components/index' //./表示当前目录 ../上级目录
//安装路由
Vue.use(Router)
//导出路由
export default new Router({
routes:[
{
path:'/hello',
name:'hello',
component: hello
},
{
path:'/',
name:'index',
component: index
}]
});
- App.vue(展示页面)
<template>
<div id="app">
<!-- 组件定义html页面 -->
<img src="./assets/logo.png">
<router-link to="/hello">hello页面</router-link>
<router-link to="/">首页</router-link>
<!-- 组件嵌套 使用组件 展示路由页面 -->
<router-view/>
</div>
</template>
<script>
//导入组件
//import HelloWorld from './components/HelloWorld' // ./表示src目录下 .vue可以省略
//导出组件
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>
十九、ElementUI快速开发
安装步骤
1、初始化vue项目 vue init webpack [项目名]
2、进行项目根路径
3、安装路由 npm install [email protected] --save-dev
4、安装elementui npm i element-ui -S
5、安装sass-loader npm install [email protected] --save-dev
6、安装node-sass (nodejs升级到18版本)
npm install -g mirror-config-china --registry=https://registry.npmmirror.com(如果更换了淘宝镜像不需要执行。)
npm install node-sass
6、安装所有的包 npm install
7、运行项目 npm run dev
具体使用看官网:https://element.eleme.cn/#/zh-CN/component/container快速开始
二十、嵌套路由
在router目录下的index.js文件中进行如下配置
import Vue from 'vue'
import Router from 'vue-router'
import login from '../components/login'
import index from '../components/index'
import level from '../components/modules/level'
import list from '../components/modules/list'
import noteFound from '../components/notFound'
Vue.use(Router)
export default new Router({
mode:'history', //默认是hash 请求路径有‘#’ http://localhost:8080/#/index history 没有#
routes:[
{
path:"/index/:name", //为了适配重定向传值
name:"index",
component: index,
//配置子路由
children:[
{
path:"/member/level/:id",
name:"MemberLevel",
component:level,
props:true //开启传值
},
{
path:"/member/list/:id",
name:"MemberList",
component:list
}
]
},
{
path:"/login",
name:"login",
component: login
},
{
path:"/goMain/:name",
redirect:"/index/:name" //重定向跳转 并传值name
},
{
path:"*",
component:noteFound //配置404页面 找不到页面默认跳转的页面
}]
});
子路由视图展示(index.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-message"></i>会员管理</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<router-link :to="{name:'MemberLevel',params:{id:3}}">会员等级</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<!-- 开启传参 -->
<router-link to="/member/list/2">会员列表</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-message"></i>商品管理</template>
<el-menu-item-group>
<el-menu-item index="2-1"><router-link to="/goMain/root">跳转到首页</router-link></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-main>
<router-view />
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name:"index"
}
</script>
<style scoped>
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
二十一、传参方式
//第一种方式 在路由文件中不开启属性值、
{
path:"/member/list/:id",
name:"MemberList",
component:list
}
//请求路径方式
<router-link to="/member/list/2">会员列表</router-link>
//获取值方式
{{$route.params.id}}
//第二种方式 在路由文件中开启属性值
{
path:"/member/level/:id",
name:"MemberLevel",
component:level,
props:true //开启传值
}
//请求路径方式
<router-link :to={name:'MemberLevel',params:{id:3}}>会员列表</router-link>
//页面取值
{{id}} //插值表达式直接在模板中取值
<script>
export default {
name:"grade",
props:["id"] //声明id属性 前提要在路由中开启 props:true
}
</script>
二十二、重定向
不带参的重定向(router/index.js文件中定义)
{
path:"/goMain",
redirect:"/index"
}, {
path:"/index/",
name:"index",
component: index,
children:[
{
path:"/member/level/:id",
name:"MemberLevel",
component:level,
props:true //开启传值
}
带参的重定向
{
path:"/goMain/:name",
redirect:"/index/:name" //重定向跳转 并传值name
}, {
path:"/index/:name", //为了适配重定向传值
name:"index",
component: index,
children:[
{
path:"/member/level/:id",
name:"MemberLevel",
component:level,
props:true //开启传值
}
//取参数值
{{$route.params.id}}
二十三、路由模式
路由模式有两种:
hash:路径带 # 符号,如 http://localhost/#/login
history:路径不带 # 符号,如 http://localhost/login
export default new Router({
mode: 'history',
routes: [
]
});
二十四、404页面
编写一个vue页面(noteFound.vue)
<template>
<div>
<p>找不到页面!</p>
</div>
</template>
<script>
export default {
name:"notFound"
}
</script>
<style>
</style>
在路由配置文件中配置(router/index.js)
{
path:"*",
component:noteFound //配置404页面 找不到页面默认跳转的页面
}
二十五、路由中的钩子函数
beforeRouteLeave:路由离开页面之前执行的钩子函数。(axios使用一般在此函数中)
beforeRouteEnter:路由进入页面之前执行的钩子函数。
/**
* to:路由要跳转的路径信息
* from:路径跳转前的路径信息
* next:路由的控制参数
* next():跳转到下一个页面
* next('/path'):改变路由的方向,使其跳转到另外页面
* next(false):返回原来的页面
* next((vm)=>{}):仅在beforeRouteEnter中可用,vm是组件实例 一般在这个钩子函数中使用异步请求
*
*/
export default {
name:"list",
beforeRouteEnter:(to,from,next)=>{
console.log("进入路由前触发的函数!");
next((vm)=>{
vm.data(); //回调函数在元素加载完成后执行函数
}); //放行
},
beforeRouteLeave:(to,from,next)=>{
console.log("离开路由前触发的函数!");
next(); //跳转到下一个页面
},
methods:{
data:function(){
this.axios({
method:'get',
url:'http://localhost:9999/ssm/queryAll',
}).then(response=>{
console.log(response.data);
}).catch(error=>{
console.log(error);
});
}
}
}
</script>
二十六、钩子函数使用axios异步请求
安装axios
node install axios -S
在main.js中配置使用
import axios from 'axios'
import vue from 'vue'
Vue.prototype.axios = axios
在beforeRouteEnter钩子函数中使用异步请求(在相应页面)
export default {
name:"list",
beforeRouteEnter:(to,from,next)=>{
console.log("进入路由前触发的函数!");
next((vm)=>{
vm.data(); //回调函数在元素加载完成后执行函数
}); //放行
},
methods:{
data:function(){
this.axios({
method:'get',
url:'http://localhost:9999/ssm/queryAll',
}).then(response=>{
console.log(response.data);
}).catch(error=>{
console.log(error);
});
}
}
}
</script>
二十七、VueX使用
在登录成功函数中设置状态值
methods: {
onSubmit(form) {
this.$refs[form].validate((valid) => {
if (valid) {
//登录成功把登录状态存进vuex中
sessionStorage.setItem("state","true");
//传属性name的值到index路由
this.$router.push({name:'index',params:{name:this.form.name}});
//把参数值传到vuex中 执行异步更新方法 传递name值
this.$store.dispatch('asyncUpdateUser',{name:this.form.name});
} else {
this.$message.error("请输入用户名或密码");
return false;
}
});
在main.js中设置路由守卫
import router from 'vue-router'
//在进行入路由页面前判断是否登录
router.beforeEach((to,from,next)=>{
//获取用户登录状态
let isLogin=sessionStorage.getItem("state");
if(to.path=="/logout"){
//清空sessionStorage
sessionStorage.clear();
//跳转到登录页
next({path:"/login"});
}else if(to.path=="/login"){
if(isLogin!=null){
next({path:"/index"}); //跳转到主页
}
//如果登录状态为空则返回登录页
}else if(isLogin==null){
next({path:"/login"}); //如果sessionStorage为空表示未登录 跳转到登录页
}
next(); //执行放行
});
//导入路由
export default router;
二十八、store模块化
封装user对象(../store/module/user.js)
const user={
state:sessionStorage.getItem("state")?JSON.parse(sessionStorage.getItem("state")):{
//定义一个全局变量
user:{
name:''
}
},
//监听state值的最新状态 (计算属性)
getters:{
getUser(state){
return state.user;
}
},
//唯一可以改变state值的方法(同步执行)
mutations:{
updateUser(state,user){
state.user=user;
}
},
//异步执行mutation方法 把user对象传进updateUser()中
actions:{
asyncUpdateUser(context,user){
context.commit('updateUser',user);
}
}
}
export default user;
在store/index.js 使用模块化组件
import Vue from 'vue'
import Vuex from 'vuex'
import user from '../store/module/user'
Vue.use(Vuex)
//获取vuex中状态值 如果有值 就转化为对象 如果没有值就初始化为对象
//暴露Vuex对象
export default new Vuex.Store({
modules:{
user
}
});
为了防止页面跳转数据丢失,vuex状态默认参数值作用单页面,一刷新数据丢失。
<template>
<div id="app">
<welcome/> <!--嵌套使用组件-->
</div>
</template>
<script>
import welcome from './welcome';
//由于vuex中保存的数据是单页面数据 刷新就会恢复原状 所以我们要声明一个监听事件
export default {
name: 'App',
components:{welcome}, //导出组件
mounted(){ //元素加载完成执行的钩子函数
window.addEventListener('unload',this.saveState); //设置为加载事件监听执行函数
},
methods:{
saveState:function(){ //定义函数
//设置状态json字符串
sessionStorage.setItem("state",JSON.stringify(this.$store.state.user));
}
}
}
</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>
页面值取值(插值表达式取值)
<template>
<span>{{$store.getters.getUser.name}}</span>
</template>
标签:index,Vue,name,js,vue,路由
From: https://www.cnblogs.com/smallzengstudy/p/17739899.html