二、脚手架、路由
2.1 创建一个项目
注意:以下全篇写的(c)npm代表可以使用npm或者cnpm命令
1.安装node.js( .msi )
官网链接:Download | Node.js
①安装时可以一路next(安装在C盘)
②也可以安装别的目录下:参考:Node.js安装详细教程 - HammerZe - 博客园
安装以后执行命令:node -v
出现此结果即为成功。
2、安装淘宝镜像
为了创建项目的时候快一点可以安装中国的镜像网站
命令:npm install -g cnpm --registry=https://registry.npm.taobao.org
注:-g :代表全局;cnpm中的c代表China ;registry:注册,后面跟的是注册地址
安装镜像后测试
3、安装vue-cli
命令:cnpm install vue-cli -g
注:install可以简写为i
4、安装webpack
命令:cnpm install webpack -g
5、安装webpack客户端
命令:(c)npm install webpack-cli -g
以上这些都只需要安装一次即可
6、使用vue2语法创建项目
语法:vue init webpack 项目名称
这里是创建失败了的
所以转变为使用vue3语法创建项目
语法:vue create 项目名
这时他会提示需要更改vue-cli的版本(卸载旧版本,安装新版本)
选择项目使用的模板(选择自定义版本:Manually select feature)
选择要使用的功能(空格即可选中)
>(*) Babel 底层语言代码解析 ( ) TypeScript 脚本 ( ) Progressive Web App (PWA) Support 项目支持 (*) Router 路由 ( ) Vuex 信息存储 ( ) CSS Pre-processors ( ) Linter / Formatter 代码格式要求 ( ) Unit Testing 单元测试 ( ) E2E Testing
选中这两个即可
选择版本号:选择2.x版本
选择其他
项目建成
使用路径进行访问
访问成功页面
项目结构
2.1.1 vue2与vue3版本创建项目的不同:
1、创建项目 vue2:vue init webpack 项目名字 vue3:vue create 项目名字
2、启动项目 2.0 启动命令:npm run dev 3.0 启动命令:npm run serve
vue2/3两种形式创建出来的项目的结构是不一样的
2.1.2 安装路由
如果上面选择功能时,没有选择路由,可以通过命令来安装路由
命令:(c)npm install vue-router --save-dev
注:--save-dev : 保存到开发配置里面 ,这里也可以不加
2.1.3 使用路由
讲解如下:
1、创建router文件夹
2、router文件夹下面建一个 index.js 的文件
3、导入路由(在router/index.js页面)
import Vue from 'vue'
import VueRouter from 'vue-router'
//使用路由
Vue.use(VueRouter);
4、导入组件、使用组件
//这里使用的是立即加载方式:占用内存较大
//使用相对路径导入刚刚新创建的组件
//import User from '../views/user/user.vue'
//使用绝对路径导入组件,这里规定使用@来替代src
import User from '@/views/user/user.vue'
//定义路由 ,下面定义路由时使用
const routes = [
{
path: '/', //路径
name: 'home',
component: HomeView //指向的组件
},
{
//路径必须以斜杠为开头
path: '/user',//path要求唯一不重复
name: 'user',//name属性可以不写,写的话就不能重复
//component: User//路由在上面已经导入,立即加载方式
component: () => import('@/views/user/user.vue')
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
//重新定义的路径的路由,这里new的名字必须和上面保持一致
const router = new VueRouter({
mode: 'history', //历史模式(可不写)
base: process.env.BASE_URL,
routes //定义的规则
})
//定义完路由后要设置为向外导出,方便其他地方使用时进行导入
export default router
或者可以写为另一种形式
import index from '../src/components/index'
import con from '../src/components/content'
//暴露定义的路由方便其他地方导入
export default new VueRouter({
routes:[
///定义路由的规则
{
path:"/index",//要写,而且要唯一不重复
name:"index",//可以不写,写出来的必须唯一不重复
component:index
},{
path:"/con",
name:"con",
component:con
}
]
})
5、在主组件中配置路由的链接
<!-- 存放主组件之外的其他组件;这里关闭之后,将无法再加载其他组件 -->
<router-view/>
2.2 项目结构解读
项目结构如下:
从上往下依次解读,没有的暂时不用
2.2.1 components
components是一个存放组件的文件夹,
HelloWorld这个文件就是一个组件
以 .vue结尾的文件就是一个组件
template中写的html静态代码
script中编写脚本语句(js代码)
style中写样式
2.2.2 router
router是存放路由的文件夹
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
//1、这里使用的是立即加载方式:占用内存较大
//使用相对路径导入刚刚新创建的组件
//import User from '../views/user/user.vue'
//使用绝对路径导入组件,这里规定使用@来替代src
import User from '@/views/user/user.vue'
Vue.use(VueRouter) ///vue使用路由
//定义路由 ,下面定义路由时使用
const routes = [
{
path: '/', //路径
name: 'home',
component: HomeView //指向的组件
},
{
//路径必须以斜杠为开头
path: '/user',//path要求唯一不重复
name: 'user',//name属性可以不写,写的话就不能重复
//component: User//路由在上面已经导入,立即加载方式
//2、延迟加载方式(推荐)
component: () => import('@/views/user/user.vue')
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
//重新定义的路径的路由,这里new的名字必须和上面保持一致
const router = new VueRouter({
mode: 'history', //历史模式(可不写)
base: process.env.BASE_URL,
routes //定义的规则
})
//定义完路由后要设置为向外导出,方便其他地方使用时进行导入
export default router
2.2.3 views
也是存放组件的文件夹
user.vue:这是自测使用的组件
<template>
<!--
这里只能有一个闭合标签:例如<div></div>,有多个的话会直接报错
在这一个闭合标签里可以写任意个闭合标签
-->
<div>
<h1> Hello MoXi~</h1>
</div>
</template>
<script>
</script>
<style>
</style>
2.2.4 App.vue(主组件)
<template>
<div id="app">
<nav>
<!-- 主页渲染首先渲染的就是这里 -->
<!--
node服务器在8080被占用时,会自动跳转到8081
-->
<!-- router-link to标签这里,点击之后会根据路径跳转到相应的组件 -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<!-- 存放主组件之外的其他组件;这里关闭之后,将无法再加载其他组件 -->
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
2.2.5 main.js(项目入口)
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//导入需要使用的文件
//导入的语法:import 自定义名字 from 文件
Vue.config.productionTip = false
new Vue({
router, //路由,当键名和值名相同时,可以只写一个
render: h => h(App) //通过箭头函数渲染到主组件App.vue中
}).$mount('#app')
示例:
/*
如果要通过路径访问一个页面:以http://localhost:8080/为例
先访问主组件App.vue,然后再在<router-view/>中查看是否还有放置别的组件,
再去router中去寻找对应的路径,再根据对应的路径找到相应的组件(HomeView.vue)
根据组件中的内容去加载响应的文件,这里HomeView.vue还引用了HelloWorld.vue组件中的东西
*/
2.3 加入ElementUI
elementUI官网:Element - The world's most popular Vue UI framework
1、安装elementUI
命令:cnpm install element-ui -S
2、在main.js中引入elementUI
// 引入elementUI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 使用elementUI
Vue.use(ElementUI);
2.4 测试表单验证
新建一个组件(subtest.vue)
从官网粘贴表单验证的代码即可
<template>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="即时配送" prop="delivery">
<el-switch v-model="ruleForm.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质" prop="type">
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></el-input>
</el-form-item>
<el-form-item>
<!-- 提交按钮绑定了点击事件,点击会执行下面函数,函数会进行验证
ruleForm是表单的绑定model属性的值
-->
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
ruleForm: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
// 定义的校验规则:这里也可以使用自定义校验
rules: {
// 这里的name 对应上面prop属性中的值
name: [{
required: true,//必填项
message: '请输入活动名称',//失焦时提示的信息
trigger: 'blur'//绑定的事件
},
{
min: 3,
max: 5,
message: '长度在 3 到 5 个字符',//
trigger: 'blur'
}
],
region: [{
required: true,
message: '请选择活动区域',
trigger: 'change'
}],
date1: [{
type: 'date',
required: true,
message: '请选择日期',
trigger: 'change'
}],
date2: [{
type: 'date',
required: true,
message: '请选择时间',
trigger: 'change'
}],
type: [{
type: 'array',
required: true,
message: '请至少选择一个活动性质',
trigger: 'change'
}],
resource: [{
required: true,
message: '请选择活动资源',
trigger: 'change'
}],
desc: [{
required: true,
message: '请填写活动形式',
trigger: 'blur'
}]
}
};
},
methods: {
submitForm(formName) {
// 函数对表单进行验证,如果通过则提交,不通过则提示
this.$refs[formName].validate((valid) => {
if (valid) {
// alert('submit!');
// 如果成功,跳转页面,这里使用push和replace是一样的
//this.$router.push("/about")//方式一:
//this.$router.replace("/about")//方式二,方式三的简略版
//this.$router.replace({path:"/about"})//方式三
this.$router.replace({name:"about"})//方式四
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script>
<style>
</style>
再在路由中配置相应的路径
{
path:'/subtest',
name:'subtest',
component:() => import('@/views/test/subtest.vue')
}
2.5 测试路由嵌套
类似这样一个后台管理系统的实现会用到路由嵌套
1、实现这样的布局
在Container 布局容器 中找对应的布局作为主体组件(main.vue)
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
<el-footer>Footer</el-footer>
</el-container>
</el-container>
<style>
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 160px;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
</style>
2、实现对应的导航
在Container 布局容器 组件中找到此样式的导航
替换掉主体组件中的<el-aside>及其里面的内容
<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>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-menu"></i>导航二</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="2-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="3">
<template slot="title"><i class="el-icon-setting"></i>导航三</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="3-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="3-4">
<template slot="title">选项4</template>
<el-menu-item index="3-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu>
</el-aside>
3、创建一个组件作为即将显示出来的内容
这里选择一个表格作为要显示的内容
<template>
<el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">
<el-table-column prop="date" label="日期" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</template>
<script>
export default {
methods: {
tableRowClassName({
row,
rowIndex
}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
}
},
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}]
}
}
}
</script>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
4、添加该组件作为主体组件的子组件
在index.js中,添加该组件的路径,位置在主体组件的children属性中
这里即是使用了嵌套路由
{
path:'/main',
name:'main',
component:() => import('@/views/test/main.vue'),
children:[
// 路由嵌套:设置要显示的路由为当前路由的子路由
{
path:'/table',
name:'table',
component: () => import('@/views/test/table.vue')
}
]
}
5、然后修改主体组件代码
绑定路由 && 设置存放组件的地方 && 同步路由
<template>
<el-container>
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<!-- 3、:router="true" ******同步路由规则***** -->
<el-menu :default-openeds="['1', '3']" :router="true">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>导航一</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<!-- 1、***********绑定路由******** -->
<!-- 第一种方式:使用 :route属性指定名字或路径 -->
<!-- <el-menu-item index="1-1" :route="{name:'about'}">选项1</el-menu-item> -->
<!-- 第二种方式 使用index属性指定名字或路径-->
<el-menu-item index="about" >选项1</el-menu-item>
<!-- 指向表格 -->
<el-menu-item index="1-2" :route="{path:'/table'}">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-menu"></i>导航二</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="2-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="3">
<template slot="title"><i class="el-icon-setting"></i>导航三</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="3-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="3-4">
<template slot="title">选项4</template>
<el-menu-item index="3-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>
<!-- 2、(************设置存放组件的地方*************** -->
<router-view></router-view>
</el-main>
<el-footer>Footer</el-footer>
</el-container>
</el-container>
</template>
<script>
</script>
<style>
.el-header,
.el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 10px;
}
body>.el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
</style>