vue第二讲

二、脚手架、路由

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值