Vue Series Twelve: Get Started Quickly in Actual Combat

We adopt the practical teaching mode and combine the ElementUI component library to apply the required knowledge points to practice, and lead you to master the use of Vue as quickly as possible;

12.1. Create a project

Note: The command line must be run in administrator mode
1. Create a project named hello-vue vue init webpack hello-vue
2. To install dependencies, we need to install four plugins, vue-router, element-ui, sass-loader and node-sass

#进入工程目录
cd hello-vue
#安装vue-routern 
npm install vue-router --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
# 安装SASS加载器
cnpm install sass-loader node-sass --save-dev
#启功测试
npm run dev

3. Npm command explanation:

  • npm install moduleName: Install the module to the project directory
  • npm install -g moduleName:-g means to install the module to the global, the specific location of the installation to the disk depends on the location of the npm config prefix
  • npm install -save moduleName:--save means to install the module into the project directory, and write dependencies in the dependencies node of the package file, -S is the abbreviation of this command
  • npm install -save-dev moduleName:--save-dev means to install the module into the project directory and write dependencies in the devDependencies node of the package file, -D is the abbreviation of this command

12.2. Create a login page

Delete useless initialization things!
  Create the following structure in the source directory:

  • assets: used to store resource files
  • components: used to store Vue functional components
  • views: used to store Vue view components
  • router: used to store vue-router configuration

To create the home page view, create a view component named Main.vue in the views directory:

<template>
	<div>首页</div>
</template>
<script>
	export default {
			name:"Main"
	}
</script>
<style scoped>
</style>

Create a login page view Create a view component named Login.vue in the views directory, where the elements of el-* are ElementUI components;

<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>

To create a route, create a index.jsrouting configuration file named vue-router in the router directory

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
      //登录页
      path: '/main',
      component: Main
    },
    //首页
    {
      path: '/login',
      component: Login
    },
  ]

})

APP.view

<template>
  <div id="app">
    <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>

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"

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(router)
Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render:h=>h(App)
})

Test: Open http://localhost:8080/#/login in the browser
If there is an error: It may be a compilation error caused by the high version of sass-loader. The current highest version is 8.0.2, and you need to return to 7.3.1 ;
Go to the "sass-loader" version in the package.json file and replace it with 7.3.1, and then re-cnpm install it;

12.3, routing nesting

Nested routing, also known as sub-routing, is usually composed of multiple layers of nested components in practical applications.
demo
1. Create a user information component, and create a view component named Profile.vue in the views/user directory;
Profile.vue

<template>
  <h1>个人信息</h1>
</template>
<script>
  export default {
    name: "UserProfile"
  }
</script>
<style scoped>
</style>

2. In the user list component, create a view component named List.vue in the views/user directory;
List.vue

<template>
  <h1>用户列表</h1>
</template>
<script>
  export default {
    name: "UserList"
  }
</script>
<style scoped>
</style>

3. To modify the home page view, we modify the Main.vue view component. The ElementUI layout container component is used here. The code is as follows:
Main.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-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-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>

4. Configure nested routing Modify the index.js routing configuration file in the router directory, and use children to put it into the main to write a submodule. The code is as follows
index.js

//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//导入子模块
import UserList from "../views/user/List";
import UserProfile from "../views/user/Profile";

//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
  routes: [
    {
      //登录页
      path: '/main',
      component: Main,
      //  写入子模块
      children: [
        {
          path: '/user/profile',
          component: UserProfile,
        }, {
          path: '/user/list',
          component: UserList,
        },
      ]
    },
    //首页
    {
      path: '/login',
      component: Login

    },
  ]
})

5. Routing nesting actual combat renderings

Graph routing nested renderings

12.4, parameter passing

Here is a demonstration of how to pass the
demo if the request has parameters. The
 code in the above example is used to modify some code. The repeated code is not placed here
. The first value method
1. Modify the routing configuration, mainly in the index.js under the router. Added placeholders such as :id to the path attribute

{
	path: '/user/profile/:id', 
	name:'UserProfile', 
	component: UserProfile
}

2. Passing parameters
 At this time, we changed to:to at the route-link position in Main.vue, in order to use this attribute as an object. Note that the name attribute name in router-link must be the same as the name in the route. The property names match, because then Vue can find the corresponding routing path;

<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>

3. Receive parameters in the component Profile.vue to be displayed Use {undefined{$route.params.id}} to receive the
Profile.vue part of the code

<template>
  <!--  所有的元素必须在根节点下-->
  <div>
    <h1>个人信息</h1>
    {
   
   {$route.params.id}}
  </div>
</template>

The second value method uses props to reduce coupling
1. Modify the routing configuration, mainly adding the props: true attribute to the routing attribute in index.js under router

{
	path: '/user/profile/:id', 
	name:'UserProfile', 
	component: UserProfile, 
	props: true
}

2. Modify the route-link address in Main.vue as before by passing parameters

<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>

3. Receive parameters in Profile.vue to add props properties to the target component
Profile.vue

<template>
  <div>
    个人信息
    {
   
   { id }}
  </div>
</template>
<script>
    export default {
      props: ['id'],
      name: "UserProfile"
    }
</script>
<style scoped>
</style>

Image transmission reference renderings

12.5, component redirection

Everyone understands the meaning of redirection, but redirection in Vue works when the path is different but the components are the same, for example:
the configuration of index.js under the router

{
  path: '/main',
  name: 'Main',
  component: Main
},
{
  path: '/goHome',
  redirect: '/main'
}

Description: Two paths are defined here, one is /main and the other is /goHome, where /goHome redirects to the /main path, it can be seen that redirection does not need to define components;

If you use it, you only need to set the corresponding path in Main.vue;

<el-menu-item index="1-3">
    <router-link to="/goHome">回到首页</router-link>
</el-menu-item>

12.6. Routing mode and 404

There are two routing modes

  • hash: path with # symbol, such as http://localhost/#/login
  • history: path without # symbol, such as http://localhost/login

Modify the routing configuration, the code is as follows:

export default new Router({
  mode: 'history',
  routes: [
  ]
});

404 demo
1. Create a NotFound.vue view component
NotFound.vue

<template>
    <div>
      <h1>404,你的页面走丢了</h1>
    </div>
</template>
<script>
    export default {
        name: "NotFound"
    }
</script>
<style scoped>
</style>

2. Modify the routing configuration index.js

import NotFound from '../views/NotFound'
{
   path: '*',
   component: NotFound
}

3. Rendering
 

 

Figure 404 renderings

Routing hooks and asynchronous requests

beforeRouteEnter: execute before entering the route
beforeRouteLeave: execute before leaving the route

Write in Profile.vue

  export default {
    name: "UserProfile",
    beforeRouteEnter: (to, from, next) => {
      console.log("准备进入个人信息页");
      next();
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("准备离开个人信息页");
      next();
    }
  }

Parameter description:
to: the path information to be jumped by the route
from: the path information before the route jump
next: the control parameter of the route
next() jump to the next page
next('/path') Change the jump direction of the route to make It jumps to another route
next(false) returns the original page
next((vm)=>{}) is only available in beforeRouteEnter, vm is the component instance

Using Asynchronous Requests in Hook Functions

1. Install Axios

cnpm install --save vue-axios
  • 1

2. Main.js references Axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

3. Prepare data: Only the files in our static directory can be accessed, so we put the static files in this directory.
The data is the same as the json data used before and needs to go to the above axios example

// 静态数据存放的位置
static/mock/data.json

4. Make an asynchronous request in beforeRouteEnter
Profile.vue

  export default {
    //第二种取值方式
    // props:['id'],
    name: "UserProfile",
    //钩子函数 过滤器
    beforeRouteEnter: (to, from, next) => {
      //加载数据
      console.log("进入路由之前")
      next(vm => {
        //进入路由之前执行getData方法
        vm.getData()
      });
    },
    beforeRouteLeave: (to, from, next) => {
      console.log("离开路由之前")
      next();
    },
    //axios
    methods: {
      getData: function () {
        this.axios({
          method: 'get',
          url: 'http://localhost:8080/static/mock/data.json'
        }).then(function (response) {
          console.log(response)
        })
      }
    }
  }

5. Routing hook and axios combination diagram

Guess you like

Origin blog.csdn.net/qq_21137441/article/details/123768364