零基础学Vue--day07项目

1. 电商业务概述

  • 客户端服务:PC端,小程序,移动web,移动app;
    管理员端服务:PC后台管理端;

  • PC后台管理端功能:管理用户账号(登录,退出,用户管理,权限管理),商品管理(商品分类,分类参数,商品信息,订单),数据统计;
    采用前后端分离的开发模式;前端项目是基于 Vue的SPA(单页应用程序)项目

  • 前端技术栈:Vue, Vue-Router, Element-UI, Axios, Echarts
    后端技术栈:Node.js, Express, Jwt(模拟session), Mysql, Sequelize(操作数据库的框架)

2. 前端项目初始化

  • 安装Vue脚手架 (只需全局安装一次即可)
  • 通过Vue脚手架创建项目:vue ui --> 创建 (安装路由、使用配置文件)
  • 配置Element-UI组件库:
    插件 -->添加插件 --> vue-cli-plugin-element --> import on demand (按需导入)
  • 配置Axios:
    依赖 --> 安装依赖 -->axios(运行依赖)

3. 初始化 git 远程仓库:

  • 设置SSH公钥:
    设置 -->安全设置 -->SSH公钥 -->怎样生成公钥;
    仓库管理 -->公钥管理 -->生成/添加SSH公钥;
  • 在本地创建公钥:
    终端运行 ssh-keygen -t rsa -C “[email protected]” //码云账号邮箱;–> 三次回车;
    找到公钥地址:Your public key has been saved in /c/Users/My/.ssh/id_rsa.pub
    复制 id_rsa.pub文件中的代码 -->码云,确定 -->登陆密码;
  • 测试公钥能不能用:
    终端运行 ssh -T [email protected] --> yes(首次测试需要,添加到SSH可信列表)
    再次测试 ssh -T [email protected] --> hi xxx … (公钥添加成功)
  • 将本地项目,托管到 码云中
    ‘+’ -->新建仓库 -->名称,一定要去的下面方框里的’√’ -->创建 -->复制’git全局设置’里的代码;
    终端运行: git全局设置里的代码(全局配置用户名和邮箱)
    项目目录 -->终端运行 -->上传到本地仓库 -->上传到码云远程仓库 (执行"已有仓库"命令)
    git remote add origin https://gitee.com/tcdiju/vue-shop.git
    git push -u origin master
    –>码云账号密码;

4. 导入数据库

MySQL管理器 -->MySQL导入导出 -->MySQL默认密码:root -->要还原的文件:mydb.sql -->还原到数据库名:与数据名称保持一致(mydb) -->导入

5. 配置后台接口服务器

打开后台项目 vue_api_server文件夹;
安装项目依赖包(node_modules文件夹): npm install;
启动服务器:node ./app.js;
使用 postman 测试登录接口;

6. 实现登录功能

1) 登录 — token原理分析

  • 登录逻辑:
    在登录页面,输入用户名和密码;
    调用后台接口,进行验证;
    通过验证后,根据后台的响应状态,跳转到项目主页;
  • http 是无状态的,登录成功后,需要记录用户登录的状态;
    通过 cookie 在客户端记录状态
    通过 session 在服务器端记录状态
    通过 token 方式维持状态:
    如果服务器和客户端同源,使用 cookie 或 session 来保持登录状态;如果跨域,用token 维持登录状态;
    零基础学Vue--day07项目_第1张图片
    2) 创建 login 分支
    git checkout -b login 创建并切换到,login分支上;//开发完成后,再合并到 master主分支上;
    git branch 查看所有分支,确定是否在 login分支上;
    梳理项目结构
vue ui 打开ui界面,运行app 查看当前项目效果;
现在是一个默认页面,需要进行更改,打开src --> main.js(项目入口文件)
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import './plugins/element.js'

    Vue.config.productionTip = false

    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app')
再打开App.vue(根组件),将根组件的内容,进行删除,留下根节点;
再打开router.js(路由),将routes数组中的路由规则清除,
然后将views中的组件、及 helloword 组件删除;

3) 创建 login登录组件

1.创建login组件;
2.router.js -> 导入login组件,并设置路由规则;
    import Login from '../components/login'
    const router = new Router({
      routes: [
        { path: '/', redirect: '/login' },
        { path: '/login', component: Login }
      ]
    })
3.APP.vue 根组件: 
    添加路由占位符<router-view> (通过路由,匹配到的组件,都会被渲染到这里)

style样式中,添加背景色'2b4b6b',此时会报错 “缺少less-loader”;
依赖 -->安装依赖 -->开发依赖 less-loader less -->重新启动项目,生效;

背景色没有占满屏幕 -->assets文件夹 -->css文件夹,创建全局样式 global.css
main.js入口文件中引入: import "./assets/css/global.css"

绘制登录页面
零基础学Vue--day07项目_第2张图片

/*  Login.vue 中的根元素,设置撑满全屏(height:100%)	
	盒子居中:(450*300px)
     	position: absolute;
  		left:50%;
  		top:50%;
  		transform: translate(-50%,-50%); x,y轴 移动盒子自身的50%
  	头像:(130*130px)
  	阴影:box-shadow: 0 0 10px #ddd;
	div 和 图片同时圆角:border-radius: 50%;
	图片和边框的间隙,内padding */

登录页面布局:
  复制 element-ui组件 -->element.js 中按需导入并注册;
                        import { Input } from 'element-ui'
                        Vue.use(Input) //注册为全局组件
  button按钮 右对齐:
     display:flex; //父元素开启flex
     ustify-content: flex-end; //右对齐
  表单移动到底部:
	 position:absolute; 定位到底部
     bottom:0;
     width: 100%;
     padding: 0 20px; 
	 /*左侧距离20px,右侧直接超出了表单区域,相当于input框整个右移了20px
	   因为默认from表单box-sizing:content*/
     box-sizing:border-box; //解决input输入框,超出表单区域

引入第三方字体图标 (阿里图标库)

1.element-ui 以prefix-icon="属性的方式",添加字体图标: 
    //用class会出现,字体图标,在input框外的情况;
	<el-input prefix-icon="iconfont icon-3702mima">     
2.引入阿里字体图标库:
  把fonts字体图标文件夹,放到assets文件夹中
  入口文件 main.js中导入: import './assets/fonts/iconfont.css' 
  添加类名: <el-input prefix-icon="iconfont icon-user"> 
  //prefix-icon="iconfont icon-xxx" iconfont基础类,每个都加;.icon-xxx 不加'.'

7. 表单数据绑定 及验证

//form表单 -->:model表单的数据绑定,loginform 数据对象;rules表单的验证规则;
<el-form ref="loginref" :model ='loginform' :rules="loginrules">
  <el-form-item prop='username'>
    <el-input v-model='loginform.username' prefix-icon="iconfont icon-user">
  </el-form-item>
    <el-input v-model='loginform.password' type='password'>
</el-form>

//prop属性='具体的验证规则名字';和表单的 item项绑定,加给父元素,不是加给 input框
-------------------------------- data(){ return {}} -----------------------------------
loginform: {
   username: '',
   password: ''
},
loginrules: {
    username: [ //数组中的每一个对象,都是验证规则;true 必填项;错误消息;失去焦点触发;
      { required: true, message: '请输入登录名称', trigger: 'blur' },
      { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
    ],
    password: [
      { required: true, message: '请输入密码', trigger: 'blur' },
      { min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
    ]
}
//验证规则中的登录名username[]、密码password[],必须和数据中名字一致;否则,验证长度规则,不生效;

8. 表单重置

零基础学Vue--day07项目_第3张图片
获得表单的实例对象,调用resetField()函数,重置整个表单,为初始值;
用ref引用,获得表单的实例对象;loginref 就是表单的实例对象;

form 表单 -->ref="loginref"(名字自定义);
methods: {
  resetform () {
     this.$refs.loginref.resetFields()
  }
}
//Vue 直接操作 DOM: 在DOM元素上,通过ref属性标注;(属性名称自定义)
<div ref="info">hello</div>
 
 //通过Vue实例的 $refs获取,标记 ref属性的元素;
 let info = this.$refs.info.innerHTML
 console.log(info) // hello

9. 登录前的预验证

/*点击"登录"按钮,发起请求之前,先对表单的数据,进行预验证;
 *拿到表单的实例对象,调用实例对象的 validate()函数;validate 接收一个回调函数,对表单进行校验
 *resetFields() validate() element-ui 组件的方法*/

// 发送请求前,找到 main.js 入口文件,对axios进行全局配置:
    import axios from 'axios' //先导入axios包;用于发送 ajax请求;
    axios.defaults.baseURL='接口文档请求基准地址' //设置请求根路径;
    Vue.prototype.$http = axios 
    /*把这个包,挂载到vue的,原型对象上;这样每一个vue组件,
      都可以通过this,访问到原型上的 $http,从而发起 ajax请求
     *js必须挂在原型上 prototype.$http; html、css挂在 Vue.use()上
//点击登录时,先调用 validate方法,验证表单内容是否有错误;valid 表单验证的结果,布尔值 
//先启动 mysql 数据库;启动接口服务器 node ./app.js
login() { 
  this.$refs.loginref.validate(async valid=>{
    if(!valid) return; //return结束,不发送请求;
    //const result = this.$http.post("login",this.loginform) 
    //this访问原型上的$http成员,发起 ajax请求;post(请求地址,this.loginform 请求参数)
    //result返回结果是promise,所以用async/await;
    //const result = await this.$http.post("login",this.loginform)
    //async 加在最近的一个函数上;result对象,包含了6个属性,都是axios封装的,只用data属性,把它结构赋值出来;解构赋值:const { age, gender } = user user是一个对象;
    const {data:res}=await this.$http.post("login",this.loginform)
    if(res.meta.status !==200) return  this.$message.error('登录失败');
    this.$message.success('登录成功') 
    window.sessionStorage.setItem('token', res.data.token) 
    //调用API 保存session;('token 键',值是 res.data 中保存的 token)   
    this.$router.push('/home') //编程式导航,跳转到 '/home' 页面;         
}

# element.js -->配置弹框提示  
//import {Message} from 'element-ui' 按需导入弹框提示组件
//Vue.prototype.$message=Message 进行全局挂载 $message自定义属性,Message是组件;把弹框组件,挂载到了vue的原型对象上,这样,每一个组件,都可以通过this,访问到$message,进行弹窗提示;
# 登录成功后的页面跳转 -->localStorage(持久化的存储机制)
/*1.除登录外的其他 API接口,必须在登录之后,才能访问;
  2.将登录成功后的 token,保存到客户端的 sessionStorage中;
  3.sessionStorage:会话期间的存储机制;token 只在当前网站,打开期间生效;*/                       
----------------------------------------------------------------------------------------
//创建 home.vue 组件
//路由规则:import Home from './components/home.vue' 
          {path:'/home',component:Home}
day05 编程式导航:
this.$router.push('hash地址') # hash和url地址的区别
this.$router.go(n) // 1前进一步;-1后退一步;

setItem 将value存储到key字段 .setItem( key, value) 
   sessionStorage.setItem("key", "value"); 	storage.setItem(keyName, keyValue);
	localStorage.setItem("site", "js8.in");
getItem 获取指定key本地存储的值 .getItem(key)
  	var value = sessionStorage.getItem("key"); 	
	var site = localStorage.getItem("site");

10. 路由导航守卫 控制访问权限

// router.js: 通过 url地址访问,没有token,没有登录,不能访问,强制跳转到登录页面

const router = new Router({  
   ... ...
})

// 为路由对象,挂载路由导航守卫
router.beforeEach((to,from,next)=>{ 
  if(to.path === '/login') return next(); 
  const tokenStr = window.sessionStorage.getItem('token'); //获取保存的token值
  if(!tokenStr) return next('/login'); //token 值为空,没有登录,强制跳转到登录页
  next(); //token存在,直接放行;
})
//to 将要访问的页面路径;from 从那个路径跳转过来;
//next()放行函数: 1.next()放行; 2.next('/login')强制跳转到的路径;
export default router 

11. 退出功能

基于 token 的方式,实现退出功能:销毁本地 token,后续请求,就不会携带 token;必须重新登录,才能访问;

Home.vue -->点击退出按钮

methods:{
  logout(){
    window.sessionStorage.clear(); //清空token
    this.$router.push('/login');   //编程式导航,跳转到登录页
  }
}

12. 提交到码云

git status 查看修改与新增的文件
将所有文件添加到暂存区:git add .
提交到本地仓库:git commit -m "登录功能"

查看当前分支: git branch  
将login分支代码,合并到 master主分支,先切换到主分支: git checkout master
再进行代码合并:git merge login
将本地的 master分支,推送到码云:git push

推送本地的子分支到码云,先切换到子分支:git checkout login
然后推送:git push -u origin login

13. 处理 ESLint警告

/*根目录添加,格式化工具配置文件 .prettierrc(json格式的文件),
  解决 ESLint 与 vscode 格式化时,的冲突 */
{
  "semi":false,  //格式化代码时,结尾不加';'
  "singleQuote":true  // ''替代" " 启用单引号,格式化方式;
}

.eslintrc.js文件

rules: {
  'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  'space-before-function-paren' : 0 //禁用 ()之前需要空格;
}

ESLint 规则

不能有';'
"双引号" 换成 '单引号'
()之前需要空格
行与行之间最多空一行
no-trailing-spaces 不要-拖拉-空格:多了一个空格
object-curly-newline 目标-卷曲-换行
eol-last 文件最后空一行
{ 前后距离都要有一个空格 }
标签后不允许有空格 <div>
关键字后,要有空格 class =''if (to.path === '/login') {}

你可能感兴趣的:(vue,vue.js,node.js,npm,javascript,前端)