文章目录
Vue-cli
什么是vue-cli
vue-cli 官方提供的一个脚手架,用于快速生成一个vue的项目模板;
预先定义好的目录结构及基础代码,就好比创建Maven项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速;
主要的功能:
-
统一的目录结构
-
本地调试
-
热部署
-
单元测试
-
集成打包上线
需要的环境
-
**Node.js : http://nodejs.cn/download/ ** 安装就无脑下一步就好,安装在自己的环境目录下
-
Git : https://git-scm.com/downloads
-
镜像:https://npm.taobao.org/mirrors/git-for-windows/
确认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
虽然安装了cnpm,但是尽量少用!
安装的位置:C :\Users \Administrator \AppData \Roaming \npm
安装vue-cli
cnpm install vue-cli -g
#测试是否安装成功
#查看可以基于哪些模板创建vue 应用程序,通常我们选择webpack
vue list
第一个vue-cli应用程序
1.创建一个Vue项目,在D盘下新建一个目录
D:\Project \ vue-study ;
2.创建一个基于webpack模板的vue应用程序
#这里的myvue是项目名称
vue init webpack myvue
为了体验创建过程,一路都选择no即可
3.初始化并运行(以管理员身份运行)
npm install
npm run dev
#执行完成后,目录多了很多依赖
window下的cmd命令
-
从C盘切到F盘:F:
-
从一个盘切换到另外一个盘的文件夹下 加上 /d 参数
webpack的使用
WebPack是一款模块加载器兼打包工具, 它能把各种资源, 如JS、JSX、ES 6、SASS、LESS、图片等都作为模块来处理和使用。
webpack默认不支持es6语法,一般使用es5,若需使用es6的export和import,需要先用babel转码成es5再用webpack打包。
安装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.config.js文件主要内容:
module.exports = {
entry:"",
output:{
path:"",
filename:""
},
module:{
loaders:[
{test:/\.js$/,;\loade:""}
]
},
plugins:{},
resolve:{},
watch:true
}
webpack的使用
- 创建项目
- 创建文件夹,并创建hello.js文件
module.exports={
say(){
document.write("Hello Webpack!")
}
}
- 创建main.js入口文件
const hello = require('./hello')
hello.say()
- 在项目根目录下创建webpack.config.js文件
module.exports={
entry:"./module/main.js",
output:{
filename:'./js/bundle.js'
},
}
-
执行
webpack
命令,打包到dist文件夹下 -
若出现以下错误,在webpack.config.js文件中设置mode,
mode: 'development'
- 创建html文件,使用改打包的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>
- 运行html,查看效果
注意:
参数–watch 用于监听变化,
如果要打包的东西有变化,就重新打包
webpack --watch
vue-router路由
安装路由
npm install vue-router --save-dev
或者
npm install --save vue-router@3
(注:vue-router@3适配vue2,而vue-router@4适配vue3)
使用路由:
import Vue from 'vue'
import VueRouter from 'vue-router'
//显示声明使用路由
Vue.use(VueRouter);
路由的使用案例
- 在component文件夹下创建3个组件,main.vue,content.vue,helloworld.vue
<template>
<div>主页</div>
</template>
<script>
export default {
name: "main"
}
</script>
<style scoped>
</style>
<template>
<div>内容页</div>
</template>
<script>
export default {
name: "content"
}
</script>
<style scoped>
</style>
<template>
<div>ZjiaW</div>
</template>
<script>
export default {
name: 'HelloWorld'
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
-
创建router文件夹,在该文件夹下创建index.js文件(默认配置文件名为index)
-
在路由默认配置index.js文件下导入Vue、vue-router模块和三个组件
import Main from '../components/main'
import Content from '../components/content'
import HelloWorld from "../components/HelloWorld";
import Router from 'vue-router'
import Vue from 'vue'
Vue.use(Router)
export default new Router({
routes:[
{
path:'/content',
name:'Content',
component:Content
},
{
path:'/main',
name:'Main',
component:Main
},
{
path:'/helloworld',
name:'HelloWorld',
component:HelloWorld
}
]
})
- 在main.js中配置路由
// 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 router from './router' //默认找到router文件夹下的index.js文件
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
- 在首页App.vue中写入路由链接
<router-link to='路由里的path路径'></router-link>
和视图<router-view></router-view>
<template>
<div id="app">
<router-link to="/main">主页</router-link>
<router-link to="/content">内容页</router-link>
<router-link to="/helloworld">hello</router-link>
<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>
npm run dev
运行程序
vue-cli结合elementUI案例
创建项目
- 创建项目 hello-vue
vue init webpack hello-vue
- 安装模块( vue-router、element-ui、sass-loader和node-sass四个插件)
#进入工程目录
cd hello-vue
#安装vue-router
npm install vue-router@3 --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
#安装SASS加载器
npm install sass-loader@7.3.1 --save-dev
npm install node-sass --save
npm install style-loader --save
#或者
cnpm install sass-loader@7.3.1 node-sass --save-dev
#@7.3.1不行就改成@4.0.0
#启功测试
npm run dev
npm命令说明
npm install moduleName
:安装模块到项目目录下
npm install -g moduleName
:-g的意思是将模块安装到全局,具体安装到磁盘哪个位置要看npmconfig prefix的位置
npm install -save moduleName
:–save的意思是将模块安装到项目目录下, 并在package文件的dependencies节点写入依赖,-S为该命令的缩写
npm install -save-dev moduleName
:–save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写
-
idea打开创建好的项目
-
新建router文件夹并创建index.js默认配置文件
-
在入口文件main.js导入router和element依赖并使用
import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'; //需要安装sass加载器
import router from './router'
Vue.config.productionTip = false
Vue.use(router)
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
render: h => h(App)
});
创建登录页面
- 先创建Main.vue页面,和Login.vue页面
main.vue:
<template>
<div>
主页
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
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:"密码不可为空",tigger:"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>
<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:"密码不可为空",tigger:"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>
- 在路由中导入组件并写入路径
import Vue from "vue";
import Router from 'vue-router'
import Main from "../components/Main";
import Login from "../components/Login";
Vue.use(Router)
export default new Router({
routes:[
{
path:'/main',
name:'Main',
component:Main
},
{
path:'/login',
name:'Login',
component:Login
}
]
})
- 在App.vue页面写入路由视图
<router-view></router-view>
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
npm run dev
运行程序
说明:
如果出现错误: 可能是因为sass-loader的版本过高导致的编译错误 ,可以去package.json文件中把sass-loder的版本降低,也有可能是node-sass版本过高,看报错内容修改相应的版本。
路由嵌套-子路由
嵌套路由又称子路由,在实际应用中,通常由多层嵌套的组件组合而成。
-
子路由:该路径的组件会在父路由下显示
-
路由编写的优先级:谁在前面,谁的优先级高
案例
- 在view文件夹下创建用户列表List.vue和个人信息ProFile.vue
List.vue:
<template>
<div>
用户列表
</div>
</template>
<script>
export default {
name: "List"
}
</script>
<style scoped>
</style>
ProFile.vue:
<template>
<div>
用户个人信息
</div>
</template>
<script>
export default {
name: "ProFile"
}
</script>
<style scoped>
</style>
- 添加两个组件的路由
import Vue from "vue";
import Router from 'vue-router'
import Main from "../components/Main";
import Login from "../components/Login";
import List from "../view/List";
import ProFile from "../view/ProFile";
Vue.use(Router)
export default new Router({
routes:[
{
path:'/main',
name:'Main',
component:Main,
children:[
{
path:'/user/list',
name:'List',
component:List
},
{
path:'/user/profile',
name:'ProFile',
component:ProFile
}
]
},
{
path:'/login',
name:'Login',
component:Login
}
]
})
- 修改Main.vue页面,写入侧边栏,并将上面两个组件添加路由链接到main页面
<template>
<div>
<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-submenu index="3">
<template slot="title"><i class="el-icon-caret-right"></i>系统管理</template>
<el-menu-item-group>
</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 />
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped lang="scss">
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
参数传递
方法一
- 修改路由配置, 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符
{
path: '/user/profile/:id',
name:'Profile',
component: Profile
}
- 视图层传递参数
<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'Profile',params:{id:1}}">个人信息</router-link>
- Profile.vue页面接受参数id
<template>
<div>
用户个人信息{{ $route.params.id }}<br>
</div>
</template>
方法二
使用props 减少耦合
- 在路由中允许使用props
{
path:'/user/profile/:id',
name:'ProFile',
props: true,
component:ProFile
}
- 接受参数在export中写入props属性,然后用{{id}}显示
<template>
<div>
用户个人信息{{ $route.params.id }}<br>
{{id}}
</div>
</template>
<script>
export default {
name: "ProFile",
props:['id']
}
</script>
重定向
- 在路由配置中添加重定向路由,重定向到某个路径
redirect: '/main'
import Vue from "vue";
import Router from 'vue-router'
import Main from "../components/Main";
import Login from "../components/Login";
import List from "../view/List";
import ProFile from "../view/ProFile";
Vue.use(Router)
export default new Router({
routes:[
{
path:'/main', //没有登录时也可以访问主页
name:'Main',
component:Main,
props: true,
children:[
{
path:'/user/list',
name:'List',
props: true,
component:List
},
{
path:'/user/profile/:id',
name:'ProFile',
props: true,
component:ProFile
}
]
},
{
path:'/gohome',
name:'gohome',
redirect: '/main'
}
]
})
- 使用路由链接进行重定向
<router-link to="/gohome">重定向</router-link>
路由模式(去除url中的#)
路由模式有两种
- hash:路径带 # 符号,如 http://localhost/#/login
- history:路径不带 # 符号,如 http://localhost/login
修改路由配置
export default new VueRouter({
mode:'history',
routes: []
)}
404页面
- 创建404页面
<template>
<div>
404你的页面走丢了...
</div>
</template>
<script>
export default {
name: "NOFound"
}
</script>
<style scoped>
</style>
- 为该页面写入路由,在最后一个路由中写404页面的路径。上面的路径不匹配就会找到最后一个*。
import NOFound from "../view/404"
{
path:'*',
component:NOFound
}
路由钩子
- beforeRouteEnter:在进入路由前执行
- beforeRouteLeave:在离开路由前执行
使用方法
<script>
export default {
name: "Profile",
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 是组件实例
axios异步请求
在进入路由前获取到后端的数据。
这里写入静态的数据
- 安装axios
npm install --save axios vue-axios
- 在入口文件导入axios并使用
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
- 在static下创建mock(测试)文件夹,然后创建data.json文件
{
"name": "ZjiaW",
"url": "https://blog.csdn.net/qq_53261858?type=blog",
"page": 1,
"isNonProfit": true,
"address": {
"street": "含光门",
"city": "陕西西安",
"country": "中国"
},
"links": [
{
"name": "bilibili",
"url": "https://bilibili.com"
},
{
"name": "早餐有胃口吗",
"url": "https://blog.csdn.net/qq_53261858?type=blog"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
说明:
只有我们的 static 目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。
- axios请求获取参数,将数据返回到前端保存,并显示在页面
- 注意axios中要使用箭头函数
- 可以将axios请求放到mounted钩子函数中,然后beforeRouteEnter中vm.mounted即可
<template>
<div>
用户个人信息{{ $route.params.id }}<br>
{{id}}<br/>
姓名:{{info.name}}
url:{{info.url}}
</div>
</template>
<script>
export default {
name: "ProFile",
props:['id'],
data(){
return{ //根据钩子函数将数据返回到这里,格式必须为json格式
info:{
name:'',
url:''
}
}
},
beforeRouteEnter: (to, from, next) => {
console.log("准备进入个人信息页");
next(vm=>{
vm.getData()
})
},
beforeRouteLeave: (to, from, next) => {
console.log("准备离开个人信息页");
next();
},
methods:{
getData(){
this.axios({
method:'get',
url:'http://localhost:8080/static/data.json',
}).then(response=>{
console.log(this.id)
console.log(response.data)
this.info = response.data
})
}
}
}
</script>
<style scoped>
</style>