项目仓库:https://github.com/changeclass/vue-shop

项目初始化

  1. 安装脚手架

  2. 通过VUE脚手架创建项目

  3. 安装Element-ui组件库、

    添加插件处安装

  4. 配置axios库

    安装依赖处安装

  5. 将项目托管在GitHub中

  6. 后台配置

    • MySQL
    • Node.js

    后端API项目地址:https://github.com/changeclass/Tzk/tree/master/2020-11/vue-api

登录与退出

保持用户登录状态有两种方法:第一种:利用Cookie和Session,但这种方式存在跨域问题。第二种:利用token,这种方式可以避免跨域问题

image-20201104104003647

登录页面的开发

  1. 通过子分支进行开发

    git checkout -b login
  2. 删除不要的组件

  3. 创建登录组件

    • components中新建一个Login.vue文件。

      <template>
      <div>登录组件</div>
      </template>
      
      <script>
      export default {}
      </script>
      
      <style scoped>
      </style>
    • 设置路由

      const routes = [
        // 当访问根路径时自动跳转登录页面
        {
          path: '/',
          redirect: '/login'
        },
        // 登录页面的路由
        { path: '/login', component: Login }
      ]
  4. 登录组件的布局

    • 安装less-loaderless依赖到开发依赖。
  5. 表单组件的验证

    表单组件验证使用elementUi提供的方法rules

    • 为组件绑定rules,值定义在data数据里,为一个对象。通过prop属性为组件绑定使用那个一个规则

      <el-form :rules="loginFormRules" >
          <el-form-item prop="username">
              <el-input></el-input>
          </el-form-item>
      data: function () {
          return {
              loginFormRules: {
                  username: [
                      { 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: '长度3到10个字符', trigger: 'blur' }
                  ]
              }
          },
  6. 表单值双向绑定

    双向绑定使用:model,其值也为一个对象,定义在data里。子组件通过v-model绑定data里的值。

    <el-form :model="loginFrom" >
        <!-- 用户名 -->
        <el-form-item prop="username">
            <el-input v-model="loginFrom.username"></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item prop="password">
            <el-input v-model="loginFrom.password" ></el-input>
        </el-form-item>
    </el-form>
    data: function () {
        return {
            // 这是登录表单的数据绑定对象
            loginFrom: {
                username: 'admin',
                password: '123456'
            }
        },
  7. 登录事件

    当登录后触发事件,将数据提交给后台。

    • 挂在axios

      在入口文件导入axios库

      import axios from 'axios'
      // 配置根路径
      axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
      Vue.prototype.$http = axios
    • 发送请求

      发送请求需要使用表单中的数据,因此可以直接获取表单进行提交。通过对form表单添加一个引用属性ref即可在方法中获取元素

      <el-form ref="loginFormRef" >
      login () {
          this.$refs.loginFormRef.validate(async valid => {
              // 如果valid为true则表示验证通过
              if (!valid) return
              const { data: res } = await this.$http.post('login', this.loginFrom)
              if (res.meta.status !== 200) return this.$message.error('登录失败')
              this.$message.success('登录成功')
              // 登录成功后的逻辑
              window.sessionStorage.setItem('token', res.data.token)
              this.$router.push('/home')
          })
      }
    • 将数据存储在sessionStorage中。

      调用window对象的方法即可。

  8. 路由导航

    当登录成功后应该跳转home页面,但如果没有登录成功,那么应该重定向到登录页面,而不是直接打开home页面。在路由文件中为route对象添加逻辑

    const router = new VueRouter({
        routes
    })
    // 路由导航守卫
    router.beforeEach((to, from, next) => {
        // to 将要访问的路径
        // from 代表从那个路径跳转而来
        // next表示一个函数,放行
        if (to.path === '/login') return next()
        // 获取TOKEN
        const tokenStr = window.sessionStorage.getItem('token')
        if (!tokenStr) return next('./login')
        next()
    })

退出

退出的逻辑很简单,只需要调用window的方法,将sessionStorage里的数据清除即可。

methods: {
    logout () {
        window.sessionStorage.clear()
        this.$router.push('/login')
    }
}

报错或警告

格式化问题

格式化后会自动将单引号转换为双引号,以及添加分号。解决方案:

在项目根目录创建.prettierrc文件,写入如下内容:

{
  "semi":false,
  "singleQuote": true
}

方法后添加空格问题

.eslintrc.js文件中添加如下规则:

rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'space-before-function-paren': 0
  }

Vetur

如果使用了此插件,那么建议禁用掉这个插件的格式化代码,而是使用Eslint插件的代码格式化。

image-20201104171933087