一. Vue项目搭建
1. cmd命令cd
用管理员身份运行 cmd, 目录切换到项目要创建的文件夹
2. 初始化工程
使用webpack打包工具初始化一个名为 vue-elementui 的工程
vue init webpack vue-elementui
这里稍微会有一点慢,我大概等了3分钟左右,然后根据以下截图选择即可:
等待3分钟左右,出现以下界面则安装完成。
3. 安装vue-router
npm install vue-router --save-dev
安装过程中,若无报错则继续
我有以下报错,npm ERR! peer vue@"^3.2.0" from vue-router@4.2.4
这是因为2022年2月7日以后,vue-router的默认版本,为4版本,而且 vue-router4,只能在vue3中,我目前vue是版本2 ,因此vue2中需要改成vue-router3
命令指定vue-router的版本为3,即可安装成功
npm install vue-router@3 --save-dev
4. 安装ElementUI
npm i element-ui -S
5. 安装SASS加载器
npm install sass-loader@7.3.1 node-sass --save-dev
说明: sass-loader默认不指定版本是最新的8.0.x,运行可能出现问题,所以指定版本安装
6. 安装项目所有依赖
npm install
7. 项目启动测试
npm run dev
浏览器访问成功:
二. 项目实战
1. 设置路由成功
1-1 项目开始从App.vue入手,删掉原来的页面展示代码和style样式,并添加路由标签<router-view />, HelloWorld.vue删掉,如下:
<template>
<div id="app">
<!-- 项目自带的,注释掉 -->
<!-- <img src="./assets/logo.png">
<HelloWorld/> -->
<router-view />
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
// components: {
// HelloWorld
// }
}
</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> -->
1-2 新建一个登录页面,路径为/src/views/Login.vue,将这个页面暴露出去
<template>
<div>
我是登录页
</div>
</template>
<script>
export default {
name: 'login'
}
</script>
<style lang="">
</style>
1-3 主页面和登录页面要建立关联,因此创建/src/router/index.js文件,来实现路由功能
引入'vue-router'并使用,将登录页面Login.vue跟访问路径对应起来
import Vue from 'vue'
import Router from 'vue-router'
import Login from '../views/Login.vue'
Vue.use(Router);
export default new Router({
routes: [{
//登录页
path: '/login',
name: 'login',
component: Login
}]
})
1-4 main.js文件需要引入'vue-router'和elementui相关依赖,看elementui官网:
https://element.eleme.cn/#/zh-CN/component/quickstarthttps://element.eleme.cn/#/zh-CN/component/quickstart
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(VueRouter);
Vue.use(ElementUI);
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
现在,一个简单的页面路由就可以测试成功啦
2. 登录页面绘制
2-1 登录页面绘制
<template>
<div>
<el-form ref="form" :model="form" label-width="40px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号">
<el-input type="text" placeholder="请输入账号" v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" placeholder="请输入密码" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'login',
data() {
return {
form: {
name: '',
password: ''
}
}
},
methods: {
onSubmit() {
alert("登录中");
}
}
}
</script>
<!--scoped是指只在本页面生效-->
<style lang="css" scoped>
.login-box{
width: 350px;
margin: 120px auto;
border: 1px solid #DCDFE6;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 30px #DCDFE6;
}
.login-title{
text-align: center;
}
</style>
2-2 登录成功,跳转主页面绘制 /src/views/Main.vue
<template>
<div>
首页
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
在index.js中增加路由配置,在Login.vue中增加跳转代码
3. 登录验证
组件从ElementUI官网直接抄现成的 /src/views/Login.vue
<template>
<div>
<el-form ref="form" :model="form" :rules="rules" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号" prop="name">
<el-input type="text" placeholder="请输入账号" v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('form')">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'login',
data() {
return {
form: {
name: '',
password: ''
},
rules: {
name: [
{required: true, message: '请输入账号', trigger: 'blur'}
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
],
}
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$router.push("/main");
} else {
this.$message({
message: '请输入用户名和密码',
type: 'warning'
});
return false;
}
});
},
}
}
</script>
<!--scoped是指只在本页面生效-->
<style lang="css" scoped>
.login-box {
width: 350px;
margin: 120px auto;
border: 1px solid #DCDFE6;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 30px #DCDFE6;
}
.login-title {
text-align: center;
}
</style>
4. 嵌套路由与参数传递
4-1 路由嵌套
主要适用于一个主页面,有侧边栏、导航栏和中间动态的部分,点击侧边栏,中间内容随着变化的场景,中间变化的内容便是嵌套的路由
4-1-1 在中间嵌套路由那里用 <router-view />占用位置
4-1-2 中间部分需要新建页面,如MemberLevel.vue
<template>
<div>
会员等级
</div>
</template>
<script>
export default {
name: "MemberLevel"
}
</script>
<style scoped>
</style>
4-1-3 子路由需要配置在/src/router/index.js中
import Vue from 'vue'
import Router from 'vue-router'
import Login from '../views/Login.vue'
import Main from '../views/Main.vue'
import MemberLevel from "../views/member/MemberLevel";
import MemberList from "../views/member/MemberList";
Vue.use(Router);
export default new Router({
routes: [{
//登录页
path: '/login',
name: 'login',
component: Login
},
{
//首页
path: '/main',
name: 'main',
component: Main,
//子路由
children: [
{
//会员等级
path: '/member/level',
name: 'MemberLevel',
component: MemberLevel
},
{
//会员等级
path: '/member/list',
name: 'MemberList',
component: MemberList
}
]
},
]
})
4-1-4 路由跳转配置在页面点击处,跟超链接的概念一致 /src/views/Main.vue
<router-link to="/member/level">会员等级</router-link>
<template>
<div>
<el-container>
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '2']">
<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="/member/level">会员等级</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<router-link to="/member/list">会员列表</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">商品分类</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>
<span>王小虎</span>
</el-header>
<el-main>
<!--嵌套路由-->
<router-view />
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
4-2 参数传递
4-2-1 路径匹配的两种方式
{ //会员等级 path: '/member/level/:id', name: 'MemberLevel', component: MemberLevel }
说明:主要是在path属性中增加了:id这样的占位符
取值方式:
<div> 会员等级 ID= {{$route.params.id}} </div>
<!--第一种方式--> <router-link to="/member/level/1">会员等级</router-link> <!--第二种方式--> <router-link :to="{name: 'MemberLevel', params: {id:2}}">会员等级</router-link>
4-2-2 props的方式
{ //会员等级 path: '/member/level/:id', name: 'MemberLevel', component: MemberLevel, props: true }
export default { props:['id'], name: "MemberLevel" }
取值方式:
会员等级 ID= <!--{{$route.params.id}}--> {{id}}
5. 组件重定向
<el-menu-item index="1-3"> <router-link to="/main/admin123">返回首页</router-link> </el-menu-item>
{ //重定向 path: '/goMain/:name', redirect: '/main/:name' }
6. 路由模式 + 处理404
6-1 之前访问路径http://localhost:8080/#/login 总带有‘#’,可以这种方式去掉
export default new Router({ mode: 'history',
6-2 有些页面找不到资源的时候,需要报错404
新增报错页面 ,然后在页面加以下配置即可
{ path: '*', component: Error }
7. 路由钩子函数 + 异步请求
7-1 钩子函数
/*路由钩子*/ beforeRouteEnter: (to, from, next) => { console.log("进入会员等级页面"); next(); }, beforeRouteLeave: (to, from, next) => { console.log("离开会员等级页面"); next(); }
7-2 异步请求
安装axios
npm install axios -s
在main.js文件中引入并使用axios
import axios from "axios"; Vue.prototype.axios = axios;
7-3 使用
methods: { getData: function () { this.axios({ method: 'get', url: 'http://localhost:8080/data.json', }).then(function (repos) { console.log(repos); }).catch(function (error) { console.log(error); }) } }
/*路由钩子*/ beforeRouteEnter: (to, from, next) => { console.log("进入会员等级页面"); next(vm => { vm.getData(); }); },
这里,我遇到一个跨域的问题,后续解决完再回来补充
8. Vuex判断用户是否登录
安装Vuex,引入并使用
npm install vuex@3 --save
import Vuex from "vuex";
Vue.use(Vuex);
sessionStorage.setItem('isLogin', 'true'); // 路由跳转之前 router.beforeEach((to, from, next)=>{ let isLogin = sessionStorage.getItem('isLogin'); if (to.path == '/logout'){ //清空 sessionStorage.clear(); //跳转到登录页面 next({path:'/login'}); }else if (to.path == '/login') { if (isLogin != null) { next({path:'/main'}); } }else if (isLogin == null) { next({path:'/login'}); } next(); })