vue学习106-120

创建项目p106


router,store和app.vue不用删
清一下router里的路由配置

vant组件库p107

目标:认识第三方vue组件库vant-ui(cv战士)
封装好了的组件整合在一起就是组件库
http://vant-contrib.gitee.io/vant/v2/#/zh-CN/
vue2用vant2,vue3用vant3和4
在这里插入图片描述
vant全部导入太慢了,按需导入推荐
安装npm i vant@latest-v2 -S
阿里云安装镜像 npm config set registry https://registry.npmmirror.com/

引入

vant网址http://vant-contrib.gitee.io/vant/v2/#/zh-CN/quickstart
cv到main.js
方式一. 自动按需引入组件 (推荐)
babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。

###### 安装插件
npm i babel-plugin-import -D
// 在.babelrc 中添加配置
// 注意:webpack 1 无需设置 libraryDirectory
{
  "plugins": [
    ["import", {
      "libraryName": "vant",
      "libraryDirectory": "es",
      "style": true
    }]
  ]
}

// 对于使用 babel7 的用户,可以在 babel.config.js 中配置
module.exports = {
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant']
  ]
};
// 接着你可以在代码中直接引入 Vant 组件
// 插件会自动将代码转化为方式二中的按需引入形式
import { Button } from 'vant';

Tips: 如果你在使用 TypeScript,可以使用 ts-import-plugin 实现按需引入。

方式二. 手动按需引入组件(要css,不推荐)
在不使用插件的情况下,可以手动引入需要的组件。

import Button from 'vant/lib/button';
import 'vant/lib/button/style';

方式三. 导入所有组件
Vant 支持一次性导入所有组件,引入所有组件会增加代码包体积,因此不推荐这种做法。

import Vue from 'vue';
import Vant from 'vant';
import 'vant/lib/index.css';
//插件安装初始化,内部将所有的vant组件进行导入注册
Vue.use(Vant);

Tips: 配置按需引入后,将不允许直接导入所有组件。

按需导入


安装插件每次都要重新弄npm i babel-plugin-import -D

module.exports = {
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant']
  ]
};

在这里插入图片描述
放main.js里太多了,导入组件单独分一个vant-ui.js放在utils文件夹里
如果渲染不出来,重新打开编程软件和终端
在这里插入图片描述

postcss插件-实现vw适配p108

postcss写多少px直接转换为多少vw
在这里插入图片描述
npm下载插件:npm install postcss-px-to-viewport@1.1.1 -D --force//npm install postcss-px-to-viewport --legacy-peer-deps/
要在根目录上(和src同级的)创建postcss.config.js
然后官网cv:

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
    },
  },
};

在这里插入图片描述

路由设计配置p109

一级路由配置

单个页面独立展示的是一级路由
在这里插入图片描述
每个一级路由要建成一个文件夹
在这里插入图片描述
文件夹里只有一个时直接简写文件夹
path中表示首页的是/

二级路由-底部导航tabbar

vant组件库有
在这里插入图片描述
vant2里有基础组件-icon图标
tabber标签栏-自定义颜色
在这里插入图片描述
点击切换用vant2的路由模式
在这里插入图片描述
默认首页在routes里加redirect
在这里插入图片描述
在这里插入图片描述

登录页静态布局+图形验证码功能p110

在这里插入图片描述

头部navbar

通用样式覆盖
在这里插入图片描述

request模块-axios封装-13min

使用axios请求后端接口,单独封装到一个request模块
request模块放在utils/request.js文件里
接口文档地址: https://apifox.com/apidoc/shared-12ab6b18-adc2-444c-ad11-0e60f5693f66/doc-2221080
基地址:http://cba.itlike.com/public/index.php?s=/api/
request文件里面放axios官方文档-axios实例(https://www.axios-http.cn/docs/instance)
在这里插入图片描述

  1. 创建axios实例
    创建axios实例不会污染原始的axios实例,如果触及就会改底层参数
  2. 自定义配置-请求/响应 拦截器
添加请求拦截器

给原本axios实例加配置,没加到创建的实例上,要想不污染原始,就改成instance(创建的axios实例上)
在这里插入图片描述
axios的接口文档要从智慧商城找(http://cba.itlike.com/public/index.php?s=/api/)

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',//接口文档地址
  timeout: 1000,//超时时间
  headers: {'X-Custom-Header': 'foobar'}//这个没用
});

在这里插入图片描述

添加响应拦截器

在这里插入图片描述

导出配置好的实例(instance)

获取图片验证码数据结构,要复制地址

  1. base64:图片
  2. key:唯一标识
  3. md5:验证
    在这里插入图片描述

图形验证码

在这里插入图片描述

获取短信验证码-39min

前两个缺一不可
4. captchacode 图形验证码值
5. captchakey验证码的唯一标识
6. mobile手机号
在这里插入图片描述

api接口模块-封装图片验证码接口p111

api模块(存放封装好的请求函数)
以前的模式

  1. 页面请求代码太多,可阅读性不高
  2. 相同请求没有复用
  3. 请求没有统一管理
    封装api模块的好处
  4. 请求与页面逻辑分离
  5. 相同的请求可以直接复用
  6. 请求进行了统一管理
    在这里插入图片描述

toast轻提示p112

在这里插入图片描述
点击出现轻提示
在这里插入图片描述
进入页面出现轻提示
在这里插入图片描述
this.$toast()只能用在实例组件里
在这里插入图片描述

短信验证倒计时p113

在这里插入图片描述
totalSecond和second要一致
封装短信验证请求接口智慧商城里
import { getMsgCode } from '@/api/login’别忘了导入

<template>
  <div class="login" @click="getPicCode">
    <button>wds</button>
    <input type="number">
    <button @click="getCode">{{ second===totalSecond? '获取验证码':second+'秒后重新发送'}}</button>
  </div>
</template>

<script>
import { getMsgCode } from '@/api/login'

export default {
  name: 'login-page',
  data () {
    return {
      picKey: '',
      picUrl: '',
      totalSecond: 6, // 总秒数
      second: 6, // 当前秒数
      timer: null, // 定时器id
      mobile: '', // 手机号
      picCode: ''// 用户输入的图形验证码
    }
  },
  methods: {
    // 获取图片验证码
    async getPicCode () {
      // Toast('获取图形验证码成功')
      this.$toast('wdf')
    },
    // 校验手机号和图形验证码是否合法
    validFn () {
      if (!/^1[3-9]\d{9}$/.test(this.mobile)) {
        this.$toast('请输入正确手机号')
        return false
      }
      if (!/^\w{4}$/.test(this.picCode)) {
        this.$toast('请输入正确手机号')
        return false
      }
      return true
    },
    // 获取验证码
    async getCode () {
      if (!this.validFn()) {
        return
      }
      // 当前没有定时器开着,且totalsecond和second一致(秒数归位)才可以倒计时
      if (!this.timer && this.totalSecond === this.second) {
        // 发送请求
        await getMsgCode(this.captchaCode, this.captchaKey, this.mobile)
        // 开启倒计时
        setInterval(() => {
          this.second--
          if (this.second <= 0) {
            clearInterval(this.timer)
            this.timer = null// 重置定时器id
            this.second = this.totalSecond// 归位
          }
        }, 1000)
      }
    }

  },
  destroyed () {
    clearInterval(this.timer)// 离开页面清除定时器
  }
}
</script>

<style>

</style>

响应拦截处理器-统一处理错误p115

status

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么(默认axios会多包装一层data,需要响应拦截器中处理一下)
  const res = response.data
  if (res.status !== 200) {
    // 给提示
    Toast(res.message)
    // 抛出一个错误的promise
    return Promise.reject(res.message)
  }
  return response.data
}, function (error) {
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么
  return Promise.reject(error)
})

在这里插入图片描述

登录权证信息存储token和userld(user模块)/将token权证信息存入vuexP116

user模块放在store下面
在这里插入图片描述
在这里插入图片描述

export default {
  namespaced: true,
  // 提供数据
  state () {
    return {
      // 个人权证相关
      userInfo: {
        token: '',
        userId: ''
      }
    }
  },
  // 提供修改数据的方法的
  mutations: {},
  // 提供异步操作
  actions: {},
  // 提供基于state派生出来的属性
  getters: {}
}

storage存储模块-vuex持久化处理P117

vuex刷新会丢失,storage模块放utils里

// 约定一个通用的键名
const INFO_KEY = 'hm-shopping-info'

// 获取个人信息
export const getInfo = () => {
  const defultObj = { token: '', userId: '' }
  const result = localStorage.getItem(INFO_KEY)
  return result ? JSON.parse(result) : defultObj
}

// 设置个人信息
export const setInfo = (obj) => {
  localStorage.setItem(INFO_KEY, JSON.stringify(obj))
}

// 移除个人信息
export const removeInfo = () => {
  localStorage.removeItemItem(INFO_KEY)
}

import { getInfo, setInfo } from '@/utils/storage'

export default {
  namespaced: true,
  // 提供数据
  state () {
    return {
      // 个人权证相关
      userInfo: getInfo
    }
  },
  // 提供修改数据的方法的
  mutations: {
    // 所有mutations的第一个参数,都是state
    setUserInfo (state, obj) {
      state.userInfo = obj
      setInfo(obj)
    }
  },
  // 提供异步操作
  actions: {},
  // 提供基于state派生出来的属性
  getters: {}
}

添加请求loading效果P118

toast轻提示中的加载提示
在这里插入图片描述

页面访问拦截p119

在这里插入图片描述

// 所有的路由在真正访问到之前,都会经过全局前置守卫
// 只有全局前置守卫放行了,才能到达对应的页面

// 全局前置导航守卫
// to:到哪里去,到哪去的完整路由信息对象(路径,参数)
// from:到哪里来,从哪来的完整路由信息对象(路径,参数)
// next:是否放行
// (1)next()直接放行,放行到to要去的路径
// (2)next(路径)进行拦截,拦截到next里面配置的路径
router.beforeEach((to, from, next) => {
  // ...
  // 返回 false 以取消导航
  return false
})

在这里插入图片描述

// 定义一个数组,专门用户存放所有需要权限访问的页面
const authUrls= ['']

router.beforeEach((to, from, next) => {
  // ...
  // 返回 false 以取消导航
  // return false
  if (!authUrls.includes(to.path)) {
    // 非权限页面,直接放行
    next()
    return
  }
  // 是权限页面,需要判断token
  const token = store.getters.token
  if (token) {
    next()
  } else {
    next('/login')
  }
})
getters: {
    token (state) {
      return state.user.userInfo.token
    }
  },

首页-静态页面结构准备&动态渲染P120

  1. 静态结构准备(直接cv)
<template>
    <div class="home">
      <!-- 导航条 -->
      <van-nav-bar title="智慧商城" fixed />

      <!-- 搜索框 -->
      <van-search
        readonly
        shape="round"
        background="#f1f1f2"
        placeholder="请在此输入搜索关键词"
        @click="$router.push('/search')"
      />

      <!-- 轮播图 -->
      <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
        <van-swipe-item>
          <img src="@/assets/banner1.jpg" alt="">
        </van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/banner2.jpg" alt="">
        </van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/banner3.jpg" alt="">
        </van-swipe-item>
      </van-swipe>

      <!-- 导航 -->
      <van-grid column-num="5" icon-size="40">
        <van-grid-item
          v-for="item in 10" :key="item"
          icon="http://cba.itlike.com/public/uploads/10001/20230320/58a7c1f62df4cb1eb47fe83ff0e566e6.png"
          text="新品首发"
          @click="$router.push('/category')"
        />
      </van-grid>

      <!-- 主会场 -->
      <div class="main">
        <img src="@/assets/main.png" alt="">
      </div>

      <!-- 猜你喜欢 -->
      <div class="guess">
        <p class="guess-title">—— 猜你喜欢 ——</p>

        <div class="goods-list">
          <GoodsItem v-for="item in 10" :key="item"></GoodsItem>
        </div>
      </div>
    </div>
  </template>

<script>
import GoodsItem from '@/components/GoodsItem.vue'
export default {
  name: 'HomePage',
  components: {
    GoodsItem
  }
}
</script>

  <style lang="less" scoped>
  // 主题 padding
  .home {
    padding-top: 100px;
    padding-bottom: 50px;
  }

  // 导航条样式定制
  .van-nav-bar {
    z-index: 999;
    background-color: #c21401;
    ::v-deep .van-nav-bar__title {
      color: #fff;
    }
  }

  // 搜索框样式定制
  .van-search {
    position: fixed;
    width: 100%;
    top: 46px;
    z-index: 999;
  }

  // 分类导航部分
  .my-swipe .van-swipe-item {
    height: 185px;
    color: #fff;
    font-size: 20px;
    text-align: center;
    background-color: #39a9ed;
  }
  .my-swipe .van-swipe-item img {
    width: 100%;
    height: 185px;
  }

  // 主会场
  .main img {
    display: block;
    width: 100%;
  }

  // 猜你喜欢
  .guess .guess-title {
    height: 40px;
    line-height: 40px;
    text-align: center;
  }

  // 商品样式
  .goods-list {
    background-color: #f6f6f6;
  }
  </style>

还要导入
在这里插入图片描述
2. 封装接口
导入api
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/388502.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python自学...

一、稍微高级一点的。。。 1. 闭包&#xff08;跟js差不多&#xff09; 2. 装饰器 就是spring的aop 3. 多线程

开窗,挖槽,放电齿,拼版

我们在阻焊层画线&#xff0c;就相当于去掉绿油阻焊&#xff0c;开窗一般是用在大电流走线的时候。先画要走的导线&#xff0c;之后切换到TopSolder或者Bottom Solder层&#xff0c;然后Place->line 画一条和原来先粗细一样的线即可&#xff01;但走电流的仍然是导线&#x…

第21讲关于我们页面实现

关于我们页面实现 关于锋哥页面author.vue 我们这里用一个vip宣传页面&#xff0c;套一个web-view <template><web-view src"http://www.java1234.com/vip.html"></web-view> </template><script> </script><style> <…

信息学奥赛一本通1258:【例9.2】数字金字塔

1258&#xff1a;【例9.2】数字金字塔 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 44051 通过数: 26272 【题目描述】 观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可以从当前点走到左下方…

[嵌入式系统-15]:RT-Thread -1- 简介与技术架构

目录 一、RT-Thread简介 1.1 简介 1.2 功能特点 1.3 发展历史 1.4 应用场合 1.5 与Linux的比较 1.6 ​​​​​​​RT-Thread优缺点 二、技术架构 2.1 分层架构​编辑 2.2 功能组件 2.3 应用程序接口RT-Thread API 2.4 应用程序接口&#xff1a;RT-Thread API、POS…

[HCIE]vxlan --静态隧道

实验目的:1.pc2与pc3互通&#xff08;二层互通&#xff09;&#xff1b;2.pc1与pc3互通&#xff08;三层互通&#xff09; 实验说明&#xff1a;sw1划分vlan10 vlan20 ;sw2划分vlan30&#xff1b;上行接口均配置为Trunk 实验步骤&#xff1a; 1.配置CE1/CE2/CE3环回口互通&a…

房屋租赁系统的Java实战开发之旅

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

springboot191教师工作量管理系统

简介 【 毕设 源码 推荐 javaweb 项目】 基于 springbootvue 的教师工作量管理系统&#xff08;springboot191&#xff09; 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后…

【调试】pstore原理和使用方法总结

什么是pstore pstore最初是用于系统发生oops或panic时&#xff0c;自动保存内核log buffer中的日志。不过在当前内核版本中&#xff0c;其已经支持了更多的功能&#xff0c;如保存console日志、ftrace消息和用户空间日志。同时&#xff0c;它还支持将这些消息保存在不同的存储…

Vulnhub靶场 DC-6

目录 一、环境搭建 二、主机发现 三、漏洞复现 1、wpscan工具 2、后台识别 dirsearch 3、爆破密码 4、rce漏洞利用 activity monitor 5、rce写shell 6、新线索 账户 7、提权 8、拿取flag 四、总结 一、环境搭建 Vulnhub靶机下载&#xff1a; 官网地址&#xff1a…

了解Ping、Wget、端口、Netstat和Curl命令

1. 端口 1.1 什么是端口&#xff1f; 端口是一种用于标识不同应用程序或服务的逻辑通道。它是一个数字&#xff0c;取值范围从0到65535。常见的端口有一些已经被标准化&#xff0c;比如HTTP使用的80端口&#xff0c;HTTPS使用的443端口。 1.2 了解端口状态 使用netstat -an…

超详细的介绍Python语句

一、 常用命令 在介绍Python语句之前&#xff0c;先介绍一下几个有用的Python命令。 dir(模块名或类名或变量名或表达式名)&#xff1a;获得当前模块、变量对应类型、表达式计算值对应类的属性列表 type&#xff08;变量名或表达式名&#xff09;:获取变量或表达式计算值的对…

URL编码算法:解决特殊字符在URL中的烦恼

引言&#xff1a; URL编码算法是一种将URL中的特殊字符转换为特定格式的编码方式。它在网络传输中起到了保护数据安全与完整性的重要作用。本文将深入探讨URL编码算法的优点与缺点&#xff0c;并介绍它在Web开发、网络安全等方面的应用。 URL编码解码 | 一个覆盖广泛主题工具…

C++类和对象-C++对象模型和this指针->成员变量和成员函数分开存储、this指针概念、空指针访问成员函数、const修饰成员函数

#include<iostream> using namespace std; //成员变量 和 成员函数 分开储存的 class Person { public: Person() { mA 0; } //非静态成员变量占对象空间 int mA; //静态成员变量不占对象空间 static int mB; //函数也不占对象空间…

【leetcode】深搜、暴搜、回溯、剪枝(C++)2

深搜、暴搜、回溯、剪枝&#xff08;C&#xff09;2 一、括号生成1、题目描述2、代码3、解析 二、组合1、题目描述2、代码3、解析 三、目标和1、题目描述2、代码3、解析 四、组合总和1、题目描述2、代码3、解析 五、字母大小写全排列1、题目描述2、代码3、解析 六、优美的排列1…

《合成孔径雷达成像算法与实现》Figure6.13

clc clear close all参数设置 距离向参数设置 R_eta_c 20e3; % 景中心斜距 Tr 2.5e-6; % 发射脉冲时宽 Kr 20e12; % 距离向调频率 alpha_os_r 1.2; % 距离过采样率 Nrg 320; % 距离线采样数 距离向…

ChatGPT重大升级:能自动记住用户的习惯和喜好,用户有权决定是否共享数据给OpenAI

OpenAI刚刚宣布了ChatGPT的一项激动人心的更新&#xff01; OpenAI在ChatGPT中新加了记忆功能和用户控制选项&#xff0c;这意味着GPT能够在与用户的互动中记住之前的对话内容&#xff0c;并利用这些信息在后续的交谈中提供更加相关和定制化的回答。 这一功能目前正处于测试阶…

六、Mybatis注解开发

1.MyBatis的常用注解 注解开发越来越流行&#xff0c; Mybatis也可以使用注解开发方式&#xff0c;这样就可以减少编写Mapper映射文件。Insert&#xff1a;实现新增Update&#xff1a;实现更新Delete&#xff1a;实现删除Select&#xff1a;实现查询Result&#xff1a;实现结果…

BigDecimal的常用API

BigDecimal用于解决浮点型运算时结果出现失真的问题。 这里0.20.1等于0.3就出现了失真 import java.math.BigDecimal; import java.math.RoundingMode;public class Test {public static void main(String[] args) {//BigDeciaml的使用&#xff1a;解决小数运算失真的问题doub…

【HarmonyOS 4.0 应用开发实战】ArkTS 快速入门之常用属性(3)

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…