SYT/XF

124 阅读11分钟

功能模块

  1. 展示医院数据(分页,筛选,搜索)
  2. 登录(手机验证码登录,微信授权登录,表单校验,表单清除)
  3. 预约挂号(展示医院详情,预约须知,展示有无号源,医生排班,确认挂号信息,挂号详情/已支付/已预约)
  4. 就诊人管理
  5. 实名认证
  6. 挂号订单
  7. 微信支付

接口文档

医院接口:http://139.198.34.216:8201/swagger-ui.html

公共数据接口: http://139.198.34.216:8202/swagger-ui.html

会员接口:http://139.198.34.216:8203/swagger-ui.html

短信验证码接口:http://139.198.34.216:8204/swagger-ui.html

订单接口:http://139.198.34.216:8206/swagger-ui.html

文件上传接口:http://139.198.34.216:8205/swagger-ui.html

后台用户接口:http://139.198.34.216:8212/swagger-ui.html 项目业务逻辑:

vue:购物车功能(Vuex),分类页面(别人的组件改了改)

xf

模板/样式  视图由 vant Ui less构建,对组件样式做一些修改,使用了/deep/深度选择器,做一些样式的修改, 模板上用到了 class属性,自定义属性,自定义时间,

指令语法:v-model(),v-for(遍历来自VueX的购物车列表),v-show(购物车为空就展示前往首页的按钮),

逻辑

  用到的选项式API有  name,mounted,methods,computed   name 为组件命名   mounted:进来就获取购物车的数据  异步操作需要dispatch一个action(action中执行异步操作) 但是为了VueX对数据有一个准确的跟踪并且

   mutation才是更改状态的唯一途径,我们需要commit一个mutation在mutation里面给state.cartList(购物车列表)进行一个赋值操作,

  赋值时利用map方法给请求过来的数据添加一个是否选中的属性。

  methods:购物车里有数据就显示数据,没有就是一个goHome()按钮,可以对购物车里面的每一项进行数量的加减(传 id 数量  调接口)和对

   每一项的删除(传id 调借口还要重新获取购物车),生成订单前要去选择地址的时候需要把选中的用forEach去重新用一个数组存起来,在做一个会话级的存储.

  computed:通过计算属性拿到VueX的购物车数据,reduce计算总价   ,定义checkAll计算属性,设置getter,setter 

模板/样式

   三级菜单   van-nav-bar van-search van-icon van-sidebar   van-grid  主体使用flex布局,侧边栏 使用fixed,其余就是设置宽高,字体,颜色.

逻辑 mounted:获取三级菜单的数据,并对右侧第一屏二三级菜单数据存在一个数组里面并渲染到页面,    methods:传入分类ID到搜索页面并跳转到搜索页面,点击搜索框到搜索页面 ,点击主类级别导航切换(根据侧边栏索引拿到对应的二级三级数据), 创建一个新数组把拿到的数据用来渲染到页面.

组件封装 :货物展示  Goods.vue 标题使用 具名插槽 组件内自定义商品展示网格 flex实现

微信扫码授权登录

image.png 1. 微信开放平台,注册应用。微信公众平台,查看文档 2. 引入wxlLogin.js,发请求(参数:window.location.origin + "/wxlogin")获取生成二维码所需参数 3. image.png 4. new WxLogin()利用iframe嵌入页面,微信服务器每隔一段时间询问是否登录 5. 授权成功 微信服务器向我们的服务器发请求(参数:code,state)  我们的服务器携带用户信息重定向到前端 6. 持久化存储用户信息,仓库存入信息

微信支付(syt)

1.     来到订单详情页  点击支付获取支付二维码(参数:订单号)

2.     qrcode插件 toDataURL字符串转二维码(base64)  :src:imageUrl 页面显示二维码

3.     长轮询发请求查看查询支付状态,服务器返回的数据data:true,代表支付成功

4.     支付成功 关闭对话框,关闭定时器并且显示提示信息,再次获取订单详情的数据

5.     不想支付,关闭弹窗

// 关闭窗口的回调
*const* closeDialog = () => {
  *//* *关闭对话框* *,* *对话框隐藏*
  dialogVisible.value = false;
  *//* *清除定时器*
  clearInterval(timer.value);
};

*//* *对话框右上角关闭的叉子的回调*
*const* close = ()=>{
  clearInterval(timer.value);
}

路由鉴权(syt)

image.png

image.png

element-plus按钮禁用之后还能点击执行相应回调(syt)

在回调函数里面第一行判断(获取验证码的逻辑是否执行下去)!

(iphone.value || flag.value) return 

封装本地存储用户信息的方法(syt)

//本地存储操作用户信息的方法
export *const* SET_TOKEN = (userInfo:string)=>{
    localStorage.setItem('USERINFO',userInfo);
}

export *const* GET_TOKEN = ()=>{
   *return* localStorage.getItem('USERINFO');
}
//清除本地存储用户相关的数据
export *const* REMOVE_TOKEN = ()=>{
   localStorage.removeItem('USERINFO');
}
导入使用

import { GET_TOKEN, SET_TOKEN, REMOVE_TOKEN } from "@/utils/user";

按钮级别权限控制

定义全局方法配合v-if实现

1. 定义全局方法


export default function btnPermission(qx) {
    return ['add', 'edit'].includes(qx)
}

2.     导入main.js

import btnPermission  from './permissions'

Vue.prototype.$has = btnPermission

3模板上使用


<button v-if='$has("add")'>新增</button>

<button v-if='$has("edit")'>编辑</button>

<button v-if='$has("delete")'>删除</button>

  自定义指令

1. 在main.js全局注册

Vue.directive('permission', {
  inserted: function (el, binding) {
    //从绑定的值中获取当前用户的权限信息
    const userPermissions = ['edit',"delete"]; //假设当前用户的权限是['edit', 'delete']
    //获取按钮需要的权限
    const requiredPermission = binding.value;
    //检查当前用户是否具有按钮所需的权限
    if (!userPermissions.includes(requiredPermission)) {
      //如果没有权限,隐藏按钮
      el.style.display = 'none';
    }
  }
})

2.     模板上使用

<button v-permission="'add'">新增</button>
<button v-permission="'edit'">编辑</button>
<button v-permission="'delete'">删除</button>

请求合并

1. 数据在网络中的传输时间大于数据在服务端的处理时间 可以合并

SEO

1.使用ssr

2.使用语义化标签

3.链接使用a标签

4.TDK规范

Nuxt.js 是一个使用 Vue.js 开发的渐进式框架,它提供了丰富的功能,如服务器端渲染(SSR)和首屏渲染优化。下面是一个简单的例子,展示了如何在 Nuxt.js 中实现首屏 SSR:

  1. 首先,在 Nuxt.js 项目中添加一个 data-ssr 属性,用于标记该元素是否需要进行首屏 SSR 渲染。例如:

插入复制

<template>
<div>
  <div v-if="showSSR">
    <div data-ssr>这里是首屏内容</div>
  </div>
  <div v-else>
    <div>这里是普通内容</div>
  </div>
</div>
</template>
  1. 然后,在 Nuxt.js 组件的 mounted 生命周期钩子函数中,使用 fetch 函数获取首屏内容。例如:

插入复制


mounted() {
 this.showSSR = true;
 const content = fetch('https://example.com/ssr-content');
 content.then((response) => {
   response.text().then((data) => {
     this.$next({
       data: {
         content: data,
       },
     });
   });
 });
}
  1. 在 Nuxt.js 组件的 created 生命周期钩子函数中,使用 async/await 关键字等待首屏内容获取完成,然后将其插入到页面中。例如:

插入复制

async function loadSSRContent(context) {
 const content = context.data.content;
 const ssrElement = document.querySelector('[data-ssr]');
 ssrElement.innerHTML = content;
}
//在页面加载时,调用loadSSRContent函数
loadSSRContent({});
  1. 最后,在 Nuxt.js 项目的 nuxt.config.js 文件中,配置服务器端渲染(SSR)的相关参数。例如:

插入复制

export default {
 buildModules: [
   'nuxt-ssr',
 ],
 ssr: {
   //开启服务器端渲染
   enabled: true,
   //配置服务器端渲染的路径
   path: '/_ssr',
 },
}

这样,首屏内容将在 Nuxt.js 项目中进行服务器端渲染,然后在页面加载时立即显示,从而提高用户体验。需要注意的是,首屏 SSR 的实现需要根据具体情况进行调整和优化,以确保最佳效果。

Mixin(全局)

1.新建mixin.js导出配置对象。

//导出对象
export const hunhe = {
    data() {
        return {
            name: 'judyking',
            age: 21
        }
    },
    methods: {
        say() {
            console.log(this.name);
        }
    }
}

2.main.js全局导入

import {hunhe,hunhe1} from './mixin'
Vue.mixin(hunhe)
Vue.mixin(hunhe1)

3. 然后就全局使用了

Mixins(局部)

<script>
import {hunhe,hunhe1} from './mixin'
export default {
mixins:[hunhe,hunhe1],
name: "App",
};
</script>

组件封装(newbee)

1. 自定义属性传数据渲染

2. 插槽使用控制结构

3. 父组件中定义事件(逻辑多样)子组件中触发实现

this.$emit("事件名",子传父的值)
//事件处理程序
handler(val){
      // val是子传递给父的数据
      console.log("val:",val);
}

应用场景

<Goods :dataItem="newGoodses">
        <template #title>
          <div>
            <h3>新品上线</h3>
          </div>
        </template>
      </Goods>

用自定义属性将数据渲染到封装的组件

利用具名插槽展示不同推荐商品的标题

购物车(newbee)

进来就获取购物车的数据  异步操作需要dispatch一个action(action中执行异步操作) 但是为了VueX对数据有一个准确的跟踪并且mutation才是更改状态的唯一途径,我们需要commit一个mutation在mutation里面给state.cartList(购物车列表)进行一个赋值操作,赋值时利用map方法给请求过来的数据添加一个是否选中的属性。methods:购物车里有数据就显示数据,没有就是一个goHome()按钮,可以对购物车里面的每一项进行数量的加减(传 id 数量  调接口)和对每一项的删除(传id 调借口还要重新获取购物车),生成订单前要去选择地址的时候需要把选中的用forEach去重新用一个数组存起来,在做一个会话级的存储.computed:通过计算属性拿到VueX的购物车数据,reduce计算总价   ,定义checkAll计算属性,设置getter,setter。

路由懒加载

只要将需要进行懒加载的子模块文件( ``children chunk`` ) 的引入语句( 本文特指``import`` () )放到一个函数内部。 然后再需要加载的时候执行该函数

const routes = [{
path: '/',
name: 'Home',
//将子组件加载语句封装到一个function中,将function赋给 component
component: () => import( /* webpackChunkName: "home" */ '../views/Home.vue')
}]
import()被请求的模块和它引用的所有子模块,会分离到一个单独的 chunk 中。
/* webpackChunkName: "home" */魔法注释

图片懒加载

图片懒加载的原理是没有在可视区域的图片暂时不加载图片,等进入可视区域后在加载图片,这样可以减少初始页面加载的图片数量而提升页面加载速度。 图片懒加载在提升页面加载速度的同时也会伴随用户看其他未展示的图片时会有等待时间;图片加载显示会伴有布局抖动等问题。

<!-- img中使用图片懒加载。 v-lazy代替v-bind:src -->
<img v-lazy="item" alt="" style="width: 768px;">
<!-- 背景图中使用图片懒加载。 v-lazy:background-image = "" -->
<li v-for="(item,index) in imgList" v-lazy:background-image="item"></li>

微信支付

image.png

微信小程序

image.png

image.png 后端自己实现 image.png

小程序

 tabbar页面:首页面/我的页面 非tabbar页面:商品列表页面/商品详情页面/订单页面/登陆页面/注册页面等 

  登陆

  整体就是一个form组件 给bindsubmit属性设置一个回调, 登录按钮要设置form-type属性为submit,这样回调函数可以接收一个参数,里面有表单数据.

   点击登录按钮, 把表单数据本地缓存账号密码 用于回显.发请求,成功就提示缓存token, 设置app.globalData.loginUserinfo = 1,接着跳转到我的页面

   登录页面加载时执行onLoad(query)  query 中有上个页面路径中带的参数。设置data中backUrl中的值为query.backUrl,获取本地缓存,如果本地缓存有值就

   设置data中inputUserInfo中的值为本地缓存的值,回显.

注册

   整体就是一个form组件 给bindsubmit属性设置一个回调, 登录按钮要设置form-type属性为submit,这样回调函数可以接收一个参数,里面有表单数据.

"navigationStyle": "custom" navigationStyle 可用的值为:default 默认样式、custom 自定义导航栏(只保留右上角胶囊按钮)

        backLogin() {
            wx.navigateBack({
                delta: 1
            })
        }
//带着表单数据发请求,成功就
        wx.redirectTo({
            url: "/pages/login/login"
        });

我的页面

   我的页面加载执行OnLoad()获取用户信息  OnShow()要判断app.globalData.loginUserinfo 登录就是设置data里面的isLogin  登录就显示昵称和邮箱'

   没登陆就显示登陆注册按钮、重定向到登陆页面,好多跳转(我的信息,我的分享,我的订单,修改密码,关于我们,退出登陆),退出登陆要清除缓存,

   app.globalData.loginUserinfo=0

其他须知(根据简历可能问到)

富文本解析 :

  源码中 img 属性  data-src   src

wxs:
格式化时间
        定义: 
function formatTime(time) {
            if (!time) return ""
            var date = getDate(time)
            var year = date.getFullYear()
            var month = date.getMonth() + 1
            var day = date.getDate()
            return year + '年' + month + '月' + day + '日'
        }
        导出:
        module.exports = {
            formatTime: formatTime
        }
        引入:
        <wxs module="tools" src="../../utils/tools.wxs"></wxs>
        使用:
        { { tools.formatTime(detail.pub_date) } }

后台管理系统

1、 对jquery进行了再次封装,做了请求地址拼接,headers,错误处理。

2、 在menu.json配置侧边栏。

3、 使用数据表格table模块对接展示后端数据,设置分页,分页字段名,表头,格式化数据,使用行工具模板为表格最后一列添加按钮等。

4、 新增,编辑使用layer.open()打开同一页面,编辑,删除通过监听行工具事件进行判断在发送相应的请求。

5、 layui.table.reload()实现表格重载。

微信小程序responsive pixe

image.png

面试项目问题

   图片懒加载:图片是网站优化的一个重点,图片懒加载是其中比较好用的一个方法。jquery也有很多图片懒加载的插件,

今天看了一下vue的图片懒加载插件 ---- vue-lazyload。

<!-- img中使用图片懒加载。 v-lazy代替v-bind:src -->
<!-- 背景图中使用图片懒加载。 v-lazy:background-image = "" --> 
<!-- 注意图片和盒子大小问题,否则显示可能有问题哦。--> 
 <img v-lazy="图片地址" :key="图片地址">

   :key=""  必须要加,否则就会出现,页面刷新,其他内容都刷新了,但是只有图片不刷新的情况 。因为key可能相同,所以页面不会更新!!!

   淘宝适配:  rem要根据html的font-size换算    MD5加密  随机盐加密     其实也很简单,就是设置一个过期时间,也就是cookie的失效的日期,当然中间需要有一些格式的处理,数据的加工。

   设置开发代理服务器  生产模式可能无跨域问题

   我叫祝志鹏,今年22岁,23年毕业于郑州工业应用技术学院应届毕业生。有近1年的开发⼯作经验,我对技术有深厚的兴趣,专业知识⾯宽,熟练使用Vue,和原生微信小程序开发,责任⼼强,思路清晰,沟通⼒能好。

自我介绍:

  我叫XX,今年X岁,XXXX年毕业于XX⼤学。有年的开发⼯作经验,我对技术有深厚的兴趣,专 业知识⾯宽,责任⼼强,思路清晰,沟通⼒能好,

熟练前端开发技术体系。平常有 时间看看博客,并且⾃⼰也喜欢在CSDN、简书、博客园等上写技术类的⽂章,与博友⼀起讨论。谢谢!