likes
comments
collection
share

Vue小项目总结

作者站长头像
站长
· 阅读数 10

简介

项目是一个关于工作室的招新官网,分四个如下模块:

Vue小项目总结

该项目由vue框架搭建而成,使用css中less预处理语言,涉及一些值得记录的知识点,方便今后回顾,包括:搭建好Vue基本框架,公共css样式导出,风车图的旋转,按钮点击后页面的显示和隐藏,对接后端接口,elementUI中form表单的使用,打包dist等。

一、搭建基本框架

1.创建名为maker-iot的项目:

  • vue create maker-iot
  • 选择Manually select featrues
  • 空格选择Babel、Router、Vuex、CSS pre-processors
  • 选择3.x
  • 输入No
  • 选择Less
  • 选择In dedicated config files
  • 是否保存:Y 如上操作,即创建完毕

二、公共样式导出,并解决重复引用问题

1.在assets中创建style文件夹,创建mixins.lessvariables.less文件, 敲下以下代码:

mixins.less:此处运用到混入,可进一步减少css冗余。

// 鼠标经过上移阴影动画
.hoverShadow() {
    margin-top: 10px;
    &:hover {
       margin-top: 20px;
    }
}

.size {
    width: 100px;
    height: 100px;
}

.size2(@w) {
    width: @w;
    height: @w;
}

// 运用混入
.box {
    .size2(200px);
    .hoverShadow ();
    background-color: red;
    text-align: center;
    line-height: 200px;
}

variables.less:此处为常用变量参数,调用该参数替代名作为调节样式,方便统一修改

// 主题
@xtxColor: #27BA9B;
// 辅助
@helpColor: #E26237;
// 成功
@sucColor: #1DC779;
// 警告
@warnColor: #FFB302;
// 价格
@priceColor: #CF4444;

2.为了避免在不同组件中重复引入该样式,故在vue.config.js中配置如下

配置前在终端安装响应插件:vue add style-resources-loader

之后写入以下代码:

// +(解决文件需重复引入)
const path = require('path');

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,

  // 为解决以下两个文件需要重复引入的问题
  // 在此之前需要执行以下代码:vue add style-resources-loader
  pluginOptions: {
    'style-resources-loader': {
      preProcessor: 'less',
      patterns: [
        // __dirname绝对路径
        // +(解决文件需重复引入)
        path.join(__dirname, './src/assets/styles/variables.less'),
        // +(解决文件需重复引入)
        path.join(__dirname, './src/assets/styles/mixins.less')
      ]
    }
  },

})

3.在组件中使用案例:


  <div class="box">
    我是盒子
  </div>
.box {
  background-color: @helpColor;
}

盒子样式如下:

Vue小项目总结

4.可以在style文件夹中建base.css,在main.js中引入,作为全局初始化样式,一般可设如下代码:

* {
    padding: 0;
    margin: 0;
    /* 边框+内边距计入盒子宽高 */
    box-sizing: border-box;
}

body {
    font-family: '仿宋', '微软雅黑';
    font-size: 14px;
    /* 行高是字体大小的1.5倍 */
    line-height: 1.5;    
    font-weight: normal;
    color: #333;
    background-color: #f9f9f9;
}

/* 边框宽度为0 */
/* 默认宽度为100%,父级宽度多少它宽度就多少 */
div {
    border-width: 0px;
}

a {
    color: #333;
    text-decoration: none;
    outline: none;
}

li {
    list-style: none;
}

/* 设置边框样式 */
input {
    outline: none;
}

/* 媒体查询 */
@media (max-width: 768px) {
    /* 在小屏幕下,调整全局样式 */
    body {
      font-size: 12px;
    }
  }


.ellipsis {
    /* 不换行 */
    white-space: nowrap;
    /* 超出显示省略号 */
    text-overflow: ellipsis;
    /* 超出内容隐藏 */
    overflow: hidden;
}

/* 超过两行生省略号 */
.ellipsis-2 {
    /* 对于中日韩英等文本,可以实现任意字符换行 */
    word-break: break-all;
    text-overflow: ellipsis;
    /* 隐藏超出部分的内容,用于清除浮动,裁剪文本 */
    overflow: hidden;
}


/* 清除浮动 */
.clearfix::after {
    content: '';
    display: block;
    /* 隐藏元素但仍占据空间 */
    visibility: hidden;
    /* 在元素下方新建一行,并清除所有浮动元素的影响;*/ 
    /* 常用于解决父元素因为子元素浮动而导致高度坍塌问题 */
    clear: both;
}

导入main.js中,import './assets/styles/base.css'

三、风车旋转

例图如下:

Vue小项目总结 下面我将分三个版块来介绍该风车图:

1.点击前端组,左上角 "& &组——现任成员"修改为"前端组——现任成员",整个前端组的成员介绍展现出来,此处运用路由进行了跳转,思路如下:

a、在Member中创建各个组的组件,如下:

Vue小项目总结

b、在Router的index.js中引入路由:

//导入路由部分
//成员
import Member from '@/views/Member.vue'
//引入二级路由
import MemberCopy from '@/views/Member/MemberCopy.vue'
//引入三级路由
import BackEnd from '@/views/Member/BackEnd.vue'
...
import HardWare from '@/views/Member/HardWare.vue'

const routes = [
 {
    path: '/',
    ...
 },
  {
    path: '/Member',
    component: Member,
    children: [
      {
        path: '/Member',
        component: MemberCopy,
        children: [
          {
            path: '/Member',
            component: BackEnd
          },
         ...
          {
            path: '/HardWare',
            component: HardWare
          }
        ]
      }
    ]
  },

c、在MemberCopy.vue文件中使用路由:

            <router-link to="/Front">
              <div class="group">
                前端组
              </div>
            </router-link>
            ...

2.中间的介绍版块顺时针旋转,头像始终保持向上:

a、基本结构如下:

<ul class="circle">
  <li>
    <button @click="showone(1)"
    :class="yin===1? 'active':''" >
    <img src="../../assets/qq头像/YG.jpg" alt="">
    </button>
  </li>
  <li>
    <button @click="showone(2)"
    :class="yin===2? 'active':''" >
    <img src="../../assets/qq头像/WH.jpg" alt="">
    </button>
  </li>
    ...
</ul>

b、其对应的css样式:

  ul {
    width: 6.2rem;
    ...
    transform-origin: 3.1rem 3.1rem;
    animation: tf 34s linear infinite;
    li {
      width: 1.2rem;
      ...
      //旋转点自身高度的一半,父亲宽度的一半+自身宽度的一半
      transform-origin: .6rem 3.7rem;
      button {
      width: 1.2rem;
      ...
      //反向旋转
      animation: tf reverse 34s linear infinite;
      }
      &:nth-of-type(2) {
        transform: rotate(72deg);
        img {
          transform: rotate(-72deg);
        }
      }
      &:nth-of-type(3){
        transform: rotate(144deg);
        img {
          transform: rotate(-144deg);
        }
      }
      ...
    }
  }
  @keyframes tf {
  0%{
    transform:rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

(其实此处的button按钮略显多余,下次可以试着把button删去,将点击事件放在小 li 容器中)

3、当点击按钮时,展现对应的文字介绍:

a、介绍版块如下:

<div id="circle-text"
  v-show="yin==1">
  <div id="circle-tu-wen">
     ...
  </div>
  <div id="member-introduce">
    ...
  </div>
</div>
<div id="circle-text"
  v-show="yin==2">
  <div id="circle-tu-wen">
     ...
  </div>
  <div id="member-introduce">
    ...
  </div>
</div>
...

b、按钮版块可如上2.a所示

c、对介绍版块进行判断是否显示:

export default {
data () {
  return {
    // 控制切换按钮后按钮改变样式
    yin: 1,
    // 控制点击按钮后子组件显示,再次点击隐藏
    shi: true,
  }
},
methods: {
    //判断函数
  showone (value) {
    this.yin === value ? this.shi = !this.shi : this.shi = true
    this.yin = value
  },
},
setup() {
  let pasttext = reactive({
      first:{
        name: '* *',
        occupation: '前端组长,前端开发',
        signature:'永远做自己能力范围内的事,就无法取得进步'
      },
      second:{
        ...
      }
      ...
    });
    return {
      pasttext
    }
  }
}

四、导入elementUI,并使用表单

Vue小项目总结

1.安装elementUI:

npm install element-plus --save

2.在main.js全局导入: import ElementPlus from 'element-plus'

3.调用elementUI: const app = createApp(App); app.use(ElementPlus).mount('#app');

4.开始使用form表单:

<template>
<el-form :model="form">
        <el-form-item label="姓名" prop="name">
          <el-input v-model="form.name" placeholder="请输入你的姓名" required />
        </el-form-item>
</template>

<script>
import {reactive} from "vue"
export default {
  setup() {
    const form = reactive({
      name: '',
      introduce:''
    )}
    return {form}
 }
 
 <style scoped lang="less">
 // 改变element元素样式
  /deep/.el-form-item__label {
        font-size: .4rem;
        }
    /deep/.el-input__inner {
        &::placeholder {
        font-size: 14px;
      }
    }
 </style>

五、路由之间传值

从Join组件传值给JoinSpecific

1.在join组件中:传"后端"数据到JoinSpecific

          <router-link :to="{path:'/JoinSpecific',query:{name:'后端'}}"> 
          <el-button type="primary" round id="shenqing">申请岗位</el-button>
          </router-link>

2.在router中index.js文件中,导入路由:

import JoinSpecific from '@/views/Join/JoinSpecific'
const routes = [
  {
    path: '/',
    name: 'HomeView',
    component: HomeView,
    children: [
      {
        path: '/',
        component: Home
      }
    ]
  },
  ...
  //和主页面路由同级
  {
    path: '/JoinSpecific',
    name: 'JoinSpecific',
    component: JoinSpecific
  }
  ]

3.在JoinSpecific中接收数据:

import { onMounted} from 'vue'
import { useRoute } from 'vue-router'
export default {
    setup(){
    let $route = useRoute()
    onMounted(() => {
       //注意:箭头函数中this指向
      form.introduce=$route.query.name
      })
    }
}

六、连接接口,传值给后端

1.首先导入axios:

a、安装axios:npm install axios --save-D b、在main.js中导入:

//引入axios
import axios from 'axios'

const app = createApp(App);

app.use(store)
    .use(router)
    .use(ElementPlus)
    .mount('#app');

app.config.globalProperties.$http = axios;

2.在src中建utils文件夹,再建request.js文件,导入base_url:

import axios from 'axios'
//创建axios实例
const service = axios.create({
    baseURL: 'http://124.222.203.172:8081', // api的base_url。此处为nginx的地址
    timeout: 50000 // 请求超时时间
})

export default service

3.在src中建api文件夹,再建use.js文件,导入request.js,返回post请求:

import request from '@/utils/request'

export default {
    // 没有,默认为空
    newMember(userInfo = {}) {
        return request({
            url: `/makerservice/newMember/rigist`,
            method: 'post',
            data: userInfo
        })
    },
}

4.在JoinSpecific中点击提交按钮,发送数据

Vue小项目总结

<template>
<el-button type="primary" round @click="submitForm()">申请岗位</el-button>
</template>

<script>
import UserApi from '@/api/user.js'
export default {
    setup(){
        function submitForm() {
          alert('你已经提交成功')
          UserApi.newMember(form)
            .then(response => {
             this.code = response.data.code
             //手动将name清空
              form.name = ''
             })
        }
    }
}
</script>

此处有个提交数据后清空的问题,使用this.$refs.form.resetFields(); 无法实现,解决方法:手动清空 form.name = ''

七、打包dist文件:

1.在vue.config.js中加入以下内容

module.exports = defineConfig({
    publicPath: "./",
    //  构建时的输出目录
    outputDir: "dist",
    //  放置静态资源的目录
    assetsDir: "assets",
    //  html 的输出路径
    indexPath: "index.html",
    //文件名哈希
    filenameHashing: true,
    lintOnSave: true,
    //  是否使用带有浏览器内编译器的完整构建版本
    runtimeCompiler: false,
    //  babel-loader 默认会跳过 node_modules 依赖。
    // 配置 webpack-dev-server 行为。
    devServer: {
      open: process.platform === 'darwin',
      host: '0.0.0.0',
      port: 8081,
      https: false,
      hotOnly: false,
      // 查阅 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/cli-service.md#配置代理
      proxy: {
        '/api': {
          target: "http://124.222.203.172.maker-iot.com", // 项目用到的域名
          changeOrigin: true,
          secure: false,
          pathRewrite: {
            "^/api": ""
          }
        },
        // '/foo': {
        //   target: '<other_url>'
        // }
      }
    }
})

2.执行 npm run build开始打包

总结

1.本次项目,没有合理运用到页面布局框架,纯靠HTML和CSS手写,耗时费力,且得到的效果并不理想,当页面用手机端打开时,整个页面布局会乱掉,由于布局上的失误,导致后续的响应式难以实现,更改量大。

        关于实现页面布局响应式问题,需要利用好现有的框架,在做界面时,反复在电脑和手机端查看,尽量做到在不同机位上,都能有较为美观的展现。

2.由于后期需求不断变化,更改频繁,多次在调整样式时,耗费时间,并没有很大意义。下次需注意:做好需求分析,明确对方需要怎样的界面效果,并在一开始就尽可能收集页面布局的相关信息,考虑清楚后再动手写,会相对轻松且高效。

3.没有合理运用好css公共样式,在不断写重复代码,出现代码冗余,这点同样值得注意。

4.另外,网页部署上去后,会出现渲染延迟的问题,这一点在下一次做项目时,需要注意到并解决。

5.网页放在不同电脑上打开,有的盒子会相对减小,导致文字超出原本涉及的盒子大小,下一次需要考虑到页面兼容的问题。

转载自:https://juejin.cn/post/7234315967563104313
评论
请登录