1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > vue实战 —— 图书商城移动端项目

vue实战 —— 图书商城移动端项目

时间:2022-12-01 00:47:04

相关推荐

vue实战 —— 图书商城移动端项目

介绍下项目功能

全部采用组件化封装思想,尽可能的去符合企业级项目,封装了自定义指令、app换肤等...

1、点击登录会判断正则,同时有小图标提示,错误显 X 正确显 ✔

2、登录按钮默认灰色,账号密码全部正确则变绿色

3、css布局 (最基础!)

4、Vue3 动画库

5、输入框搜索

6、。。。

前期回顾

综合热榜前6,js榜单第一,建议查看

Vue项目实战 —— 哔哩哔哩移动端开发_0.活在风浪里的博客-CSDN博客撑着下班前半小时我用vue写《哔哩哔哩 项目》移动端、新手还在哭、老鸟一直在笑。。。技术选型Vue2,技术栈有axios、Vh等,下班过来敲哈哈/m0_57904695/article/details/123594836

我故意写成两个项目,一个单独写登录注册和图书商城,但是没有js逻辑。另一个项目,单独写图书商城有js,这样将俩个分开,如果大家想要练习最适合不过,可以去写js逻辑,有一个项目是写好的,一个是没写的,方便 练习

效果图

登录

<template><div class="home"><my-headerv-back="$store.state.backColor"right-text="切换主题"title="用户登录"@right-click="rightClick"/><div class="form"><my-inputlabel="手机号码"placeholder="请输入手机号码":icon="mobileIcon"v-model="mobile"></my-input><my-inputlabel="密码"placeholder="请输入密码":icon="pwdIcon"v-model="pwd"></my-input><button class="btn" :disabled="disabled" @click="$router.push('/about')">登陆</button></div></div></template><script>import myHeader from "@/components/myHeader";import myInput from "@/components/myInput";import { ref, watch, watchEffect } from "vue";import { useStore } from "vuex";export default {name: "Home",components: {myHeader,myInput,},setup() {const disabled = ref(true);const mobile = ref("");const pwd = ref("");const mobileIcon = ref("");const pwdIcon = ref("");const color = ref("#cccccc");const store = useStore();// 手机号码正则表达式let regMobile = /^1[356789]\d{9}$/;let regPwd = /^[a-zA-Z]\w{5}$/;// watchEffect兼容数据变化的方法 但是只能用来兼容ref数据watchEffect(() => {if (regMobile.test(mobile.value) && regPwd.test(pwd.value)) {disabled.value = false;// 判断成功则将变量颜色赋值按钮color.value = store.state.backColor;} else {disabled.value = true;}});watch(() => mobile.value,() => {if (regMobile.test(mobile.value)) {mobileIcon.value = "iconfont duihao";} else {mobileIcon.value = "iconfont chahao";}});watch(() => pwd.value,() => {// console.log(regPwd.test(pwd.value));if (regPwd.test(pwd.value)) {pwdIcon.value = "iconfont duihao";} else {pwdIcon.value = "iconfont chahao";}});function rightClick() {// console.log(1);mit("changeBackColor");}return {rightClick,disabled,mobile,pwd,mobileIcon,pwdIcon,color,};},};</script><style lang="scss" scoped>.form {width: 100%;margin-top: 200px;padding: 0 40px;}.btn {display: block;margin: 0 auto;width: 150px;height: 36px;border: none;outline: none;border-radius: 6px;background-color: v-bind(color);color: #fff;}.btn[disabled] {background-color: #ccc;color: #fff;}</style>

vuex store/index.js

import { createStore } from 'vuex'import axios from 'axios'export default createStore({state: {// 默认颜色backColor: '#cccccc',// 存放数据,页面默认渲染的数据books: [],// 用于搜索_books: [],},mutations: {changeBackColor(state) {state.backColor = '#' + Math.round(Math.random() * 16777216).toString(16)},changeBooks(state, arr) {state.books = arrstate._books = deepClone(arr)function deepClone(obj) {if (typeof obj !== 'object' || obj == null) {return obj}let resultif (obj instanceof Array) {result = []} else {result = {}}for (let key in obj) {if (obj.hasOwnProperty(key)) {result[key] = deepClone(obj[key])}}return result}},},actions: {async getDate({ commit }) {//将请求的数据中的 list取出来let data = await axios.get('/goods.json')console.log(data.data.list);commit('changeBooks', data.data.list)}},modules: {}})

登录子组件

<template><div class="my-header"><span class="left">{{leftText}}</span><span class="title">{{title}}</span><span class="right" @click="clickEve">{{rightText}}</span></div></template><script>export default {// props接受数据有两种形式 一种是数组 另外一种是对象// 数组用法简单不多介绍// 对象props: {show: Boolean, // 只定义需要接受的数据的数据类型时的写法leftText: {type: String, // 要求接收的数据时字符串required: false, // 该数据不是必须传递的default: ''},rightText: {type: String,required: false,default: ''},title: String},setup(props, { emit }) {function clickEve() {emit('right-click')}return {clickEve}}}</script><style lang="scss" scoped>.my-header {width: 100%;height: 50px;display: flex;justify-content: space-between;background-color: orangered;align-items: center;.left,.right {flex-basis: 30%;text-align: center;}.right {color: skyblue;}.title {color: #fff;font-size: 24px;font-weight: bold;}}</style>

<template><div class="my-input"><label>{{label}}</label><input type="text" :placeholder="placeholder" :value="modelValue" @input="iptChange"><span :class="icon" ></span></div></template><script>export default {props: {label: String,placeholder: String,icon: String,modelValue: String},setup(props, { emit }) {function iptChange(e) {emit('update:modelValue', e.target.value)}return {iptChange}}}</script><style lang="scss" scoped>.my-input {width: 100%;display: flex;align-items: center;margin-bottom: 15px;label {width: 56px;flex-shrink: 0;font-size: 14px;overflow: hidden;white-space: nowrap;text-align: justify;text-align-last: justify;}input {height: 36px;margin-left: 5px;border: 1px solid #ccc;outline: none;border-radius: 6px;padding-left: 10px;margin-right: 10px;}.duihao {color: green;font-weight: 900;}.chahao {color: red;}}</style>

登录后页面

<template><div class="about"><myHeader left-text="" title="图书商城" right-text="我的书架"></myHeader><div class="search"><input type="text" placeholder="请根据书名进行搜素" /></div><div class="my-card"><!-- 子组件负责接受父组件数据,定义结构样式,父组件负责传值 念及此 为封装思路 --><myCard v-for="item in books" :key="item._id" :item="item"></myCard></div></div></template><script>import myHeader from "../components/myHeader";import myCard from "../components/myCard.vue";import { useStore } from "vuex";import { computed } from "vue";export default {setup() {const store = useStore();store.dispatch("getDate");// 在计算属性拿到这个值赋值一个变量,就不用每次都$store.state.booksconst books = computed(() => store.state.books);return {books,};},components: {myHeader,myCard,},};</script><style lang="scss" scoped>.search {width: 100%;height: 40px;background-color: #ccc;padding: 5px;input {width: 100%;height: 30px;border: none;font-size: 17px;background-color: transparent;outline: none;padding-left: 10px;}}.my-card {height: calc(100% - 90px);overflow: auto;display: flex;flex-wrap: wrap;}</style>

源码推送到主页的资源里了,需要的哥们儿到主页资源,down

如果感觉对你有帮助,收藏下方便找时快速翻到

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。