vue07登陆注册--跨域请求问题+ base64编码+axios使用+面试题【v-bind和v-modul和{{}}的区别】

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
.cn 域名,1个 12个月
云解析 DNS,旗舰版 1个月
简介: vue07登陆注册--跨域请求问题+ base64编码+axios使用+面试题【v-bind和v-modul和{{}}的区别】

1. 搭建项目


工程方式搭建项目,请将测试需要用的后台web服务程序事先准备好。

1.1 使用vue-cli创建项目

命令行,到自己的vue工程存放的目录,运行一下命令,前提是vue-cli先安装好。

vue init webpack vuepro

1.2 通过npm安装element-ui

cd pro01                                   #进入新建项目的根目录
npm install element-ui -S                  #安装element-ui模块

重要的事情说三遍:在指定位置!!!在指定位置!!!在指定位置!!!~~~添加三行代码


1.3 导入组件

打开 src目录下的main.js,该文件是项目的入口文件,所以在这里导入,其他组件均可使用,不用再导入。

import Vue from 'vue'
//新添加1
import ElementUI from 'element-ui' 
//新增加2,避免后期打包样式不同,要放在import App from './App';之前
import 'element-ui/lib/theme-chalk/index.css'
import App from './App'
import router from './router'
Vue.use(ElementUI)   //新添加3
Vue.config.productionTip = false

1.4 测试

修改HelloWorld.vue添加elementUI组件查看效果


2 创建登录页面


2.1 创建登录组件

1) 新建views目录,在目录上右击,选择新建vue(简单模块)创建Login

<template>
</template>
<script>
</script>
<style>
</style>

2)在element-ui组件,在form组件中找到与登录页面类似的组件,拷贝代码到刚新建的Login组件中,修改为自己需要的登录页面,页面包含:账户,密码, 提交按钮

<template>
    <div>
        <el-form >
            <el-form-item label="账户" >
              <el-input type="password" v-model="userName" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="密码" >
              <el-input type="password" v-model="passWord" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
            </el-form-item>
         </el-form>
    </div>
</template>
<script>
  export default {
    name: 'Login',
    data: function() {
      return {
         userName: null,
         passWord: null,
      }
    },
    methods: {
      submitForm: function() {
          console.log("fdfdd");
      }
    }
  }
</script>
<style>
</style>

2.2 引入css(css.txt)

按照css.txt中的说明进行引入,用于控制样式,加入样式

App.vue
<style> 
html,
body {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    padding: 0px;
    margin: 0px;
}
#app {
    font-family: "Avenir", Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    color: #2c3e50;
    widows: 100%;
    height: 100%;
}
</style>
login.vue
<style scoped>
  .login-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding-top: 10%;
  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjEzNjFweCIgaGVpZ2h0PSI2MDlweCIgdmlld0JveD0iMCAwIDEzNjEgNjA5IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0Ni4yICg0NDQ5NikgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+R3JvdXAgMjE8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iQW50LURlc2lnbi1Qcm8tMy4wIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i6LSm5oi35a+G56CB55m75b2VLeagoemqjCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTc5LjAwMDAwMCwgLTgyLjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0iR3JvdXAtMjEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDc3LjAwMDAwMCwgNzMuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iR3JvdXAtMTgiIG9wYWNpdHk9IjAuOCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzQuOTAxNDE2LCA1NjkuNjk5MTU4KSByb3RhdGUoLTcuMDAwMDAwKSB0cmFuc2xhdGUoLTc0LjkwMTQxNiwgLTU2OS42OTkxNTgpIHRyYW5zbGF0ZSg0LjkwMTQxNiwgNTI1LjE5OTE1OCkiPgogICAgICAgICAgICAgICAgICAgIDxlbGxpcHNlIGlkPSJPdmFsLTExIiBmaWxsPSIjQ0ZEQUU2IiBvcGFjaXR5PSIwLjI1IiBjeD0iNjMuNTc0ODc5MiIgY3k9IjMyLjQ2ODM2NyIgcng9IjIxLjc4MzA0NzkiIHJ5PSIyMS43NjYwMDgiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC0zIiBmaWxsPSIjQ0ZEQUU2IiBvcGFjaXR5PSIwLjU5OTk5OTk2NCIgY3g9IjUuOTg3NDY0NzkiIGN5PSIxMy44NjY4NjAxIiByeD0iNS4yMTczOTEzIiByeT0iNS4yMTMzMDk5NyI+PC9lbGxpcHNlPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0zOC4xMzU0NTE0LDg4LjM1MjAyMTUgQzQzLjg5ODQyMjcsODguMzUyMDIxNSA0OC41NzAyMzQsODMuNjgzODY0NyA0OC41NzAyMzQsNzcuOTI1NDAxNSBDNDguNTcwMjM0LDcyLjE2NjkzODMgNDMuODk4NDIyNyw2Ny40OTg3ODE2IDM4LjEzNTQ1MTQsNjcuNDk4NzgxNiBDMzIuMzcyNDgwMSw2Ny40OTg3ODE2IDI3LjcwMDY2ODgsNzIuMTY2OTM4MyAyNy43MDA2Njg4LDc3LjkyNTQwMTUgQzI3LjcwMDY2ODgsODMuNjgzODY0NyAzMi4zNzI0ODAxLDg4LjM1MjAyMTUgMzguMTM1NDUxNCw4OC4zNTIwMjE1IFoiIGlkPSJPdmFsLTMtQ29weSIgZmlsbD0iI0NGREFFNiIgb3BhY2l0eT0iMC40NSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02NC4yNzc1NTgyLDMzLjE3MDQ5NjMgTDExOS4xODU4MzYsMTYuNTY1NDkxNSIgaWQ9IlBhdGgtMTIiIHN0cm9rZT0iI0NGREFFNiIgc3Ryb2tlLXdpZHRoPSIxLjczOTEzMDQzIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNDIuMTQzMTcwOCwyNi41MDAyNjgxIEw3LjcxMTkwMTYyLDE0LjU2NDA3MDIiIGlkPSJQYXRoLTE2IiBzdHJva2U9IiNFMEI0QjciIHN0cm9rZS13aWR0aD0iMC43MDI2Nzg5NjQiIG9wYWNpdHk9IjAuNyIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtZGFzaGFycmF5PSIxLjQwNTM1Nzg5OTg3MzE1MywyLjEwODAzNjk1MzQ2OTk4MSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02My45MjYyMTg3LDMzLjUyMTU2MSBMNDMuNjcyMTMyNiw2OS4zMjUwOTUxIiBpZD0iUGF0aC0xNSIgc3Ryb2tlPSIjQkFDQUQ5IiBzdHJva2Utd2lkdGg9IjAuNzAyNjc4OTY0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1kYXNoYXJyYXk9IjEuNDA1MzU3ODk5ODczMTUzLDIuMTA4MDM2OTUzNDY5OTgxIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTE3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjYuODUwOTIyLCAxMy41NDM2NTQpIHJvdGF0ZSgzMC4wMDAwMDApIHRyYW5zbGF0ZSgtMTI2Ljg1MDkyMiwgLTEzLjU0MzY1NCkgdHJhbnNsYXRlKDExNy4yODU3MDUsIDQuMzgxODg5KSIgZmlsbD0iI0NGREFFNiI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxlbGxpcHNlIGlkPSJPdmFsLTQiIG9wYWNpdHk9IjAuNDUiIGN4PSI5LjEzNDgyNjUzIiBjeT0iOS4xMjc2ODA3NiIgcng9IjkuMTM0ODI2NTMiIHJ5PSI5LjEyNzY4MDc2Ij48L2VsbGlwc2U+CiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xOC4yNjk2NTMxLDE4LjI1NTM2MTUgQzE4LjI2OTY1MzEsMTMuMjE0MjgyNiAxNC4xNzk4NTE5LDkuMTI3NjgwNzYgOS4xMzQ4MjY1Myw5LjEyNzY4MDc2IEM0LjA4OTgwMTE0LDkuMTI3NjgwNzYgMCwxMy4yMTQyODI2IDAsMTguMjU1MzYxNSBMMTguMjY5NjUzMSwxOC4yNTUzNjE1IFoiIGlkPSJPdmFsLTQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDkuMTM0ODI3LCAxMy42OTE1MjEpIHNjYWxlKC0xLCAtMSkgdHJhbnNsYXRlKC05LjEzNDgyNywgLTEzLjY5MTUyMSkgIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMTYuMjk0NzAwLCAxMjMuNzI1NjAwKSByb3RhdGUoLTUuMDAwMDAwKSB0cmFuc2xhdGUoLTIxNi4yOTQ3MDAsIC0xMjMuNzI1NjAwKSB0cmFuc2xhdGUoMTA2LjI5NDcwMCwgMzUuMjI1NjAwKSI+CiAgICAgICAgICAgICAgICAgICAgPGVsbGlwc2UgaWQ9Ik92YWwtMiIgZmlsbD0iI0NGREFFNiIgb3BhY2l0eT0iMC4yNSIgY3g9IjI5LjExNzY0NzEiIGN5PSIyOS4xNDAyNDM5IiByeD0iMjkuMTE3NjQ3MSIgcnk9IjI5LjE0MDI0MzkiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC0yIiBmaWxsPSIjQ0ZEQUU2IiBvcGFjaXR5PSIwLjMiIGN4PSIyOS4xMTc2NDcxIiBjeT0iMjkuMTQwMjQzOSIgcng9IjIxLjU2ODYyNzUiIHJ5PSIyMS41ODUzNjU5Ij48L2VsbGlwc2U+CiAgICAgICAgICAgICAgICAgICAgPGVsbGlwc2UgaWQ9Ik92YWwtMi1Db3B5IiBzdHJva2U9IiNDRkRBRTYiIG9wYWNpdHk9IjAuNCIgY3g9IjE3OS4wMTk2MDgiIGN5PSIxMzguMTQ2MzQxIiByeD0iMjMuNzI1NDkwMiIgcnk9IjIzLjc0MzkwMjQiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC0yIiBmaWxsPSIjQkFDQUQ5IiBvcGFjaXR5PSIwLjUiIGN4PSIyOS4xMTc2NDcxIiBjeT0iMjkuMTQwMjQzOSIgcng9IjEwLjc4NDMxMzciIHJ5PSIxMC43OTI2ODI5Ij48L2VsbGlwc2U+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTI5LjExNzY0NzEsMzkuOTMyOTI2OCBMMjkuMTE3NjQ3MSwxOC4zNDc1NjEgQzIzLjE2MTYzNTEsMTguMzQ3NTYxIDE4LjMzMzMzMzMsMjMuMTc5NjA5NyAxOC4zMzMzMzMzLDI5LjE0MDI0MzkgQzE4LjMzMzMzMzMsMzUuMTAwODc4MSAyMy4xNjE2MzUxLDM5LjkzMjkyNjggMjkuMTE3NjQ3MSwzOS45MzI5MjY4IFoiIGlkPSJPdmFsLTIiIGZpbGw9IiNCQUNBRDkiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0iR3JvdXAtOSIgb3BhY2l0eT0iMC40NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTcyLjAwMDAwMCwgMTMxLjAwMDAwMCkiIGZpbGw9IiNFNkExQTYiPgogICAgICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC0yLUNvcHktMiIgY3g9IjcuMDE5NjA3ODQiIGN5PSI3LjE0NjM0MTQ2IiByeD0iNi40NzA1ODgyNCIgcnk9IjYuNDc1NjA5NzYiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTAuNTQ5MDE5NjA4LDEzLjYyMTk1MTIgQzQuMTIyNjI2ODEsMTMuNjIxOTUxMiA3LjAxOTYwNzg0LDEwLjcyMjcyMiA3LjAxOTYwNzg0LDcuMTQ2MzQxNDYgQzcuMDE5NjA3ODQsMy41Njk5NjA5NSA0LjEyMjYyNjgxLDAuNjcwNzMxNzA3IDAuNTQ5MDE5NjA4LDAuNjcwNzMxNzA3IEwwLjU0OTAxOTYwOCwxMy42MjE5NTEyIFoiIGlkPSJPdmFsLTItQ29weS0yIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjc4NDMxNCwgNy4xNDYzNDEpIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTMuNzg0MzE0LCAtNy4xNDYzNDEpICI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC0xMCIgZmlsbD0iI0NGREFFNiIgY3g9IjIxOC4zODIzNTMiIGN5PSIxMzguNjg1OTc2IiByeD0iMS42MTc2NDcwNiIgcnk9IjEuNjE4OTAyNDQiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC0xMC1Db3B5LTIiIGZpbGw9IiNFMEI0QjciIG9wYWNpdHk9IjAuMzUiIGN4PSIxNzkuNTU4ODI0IiBjeT0iMTc1LjM4MTA5OCIgcng9IjEuNjE3NjQ3MDYiIHJ5PSIxLjYxODkwMjQ0Ij48L2VsbGlwc2U+CiAgICAgICAgICAgICAgICAgICAgPGVsbGlwc2UgaWQ9Ik92YWwtMTAtQ29weSIgZmlsbD0iI0UwQjRCNyIgb3BhY2l0eT0iMC4zNSIgY3g9IjE4MC4wOTgwMzkiIGN5PSIxMDIuNTMwNDg4IiByeD0iMi4xNTY4NjI3NSIgcnk9IjIuMTU4NTM2NTkiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjguOTk4NTM4MSwyOS45NjcxNTk4IEwxNzEuMTUxMDE4LDEzMi44NzYwMjQiIGlkPSJQYXRoLTExIiBzdHJva2U9IiNDRkRBRTYiIG9wYWNpdHk9IjAuOCI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTEwIiBvcGFjaXR5PSIwLjc5OTk5OTk1MiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTA1NC4xMDA2MzUsIDM2LjY1OTMxNykgcm90YXRlKC0xMS4wMDAwMDApIHRyYW5zbGF0ZSgtMTA1NC4xMDA2MzUsIC0zNi42NTkzMTcpIHRyYW5zbGF0ZSgxMDI2LjYwMDYzNSwgNC42NTkzMTcpIj4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbC03IiBzdHJva2U9IiNDRkRBRTYiIHN0cm9rZS13aWR0aD0iMC45NDExNzY0NzEiIGN4PSI0My44MTM1NTkzIiBjeT0iMzIiIHJ4PSIxMS4xODY0NDA3IiByeT0iMTEuMjk0MTE3NiI+PC9lbGxpcHNlPgogICAgICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cC0xMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzQuNTk2Nzc0LCAyMy4xMTExMTEpIiBmaWxsPSIjQkFDQUQ5Ij4KICAgICAgICAgICAgICAgICAgICAgICAgPGVsbGlwc2UgaWQ9Ik92YWwtNyIgb3BhY2l0eT0iMC40NSIgY3g9IjkuMTg1MzQ3MTgiIGN5PSI4Ljg4ODg4ODg5IiByeD0iOC40NzQ1NzYyNyIgcnk9IjguNTU2MTQ5NzMiPjwvZWxsaXBzZT4KICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkuMTg1MzQ3MTgsMTcuNDQ1MDM4NiBDMTMuODY1NzI2NCwxNy40NDUwMzg2IDE3LjY1OTkyMzUsMTMuNjE0MzE5OSAxNy42NTk5MjM1LDguODg4ODg4ODkgQzE3LjY1OTkyMzUsNC4xNjM0NTc4NyAxMy44NjU3MjY0LDAuMzMyNzM5MTU2IDkuMTg1MzQ3MTgsMC4zMzI3MzkxNTYgTDkuMTg1MzQ3MTgsMTcuNDQ1MDM4NiBaIiBpZD0iT3ZhbC03Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0zNC42NTk3Mzg1LDI0LjgwOTY5NCBMNS43MTY2NjA4NCw0Ljc2ODc4OTQ1IiBpZD0iUGF0aC0yIiBzdHJva2U9IiNDRkRBRTYiIHN0cm9rZS13aWR0aD0iMC45NDExNzY0NzEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8ZWxsaXBzZSBpZD0iT3ZhbCIgc3Ryb2tlPSIjQ0ZEQUU2IiBzdHJva2Utd2lkdGg9IjAuOTQxMTc2NDcxIiBjeD0iMy4yNjI3MTE4NiIgY3k9IjMuMjk0MTE3NjUiIHJ4PSIzLjI2MjcxMTg2IiByeT0iMy4yOTQxMTc2NSI+PC9lbGxpcHNlPgogICAgICAgICAgICAgICAgICAgIDxlbGxpcHNlIGlkPSJPdmFsLUNvcHkiIGZpbGw9IiNGN0UxQUQiIGN4PSIyLjc5NjYxMDE3IiBjeT0iNjEuMTc2NDcwNiIgcng9IjIuNzk2NjEwMTciIHJ5PSIyLjgyMzUyOTQxIj48L2VsbGlwc2U+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTM0LjYzMTI0NDMsMzkuMjkyMjcxMiBMNS4wNjM2NjY2Myw1OS43ODUwODIiIGlkPSJQYXRoLTEwIiBzdHJva2U9IiNDRkRBRTYiIHN0cm9rZS13aWR0aD0iMC45NDExNzY0NzEiPjwvcGF0aD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cC0xOSIgb3BhY2l0eT0iMC4zMyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTI4Mi41MzcyMTksIDQ0Ni41MDI4NjcpIHJvdGF0ZSgtMTAuMDAwMDAwKSB0cmFuc2xhdGUoLTEyODIuNTM3MjE5LCAtNDQ2LjUwMjg2NykgdHJhbnNsYXRlKDExNDIuNTM3MjE5LCAzMjcuNTAyODY3KSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTE3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNDEuMzMzNTM5LCAxMDQuNTAyNzQyKSByb3RhdGUoMjc1LjAwMDAwMCkgdHJhbnNsYXRlKC0xNDEuMzMzNTM5LCAtMTA0LjUwMjc0MikgdHJhbnNsYXRlKDEyOS4zMzM1MzksIDkyLjUwMjc0MikiIGZpbGw9IiNCQUNBRDkiPgogICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJPdmFsLTQiIG9wYWNpdHk9IjAuNDUiIGN4PSIxMS42NjY2NjY3IiBjeT0iMTEuNjY2NjY2NyIgcj0iMTEuNjY2NjY2NyI+PC9jaXJjbGU+CiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMy4zMzMzMzMzLDIzLjMzMzMzMzMgQzIzLjMzMzMzMzMsMTYuODkwMDExMyAxOC4xMDk5ODg3LDExLjY2NjY2NjcgMTEuNjY2NjY2NywxMS42NjY2NjY3IEM1LjIyMzM0NDU5LDExLjY2NjY2NjcgMCwxNi44OTAwMTEzIDAsMjMuMzMzMzMzMyBMMjMuMzMzMzMzMywyMy4zMzMzMzMzIFoiIGlkPSJPdmFsLTQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExLjY2NjY2NywgMTcuNTAwMDAwKSBzY2FsZSgtMSwgLTEpIHRyYW5zbGF0ZSgtMTEuNjY2NjY3LCAtMTcuNTAwMDAwKSAiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0iT3ZhbC01LUNvcHktNiIgZmlsbD0iI0NGREFFNiIgY3g9IjIwMS44MzMzMzMiIGN5PSI4Ny41IiByPSI1LjgzMzMzMzMzIj48L2NpcmNsZT4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQzLjUsODguODEyNjY4NSBMMTU1LjA3MDUwMSwxNy42MDM4NTQ0IiBpZD0iUGF0aC0xNyIgc3Ryb2tlPSIjQkFDQUQ5IiBzdHJva2Utd2lkdGg9IjEuMTY2NjY2NjciPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTcuNSwzNy4zMzMzMzMzIEwxMjcuNDY2MjUyLDk3LjY0NDk3MzUiIGlkPSJQYXRoLTE4IiBzdHJva2U9IiNCQUNBRDkiIHN0cm9rZS13aWR0aD0iMS4xNjY2NjY2NyI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwb2x5bGluZSBpZD0iUGF0aC0xOSIgc3Ryb2tlPSIjQ0ZEQUU2IiBzdHJva2Utd2lkdGg9IjEuMTY2NjY2NjciIHBvaW50cz0iMTQzLjkwMjU5NyAxMjAuMzAyMjgxIDE3NC45MzU0NTUgMjMxLjU3MTM0MiAzOC41IDE0Ny41MTA4NDcgMTI2LjM2Njk0MSAxMTAuODMzMzMzIj48L3BvbHlsaW5lPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNTkuODMzMzMzLDk5Ljc0NTM4NDIgTDE5NS40MTY2NjcsODkuMjUiIGlkPSJQYXRoLTIwIiBzdHJva2U9IiNFMEI0QjciIHN0cm9rZS13aWR0aD0iMS4xNjY2NjY2NyIgb3BhY2l0eT0iMC42Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIwNS4zMzMzMzMsODIuMTM3MjEwNSBMMjM4LjcxOTQwNiwzNi4xNjY2NjY3IiBpZD0iUGF0aC0yNCIgc3Ryb2tlPSIjQkFDQUQ5IiBzdHJva2Utd2lkdGg9IjEuMTY2NjY2NjciPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjY2LjcyMzQyNCwxMzIuMjMxOTg4IEwyMDcuMDgzMzMzLDkwLjQxNjY2NjciIGlkPSJQYXRoLTI1IiBzdHJva2U9IiNDRkRBRTYiIHN0cm9rZS13aWR0aD0iMS4xNjY2NjY2NyI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9Ik92YWwtNSIgZmlsbD0iI0MxRDFFMCIgY3g9IjE1Ni45MTY2NjciIGN5PSI4Ljc1IiByPSI4Ljc1Ij48L2NpcmNsZT4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJPdmFsLTUtQ29weS0zIiBmaWxsPSIjQzFEMUUwIiBjeD0iMzkuMDgzMzMzMyIgY3k9IjE0OC43NSIgcj0iNS4yNSI+PC9jaXJjbGU+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0iT3ZhbC01LUNvcHktMiIgZmlsbC1vcGFjaXR5PSIwLjYiIGZpbGw9IiNEMURFRUQiIGN4PSI4Ljc1IiBjeT0iMzMuMjUiIHI9IjguNzUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9Ik92YWwtNS1Db3B5LTQiIGZpbGwtb3BhY2l0eT0iMC42IiBmaWxsPSIjRDFERUVEIiBjeD0iMjQzLjgzMzMzMyIgY3k9IjMwLjMzMzMzMzMiIHI9IjUuODMzMzMzMzMiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9Ik92YWwtNS1Db3B5LTUiIGZpbGw9IiNFMEI0QjciIGN4PSIxNzUuNTgzMzMzIiBjeT0iMjMyLjc1IiByPSI1LjI1Ij48L2NpcmNsZT4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+);
  /* background-color: #112346; */
  background-repeat: no-repeat;
  background-position: center right;
  background-size: 100%;
  }
  .login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
  }
  .title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
  }
</style>


base64编码:

基于64个可打印字符来表示二进制数据,用于传输8Bit字节代码,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。


注1:<style scoped>

       在vue组件中,在style标签上添加scoped属性,以表示它的样式作用于当下的模块,很好的实现了样式私有化的目的


注2:auto-complete="off"

       autocomplete 属性是 HTML5 中的新属性,off-----禁用自动完成

2.3 配置路由

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//首先导入组件
import Login from '@/views/Login'
Vue.use(Router)
export default new Router({
  routes: [
    {
      //配置路由,根路径访问Login组件
      path: '/',
      name: 'Login',
      component: Login
    }
  ]
})

2.4 在Login组件中将提交按键调整为100%宽度

<el-button type="primary" @click="submitForm('ruleForm')" style="width:100%">提交</el-button>

2.5 运行效果

在项目目录,运行一下命令,启动服务:

npm run dev
//界面效果:


3. 后台交互


3.1 引入axios

axios是vue2提倡使用的轻量版的ajax。它是基于promise的HTTP库。它会从浏览器中创建XMLHttpRequests,与Vue配合使用非常好。

vue.js有著名的全家桶系列:vue-router,vuex, vue-resource,再加上构建工具vue-cli,就是一个完整的vue项目的核心构成。其中vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应,但在vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios

3.2 axios/qs/vue-axios安装与使用

注:

qs.js它是一个url参数转化的js库。用法就两个:

var obj = qs.parse('a=b&c=d');  //将URL解析成对象的形式:{a:'b',c:'d'}
var str = qs.stringify(obj);    //将对象 序列化成URL的形式,以&进行拼接:a=b&c=d'

vue-axios是在axios基础上扩展的插件,在Vue.prototype原型上扩展了$http等属性,可以更加方便的使用axios


3.2.1 安装axios

npm install axios -S

2)在Login组件中导入axios

import axios from 'axios'
  export default {
  ......

3.2.2 发送get请求:

在提交按钮的监听函数中加入发送get请求的代码:

//请求url,需要保证服务可用
let url = 'http://localhost:8080/webserver/userMsg/userAction!login.action';
//注意数据是保存到json对象的params属性
axios.get(url, {
  params: {
    userNo: this.userNo,
    userPwd: this.userPwd
  }
}).then(function(response) {
  console.log(response);
}).catch(function(error) {
  console.log(error);
});

请注意下面图上的错误信息,请求发生了跨域错误问题:


跨域请求问题:

因为我们采用的是前后端分离的方式进行开发,前端和后端分别泡在不同的服务器上,基于安全性考虑,浏览器有同源策略,所以出现了跨域问题。

同源策略[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。 同源策略是浏览器安全的基石。


4)跨域问题的处理

在filter中处理跨域问题,关键代码

// Access-Control-Allow-Origin就是我们需要设置的域名
// Access-Control-Allow-Headers跨域允许包含的头。
// Access-Control-Allow-Methods是允许的请求方式
httpResponse.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名
httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
filterChain.doFilter(servletRequest, servletResponse);

将下代码配置到web.xml中,对所以请求进行拦截处理,可解决跨域问题。注意:请配置在struts中央控制器之前。下面有详细的注意事项!!!

package com.zking.test.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
/**
 * 配置tomcat允许跨域访问
 * 
 * @author Administrator
 *
 */
public class CorsFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
    throws IOException, ServletException {
  HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
  // Access-Control-Allow-Origin就是我们需要设置的域名
  // Access-Control-Allow-Headers跨域允许包含的头。
  // Access-Control-Allow-Methods是允许的请求方式
  httpResponse.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名
  httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
  filterChain.doFilter(servletRequest, servletResponse);
  }
  @Override
  public void destroy() {
  }
}

注1:axios跨域问题

          会一直报错:“http://127.0.0.1:8848' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header”因为使用了前后端分离开发,跨域访问了,解决方案:需要配置tomcat允许跨域访问,tomcat跨域配置方法很多,但最简单的方式是自己写一个过滤器CorsFilter实现,添加一个响应头Access-Control-Allow-Origin即可

          httpResponse.addHeader("Access-Control-Allow-Origin", "*");//*表示任何域名

          httpResponse.addHeader("Access-Control-Allow-Origin", "http://localhost:80");


          Access-Control-Allow-Origin:*                           #则允许所有域名的脚本访问该资源。

          Access-Control-Allow-Origin:https://www.fujieace.com    #允许特定的域名访问


注2:axios.get提交没有问题,axios.post提交后台接收不到数据


        因为POST提交的参数的格式是Request Payload,这样后台取不到数据的。


        解决方案:使用qs.js库,将{a:'b',c:'d'}转换成'a=b&c=d'


注3:为简化axios使用,还可以使用axios全局配置及拦截器

          axios.defaults.baseURL = 'https://api.example.com';

          axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';


        详细代码如下

/**
 * vue项目对axios的全局配置
 */
import axios from 'axios'
import qs from 'qs'
//引入action模块,并添加至axios的类属性urls上
import action from '@/api/action'
axios.urls = action
// axios默认配置
axios.defaults.timeout = 10000; // 超时时间
// axios.defaults.baseURL = 'http://localhost:8080/j2ee15'; // 默认地址
axios.defaults.baseURL = action.SERVER;
//整理数据
// 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据
axios.defaults.transformRequest = function(data) {
  data = qs.stringify(data);
  return data;
};
// 请求拦截器
axios.interceptors.request.use(function(config) {
  return config;
}, function(error) {
  return Promise.reject(error);
});
// 响应拦截器
axios.interceptors.response.use(function(response) {
  return response;
}, function(error) {
  return Promise.reject(error);
});
// // 路由请求拦截
// // http request 拦截器
// axios.interceptors.request.use(
//  config => {
//    //config.data = JSON.stringify(config.data);  
//    //config.headers['Content-Type'] = 'application/json;charset=UTF-8';
//    //config.headers['Token'] = 'abcxyz';
//    //判断是否存在ticket,如果存在的话,则每个http header都加上ticket
//    // if (cookie.get("token")) {
//    //  //用户每次操作,都将cookie设置成2小时
//    //  cookie.set("token", cookie.get("token"), 1 / 12)
//    //  cookie.set("name", cookie.get("name"), 1 / 12)
//    //  config.headers.token = cookie.get("token");
//    //  config.headers.name = cookie.get("name");
//    // }
//    return config;
//  },
//  error => {
//    return Promise.reject(error.response);
//  });
// // 路由响应拦截
// // http response 拦截器
// axios.interceptors.response.use(
//  response => {
//    if (response.data.resultCode == "404") {
//    console.log("response.data.resultCode是404")
//    // 返回 错误代码-1 清除ticket信息并跳转到登录页面
//    //      cookie.del("ticket")
//    //      window.location.href='http://login.com'
//    return
//    } else {
//    return response;
//    }
//  },
//  error => {
//    return Promise.reject(error.response) // 返回接口返回的错误信息
//  });
export default axios;

注4:为方便开发,建议对请求地址进行封装,详细代码如下


/**
 * 对后台请求的地址的封装,URL格式如下:
 * 模块名_实体名_操作
 */
export default {
  'SERVER': 'http://localhost:8080/j2ee15', //服务器
  'SYSTEM_USER_DOLOGIN': '/userAction.action', //登陆
  'SYSTEM_USER_DOREG': '/userAction.action', //注册
  'getFullPath': k => { //获得请求的完整地址,用于mockjs测试时使用
  return this.SERVER + this[k];
  }
}

注5:^_^~~~~为进一步简化开发,将action.js的URL地址封装到axios.urls属性上        


3.2.3 发送post请求:

//注意数据是直接保存到json对象
axios.post(url, {
    userNo: 'admin',
    userPwd: '123'
}).then(function(response) {
    console.log(response);
}).catch(function(error) {
    console.log(error);
});

输入的测试账号和密码均正确,使用get发送请求获取的响应为“密码正确”,但post方式发送的请求获取的响应为“密码不正确”!


原因分析:通过观察控制台可以发现,post发送请求时,请求参数是以json格式通过request payload进行传送的,的struts的并没有处理这种方式传递的参数(起码是我们使用的struts版本),所以传递到服务器的参数并没有得到有效的解析。


问题处理:

第一种方式: 在服务端编码实现request payload参数解析。在BaseAction中加入一个方法,该方法从request payload中获取json数据,并转化为指定的类。


public Object getRequestBody(Class clazz) {   
        BufferedReader br;
        HttpServletRequest request = ServletActionContext.getRequest();
        try {
            br = request.getReader();
            String str, aStr = "";
            while((str = br.readLine()) != null){
                aStr += str;
            }
            System.out.println(aStr);
            Object obj = JSONObject.parseObject(aStr, clazz);
            return obj;
        } catch (IOException e) {
           throw new RuntimeException("获取请求参数异常: " + e);
        }
    }


获取参数时调用该方法获取

User user = (User)this.getRequestBody(User.class);

第二种方式:使用qs.js库,将{a:'b',c:'d'}转换成'a=b&c=d'。

1) 安装qs和vue-axios

npm install qs -S
npm install vue-axios -S

安装成功后会在package.json中“dependencies”中会看到安装的新库。

在提交请求时使用qs对json对象进行转换


//qs.js它是一个url参数转化的js库。用法就两个:
var obj = qs.parse('a=b&c=d');  //将URL解析成对象的形式:{a:'b',c:'d'}
var str = qs.stringify(obj);    //将对象 序列化成URL的形式,以&进行拼接:a=b&c=d'
//注意数据是直接保存到json对象
let params = {
  userNo: 'admin',
  userPwd: '123'
};
//参数格式转换
let paramStr = qs.stringify(params);
console.log(paramStr);
//提交时使用转换之后的参数
axios.post(url, paramStr).then(function(response) {
  console.log(response);
}).catch(function(error) {
  console.log(error);
});

观察控制台中的输出,已经将json格式转化为&连接的格式。查看返回结果是否是预期值。


3.2.4 简化axios使用

vue-axios是在axios基础上扩展的插件,在Vue.prototype原型上扩展了$http等属性,可以更加方便的使用axios。为简化axios使用,还可以使用axios全局配置及拦截器


1) 安装vue-axios

npm install axios -S
npm install qs -S        
npm install vue-axios -S

2) 把代码翻到src根路径下


现在可以将在Login组件中的导入axios和qs语句删除, action.js和http.js的配置详见代码中的注释。


3)将action中的配置修改为自己的后台服务配置

export default {
  'SERVER': 'http://localhost:8080/webserver', //服务器
  'SYSTEM_USER_DOLOGIN': '/userMsg/userAction!login.action', //登陆
  'SYSTEM_USER_DOREG': '/userAction.action', //注册
  //获取完整的请求地址
  'getFullPath': k => { //获得请求的完整地址,用于mockjs测试时使用
  return this.SERVER + this[k];
  }
}

4)配置main.js

#import axios from 'axios'
#import qs from 'qs'
import axios from '@/api/http'             #vue项目对axios的全局配置      
import VueAxios from 'vue-axios' 
Vue.use(VueAxios,axios)

5) 在提交时不需要手动处理转换,全局配置进行转换。

//修改url的获取方式,url已经配置在了action.js中,这里只要指定action路径
//服务地址和服务上下文已经在http.js中设置了axios.defaults.baseURL,
//axios会根据配置自动获取。
let url = this.axios.urls.SYSTEM_USER_DOLOGIN;
this.axios.post(url, params).then(resp => {
  console.log(resp);
}).catch(resp => {});

6)发生post请求,测试


附录一:ES6的语法箭头函数,本文用到了,下篇给大家出一篇ES6的文章,它的出现主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念。

doSomething(function(a){...});
doSomething((a)=>{});


附录二:面试题 【v-bind和v-modul和{{}}的区别】

v-bind:绑定属性,对标签中的属性进行绑定,简写是冒号。

v-modul:数据双向绑定,vue中mvvm核心实现

{{}}:插值,对标前提里面的值进行插入

相关文章
|
2月前
|
资源调度 JavaScript
|
2月前
|
缓存 JavaScript 搜索推荐
|
3月前
|
JavaScript
在 Vue 3 组件通信方式中,Provide / Inject 与 Vuex 的区别是什么?
在 Vue 3 组件通信方式中,Provide / Inject 与 Vuex 的区别是什么?
173 65
|
1月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
2月前
|
JavaScript 前端开发 开发者
Vue v-for 进阶指南:in 与 of 的区别及应用场景 | 笔记
Vue.js 中的 v-for 是强大的遍历指令,但其中的 in 和 of 关键字往往被开发者忽视。尽管它们的用法相似,但适用的场景和数据结构却各有不同。本文将详细探讨 v-for 中 in 和 of 的区别、适用场景以及在实际开发中的最佳使用时机。通过理解它们的差异,你将能够编写更加高效、简洁的 Vue.js 代码,灵活应对各种数据结构的遍历需求。
94 6
|
2月前
|
缓存 JavaScript
Vue 中 computed 与 method 的区别
【10月更文挑战第15天】computed 和 method 是 Vue 中两个重要的选项,它们在功能和特点上存在着明显的区别。理解并合理运用它们的区别,可以帮助我们构建更高效、更具可维护性的 Vue 应用。在实际开发中,要根据具体情况灵活选择使用,以满足不同的需求。
28 2
|
2月前
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
128 4
|
2月前
|
XML 前端开发 JavaScript
详解Ajax与axios的区别
详解Ajax与axios的区别
|
2月前
|
编译器
经典面试题:变量的声明和定义有什么区别
在编程领域,变量的“声明”与“定义”是经典面试题之一。声明告诉编译器一个变量的存在,但不分配内存,通常包含变量类型和名称;而定义则为变量分配内存空间,一个变量必须至少被定义一次。简而言之,声明是告知变量形式,定义则是实际创建变量并准备使用。