当前位置: 首页 > news >正文

网站前台做哪些工作内容做设计需要知道的几个网站

网站前台做哪些工作内容,做设计需要知道的几个网站,做外贸商城网站,做爰明星视频网站目录 01: 通用组件#xff1a;input 构建方案分析 02: 通用组件#xff1a;input 构建方案 03: 构建用户资料基础样式 04: 用户基本资料修改方案 05: 处理不保存时的同步问题 06: 头像修改方案流程分析 07: 通用组件#xff1a;Dialog 构建方案分析 08: 通用组件input 构建方案分析 02: 通用组件input 构建方案 03: 构建用户资料基础样式  04: 用户基本资料修改方案 05: 处理不保存时的同步问题  06: 头像修改方案流程分析 07: 通用组件Dialog 构建方案分析 08: 通用组件Dialog 构建方案 09: 应用 Dialog 展示头像 10: 头像裁剪构建方案  11. 阿里云 OSS 与腾讯云 COS 对象存储方案分析  腾讯云 COS COS SDKCOS 的包  阿里云 OSS OSS 基础概念 创建存储桶Bucket 使用 STS 临时访问凭证访问 OSS  上传图片到 Bucket 的流程分析 配置 CORS 跨域处理 12. 使用临时凭证上传裁剪图片到阿里云 OSS 13. 完成头像更新操作 14. 登录鉴权解决方案 15: 总结 01: 通用组件input 构建方案分析 期望通用组件 input 至少满足 4 个功能 1. 支持单行文本输入  2. 支持多行文本输入 3. 通过 v-model 实现双向数据绑定 4. 支持最大文本输入 根据以上功能点可判断出 input 组件要有 3 个 prop 1. v-model 2. type单行 or 多行 3. max支持最大字符数 02: 通用组件input 构建方案 - src/libs - - input - - - index.vue // src/libs/input/index.vuetemplatediv classrelativeinputv-iftype TYPE_TEXTclassborder-gray-200 dark:border-zinc-600 dark:bg-zinc-800 duration-100 dark:text-zinc-400 border-[1px] outline-0 py-0.5 px-1 text-sm rounded-sm focus:border-blue-400 w-fulltypetextv-modeltext:maxlengthmax/textareav-iftype TYPE_TEXTAREAv-modeltext:maxlengthmaxrows5classborder-gray-200 dark:border-zinc-600 dark:bg-zinc-800 duration-100 dark:text-zinc-400 border-[1px] outline-0 py-0.5 px-1 text-sm rounded-sm focus:border-blue-400 w-full/textareaspanv-ifmaxclassabsolute right-1 bottom-0.5 text-zinc-400 text-xs:class{ text-red-700: currentNumber parseInt(max) }{{ currentNumber }} / {{ max }}/span/div /templatescript const TYPE_TEXT text const TYPE_TEXTAREA textarea /scriptscript setup import { useVModel } from vueuse/core import { computed } from vueconst props defineProps({modelValue: {required: true,type: String},type: {type: String,default: TYPE_TEXT,validator(value) {const arr [TYPE_TEXT, TYPE_TEXTAREA]const result arr.includes(value)if (!result) {throw new Error(type 的值必须在可选范围内 [${arr.join(、)}])}return result}},max: {type: [String, Number]} })// 事件声明 defineEmits([update:modelValue])// 输入的字符 const text useVModel(props)// 输入的字符数 const currentNumber computed(() {return text.value?.length }) /scriptstyle langscss scoped/style03: 构建用户资料基础样式  tailwindcss 先构建移动端再构建 PC 端更方便。 - src/views - - profile - - - index.vue // 路由信息{path: /profile,name: profile,component: () import(/views/profile/index.vue),// 标记当前的页面只有用户登录之后才可以进入meta: {user: true} }, // src/views/profile/index.vuetemplatedivclassh-full bg-zinc-200 dark:bg-zinc-800 duration-400 overflow-auto xl:pt-1divclassrelative max-w-screen-lg mx-auto bg-white dark:bg-zinc-900 duration-400 xl:rounded-sm xl:border-zinc-200 xl:dark:border-zinc-600 xl:border-[1px] xl:px-4 xl:py-2!-- 移动端 navbar --m-navbar sticky v-ifisMobileTerminal :clickLeftonNavbarLeftClick个人资料/m-navbar!-- pc 端 --div v-else classtext-lg font-bold text-center mb-4 dark:text-zinc-300个人资料/divdiv classh-full w-full px-1 pb-4 text-sm mt-2 xl:w-2/3 xl:pb-0!-- 头像 --div classpy-1 xl:absolute xl:right-[16%] xl:text-centerspanclassw-8 inline-block mb-2 font-bold text-sm dark:text-zinc-300 xl:block xl:mx-auto我的头像/span!-- 头像部分 --divclassrelative w-[80px] h-[80px] group xl:cursor-pointer xl:left-[50%] xl:translate-x-[-50%]clickonAvatarClickimgv-lazy:src$store.getters.userInfo.avataraltclassrounded-[50%] w-full h-full xl:inline-block/divclassabsolute top-0 rounded-[50%] w-full h-full bg-[rgba(0,0,0,.4)] hidden xl:group-hover:blockm-svg-iconnamechange-header-imageclassw-2 h-2 m-auto mt-2/m-svg-icondivclasstext-xs text-white dark:text-zinc-300 scale-90 mt-0.5点击更换头像/div/div/div!-- 隐藏域 --inputv-showfalserefinputFileTargettypefileaccept.png, .jpeg, .jpg, .gifchangeonSelectImgHandler/p classmt-1 text-zinc-500 dark:text-zinc-400 text-xs xl:w-10支持 jpg、png、jpeg 格式大小 5M 以内的图片/p/div!-- 用户名 --div classpy-1 xl:flex xl:items-center xl:my-1span classw-8 block mb-1 font-bold dark:text-zinc-300 xl:mb-0用户名/spanm-inputv-modeluserInfo.nicknameclassw-fulltypetextmax20/m-input/div!-- 职位 --div classpy-1 xl:flex xl:items-center xl:my-1span classw-8 block mb-1 font-bold dark:text-zinc-300 xl:mb-0职位/spanm-inputv-modeluserInfo.titleclassw-fulltypetext/m-input/div!-- 公司 --div classpy-1 xl:flex xl:items-center xl:my-1span classw-8 block mb-1 font-bold dark:text-zinc-300 xl:mb-0公司/spanm-inputv-modeluserInfo.companyclassw-fulltypetext/m-input/div!-- 个人主页 --div classpy-1 xl:flex xl:items-center xl:my-1span classw-8 block mb-1 font-bold dark:text-zinc-300 xl:mb-0个人主页/spanm-inputv-modeluserInfo.homePageclassw-fulltypetext/m-input/div!-- 个人介绍 --div classpy-1 xl:flex xl:my-1span classw-8 block mb-1 font-bold dark:text-zinc-300 xl:mb-0个人介绍/spanm-inputv-modeluserInfo.introductionclassw-fulltypetextareamax50/m-input/div!-- 保存修改 --m-buttonclassw-full mt-2 mb-4 dark:text-zinc-300 dark:bg-zinc-800 xl:w-[160px] xl:ml-[50%] xl:translate-x-[-50%]:loadingloadingclickonChangeProfile保存修改/m-button!-- 移动端退出登录 --m-buttonv-ifisMobileTerminalclassw-full dark:text-zinc-300 dark:bg-zinc-800 xl:w-[160px] xl:ml-[50%] xl:translate-x-[-50%]clickonLogoutClick退出登录/m-button/div/div!-- PC 端 --m-dialog v-if!isMobileTerminal v-modelisDialogVisiblechange-avatar-vue:blobcurrentBolbcloseisDialogVisible false/change-avatar-vue/m-dialog!-- 移动端 --m-popupv-else:class{ h-screen: isDialogVisible }v-modelisDialogVisiblechange-avatar-vue:blobcurrentBolbcloseisDialogVisible false/change-avatar-vue/m-popup/div /templatescript export default {name: profile } /scriptscript setup import { isMobileTerminal } from /utils/flexible import { putProfile } from /api/sys import { message, confirm } from /libs import { useRouter } from vue-router import { useStore } from vuex import { ref, watch } from vue import changeAvatarVue from ./components/change-avatar.vueconst store useStore() const router useRouter()// 隐藏域 const inputFileTarget ref(null) // 头像 dialog 展示 const isDialogVisible ref(false) // 选中的图片 const currentBolb ref() /*** 更换头像点击事件*/ const onAvatarClick () {inputFileTarget.value.click() }/*** 头像选择之后的回调*/ const onSelectImgHandler () {// 获取选中的文件const imgFile inputFileTarget.value.files[0]// 生成 blob 对象const blob URL.createObjectURL(imgFile)// 获取选中的图片currentBolb.value blob// 展示 DialogisDialogVisible.value true }/*** 监听 dialog 关闭*/ watch(isDialogVisible, (val) {if (!val) {// 防止 change 不重复触发inputFileTarget.value.value null} })/*** 数据本地的双向同步增加一个单层深拷贝*/ const userInfo ref({ ...store.getters.userInfo }) // const changeStoreUserInfo (key, value) { // store.commit(user/setUserInfo, { // ...store.getters.userInfo, // [key]: value // }) // }/*** 修改个人信息*/ const loading ref(false) const onChangeProfile async () {loading.value trueawait putProfile(userInfo.value)message(success, 用户信息修改成功)// 更新 vuexstore.commit(user/setUserInfo, userInfo.value)loading.value false }/*** 移动端后退处理*/ const onNavbarLeftClick () {// 配置跳转方式store.commit(app/changeRouterType, back)router.back() }/*** 移动端退出登录*/ const onLogoutClick () {confirm(确定要退出登录吗).then(() {store.dispatch(user/logout)}) } /scriptstyle langscss scoped/style 04: 用户基本资料修改方案 // 第一种方式直接修改 vuex state 数据违背 vue 理念。m-input v-model$store.getters.userInfo.nickname /// 第二种方式优化第一种方式。m-input :modelValue$store.getters.userInfo.nicknameupdate:modelValuechangeStoreUserInfo(nickname, $event) /const changeStoreUserInfo (key, value) {store.commit(user/setUserInfo, {...store.getters.userInfo,[key]: value}) }// 第三种方式解决用户信息未提交但提前缓存问题。推荐。m-input v-modeluserInfo.nickname //*** 数据本地的双向同步增加一个单层深拷贝*/ const userInfo ref({ ...store.getters.userInfo })/*** 修改个人信息*/ const onChangeProfile async () {// 发送修改请求 代码省略// 更新 vuexstore.commit(user/setUserInfo, userInfo.value) } 05: 处理不保存时的同步问题  讲解一下 v-model 拆解的问题。 给不理解的同学讲解一下为什么不能用 v-model 直接绑定 vuex 中的数据以及绑定之后会产生什么样的问题 思路及代码在上一小节之中。 06: 头像修改方案流程分析 接下来我们需要处理头像修改的业务逻辑。 对于该功能而言分为 PC 端和 移动端 两种情况我们需要分别进行处理 1. PC 端 1. 点击更换头像。 2. 选择对应文件。 3. 通过 Dialog 展示图片剪裁。 4. 剪裁后图片上传。 5. 功能完成。 2. 移动端 1. 点击更换头像。 2. 选择对应文件。 3. 通过 popup 展示图片剪裁。 4. 剪裁后图片上传。 5. 功能完成。 由此可以发现两者之间需要通过不同的组件进行裁剪展示。 因此我们后续的开发流程为 1. 通用组件Dialog。 2.  处理图片剪裁。 3. 处理剪裁后上传。 07: 通用组件Dialog 构建方案分析 首先我们来处理 Dialog 通用组件。 对于 Dialog 通用组件而言我们可以参考 confirm 组件的构建过程。 它们两个构建方案非常相似唯二不同的地方是 1. Dialog 无需通过方法调用的形式展示。 2. Dialog 的内容区可以渲染任意的内容。 排除这两点之后其余与 confirm 完全相同。 08: 通用组件Dialog 构建方案 - src/libs - - dialog - - - index.vue templatediv!-- 蒙版 --transition namefadedivv-ifisVisableclickcloseclassw-screen h-screen bg-zinc-900/80 z-40 fixed top-0 left-0/div/transition!-- 内容 --transition nameupdivv-ifisVisableclassmax-w-[80%] max-h-[80%] overflow-auto fixed top-[10%] left-[50%] translate-x-[-50%] z-50 px-2 py-1.5 rounded-sm border dark:border-zinc-600 cursor-pointer bg-white dark:bg-zinc-800 xl:min-w-[35%]!-- 标题 --divclasstext-lg font-bold text-zinc-900 dark:text-zinc-200 mb-2v-iftitle{{ title }}/div!-- 内容 --div classtext-base text-zinc-900 dark:text-zinc-200 mb-2slot //div!-- 按钮 --div classflex justify-end v-ifcancelHandler || confirmHandlerm-button typeinfo classmr-2 clickonCancelClick{{cancelText}}/m-buttonm-button typeprimary clickonConfirmClick{{confirmText}}/m-button/div/div/transition/div /templatescript setup import { useVModel } from vueuse/coreconst props defineProps({// 控制开关modelValue: {type: Boolean,required: true},// 标题title: {type: String},// 取消按钮文本cancelText: {type: String,default: 取消},// 确定按钮文本confirmText: {type: String,default: 确定},// 取消按钮点击事件cancelHandler: {type: Function},// 确定按钮点击事件confirmHandler: {type: Function},// 关闭的回调close: {type: Function} })defineEmits([update:modelValue])// 控制显示处理 const isVisable useVModel(props)/*** 取消按钮点击事件*/ const onCancelClick () {if (props.cancelHandler) {props.cancelHandler()}close() }/*** 确定按钮点击事件*/ const onConfirmClick () {if (props.confirmHandler) {props.confirmHandler()}close() }const close () {isVisable.value falseif (props.close) {props.close()} } /scriptstyle langscss scoped .fade-enter-active, .fade-leave-active {transition: all 0.3s; }.fade-enter-from, .fade-leave-to {opacity: 0; }.up-enter-active, .up-leave-active {transition: all 0.3s; }.up-enter-from, .up-leave-to {opacity: 0;transform: translate3d(-50%, 100px, 0); } /style09: 应用 Dialog 展示头像 // src/views/profile/index.vuetemplateimg :srccurrentBolb / /templatescript setup// 选中的图片 const currentBolb ref()/*** 头像选择之后的回调*/ const onSelectImgHandler () {// 获取选中的文件const imgFile inputFileTarget.value.files[0]// 生成 blob 对象const blob URL.createObjectURL(imgFile)// 获取选中的图片currentBolb.value blob// 展示 DialogisDialogVisible.value true }/*** 当 input file 两次选择文件是同一个的时候change 的回调不会被再次触发。* 想要解决这个问题只需要在每次选择的图片不再被使用之后清空掉 input file 的 value。* 监听 dialog 关闭*/ watch(isDialogVisible, (val) {if (!val) {// 防止 change 不重复触发inputFileTarget.value.value null} }) /script - src/views/profile - - components - - - change-avatar.vue // src/views/profile/components/change-avatar.vuetemplatediv classoverflow-auto relative flex flex-col items-centerm-svg-iconv-ifisMobileTerminalnamecloseclassw-3 h-3 p-0.5 m-1 ml-autofillClassfill-zinc-900 dark:fill-zinc-200 clickclose/m-svg-iconimg class refimageTarget :srcblob /m-buttonclassmt-4 w-[80%] xl:w-1/2:loadingloadingclickonConfirmClick确定/m-button/div /templatescript const EMITS_CLOSE close// 移动端配置对象 const mobileOptions {// 将裁剪框限制在画布的大小viewMode: 1,// 移动画布裁剪框不动dragMode: move,// 裁剪框固定纵横比1:1aspectRatio: 1,// 裁剪框不可移动cropBoxMovable: false,// 不可调整裁剪框大小cropBoxResizable: false }// PC 端配置对象 const pcOptions {// 裁剪框固定纵横比1:1aspectRatio: 1 } /scriptscript setup import { isMobileTerminal } from /utils/flexible import Cropper from cropperjs import cropperjs/dist/cropper.css import { ref, onMounted } from vue import { getOSSClient } from /utils/sts import { message } from /libs import { useStore } from vuex import { putProfile } from /api/sysdefineProps({blob: {type: String,required: true} })const emits defineEmits([EMITS_CLOSE])/*** 图片裁剪处理*/ const imageTarget ref(null) let cropper null onMounted(() {/*** 接收两个参数* 1. 需要裁剪的图片 DOM* 2. options 配置对象*/cropper new Cropper(imageTarget.value,isMobileTerminal.value ? mobileOptions : pcOptions) })/*** 确定按钮点击事件*/ const loading ref(false) const onConfirmClick () {loading.value true// 获取裁剪后的图片cropper.getCroppedCanvas().toBlob((blob) {// 裁剪后的 blob 地址// console.log(URL.createObjectURL(blob))putObjectToOSS(blob)}) }/*** 进行 OSS 上传*/ let ossClient null let store useStore() const putObjectToOSS async (file) {if (!ossClient) {ossClient await getOSSClient()}try {// 因为当前凭证只具备 images 文件夹下的访问权限所以图片需要上传到 images/xxx.xx 。否则你将得到一个 《AccessDeniedError: You have no right to access this object because of bucket acl.》 的错误const fileTypeArr file.type.split(/)const fileName ${store.getters.userInfo.username}/${Date.now()}.${fileTypeArr[fileTypeArr.length - 1]}// 文件存放路径文件const res await ossClient.put(images/${fileName}, file)// 通知服务器onChangeProfile(res.url)} catch (e) {message(error, e)} }/*** 上传新头像到服务器*/ const onChangeProfile async (avatar) {// 更新本地数据store.commit(user/setUserInfo, {...store.getters.userInfo,avatar})// 更新服务器数据await putProfile(store.getters.userInfo)// 通知用户message(success, 用户头像修改成功)// 关闭 loadingloading.value false// 关闭 dialogclose() }/*** 关闭事件*/ const close () {emits(EMITS_CLOSE) } /scriptstyle langscss scoped/style10: 头像裁剪构建方案  接下来我们需要在 src/views/profile/components/change-avatar.vue 中处理对应的图片裁剪功能。  想要处理图片裁剪我们需要使用到 cropperjs它是一个 Javascript 的库同时支持 PC 端 和 移动端。 目前 cropperjs 的最新发布版本为 1.6.2V2 级别的版本还是 RC 阶段所以我们还是使用它的 V1 版本。 1. 安装 cropperjs npm install cropperjs1.5.12 --save 2. 在 src/views/profile/components/change-acatar.vue 中进行导入 import Cropper from cropperjs import cropperjs/dist/cropper.css 3. 使用 new Cropper 进行初始化区分 PC端 和 移动端所有配置项 // 移动端配置对象 const mobileOptions {// 将裁剪框限制在画布的大小viewMode: 1,// 移动画布裁剪框不动dragMode: move,// 裁剪框固定纵横比1:1aspectRatio: 1,// 裁剪框不可移动cropBoxMovable: false,// 不可调整裁剪框大小cropBoxResizable: false }// PC 端配置对象 const pcOptions {// 裁剪框固定纵横比1:1aspectRatio: 1 } 4.  /*** 图片裁剪处理*/ const imageTarget ref(null) let cropper null onMounted(() {/*** 接收两个参数* 1. 需要裁剪的图片 DOM* 2. options 配置对象*/cropper new Cropper(imageTarget.value,isMobileTerminal.value ? mobileOptions : pcOptions) }) 5. /*** 确定按钮点击事件*/ const loading ref(false) const onConfirmClick () {loading.value true// 获取裁剪后的图片cropper.getCroppedCanvas().toBlob((blob) {// 裁剪后的 blob 地址// console.log(URL.createObjectURL(blob))putObjectToOSS(blob)}) } 11. 阿里云 OSS 与腾讯云 COS 对象存储方案分析  当图片裁剪处理完成之后接下来我们就可以处理裁剪之后的图片上传了。 通常情况下在企业开发中图片或文件的管理都会通过 对象存储 的方案进行。目前国内常见的对象存储云方案主要有两个平台  1. 阿里云 OSS 2. 腾讯云 COS 腾讯云 COS 腾讯云 COS 目前提供了 实名认证赠送 6个月 对象存储的服务点击跳转 这个服务对大家而言是非常好的一个练习服务大家可以直接使用该服务来实现 裁剪图片上传到腾讯云。 以下为腾讯云 COS 使用流程 1. 注册 腾讯云 账号并完成 实名认证。  2. 选择免费产品。 3. 选择腾讯云 COS。 4. 点击立即开通。 5. 创建存储桶。 6. 点击创建。 7. 选择 公有读、私有写。 8. 一路下一步创建即可。 此时你可以得到对应的存储桶所有的文件都会被上传到该存储桶之中。 接下来就可以按照以下步骤进行图片上传 COS SDKCOS 的包  对应文档地址  1. 下载依赖包 npm i cos-js-sdk-v5 --save 2. 构建 cos 实例初始化 cos 对象参数  名称描述SecretId开发者拥有的项目身份识别 ID用以身份认证可在 API 密钥管理 页面获取SecretKey开发者拥有的项目身份密钥可在 API 密钥管理 页面获取 import COS from cos-js-sdk-v5const cos new COS({SecretId: ,SecretKey: }) 3. 执行上传操作 cos.putObject({Bucket: , // 填入您自己的存储痛必须字段Region: , // 存储桶所在地域例如 ap-beijing必须字段Key: params.file.name, // 存储在桶里的对象键例如 1.jpg a/b/test.txt必须字段StorageClass: STANDARD,Body: , // 上传文件对象onProgress: function (progressData) {console.log(JSON.stringify(progressData)} }, function (err, data) {// 上传成功返回的数据data.location 为图片的地址console.log(err || data) }) 4. 图片上传成功在存储桶中即可查看上传的图片。  阿里云 OSS 目前国内企业使用最多的云服务为 阿里云所以说咱们文章将会以 阿里云 为例进行开发。 阿里云的 OSS 服务有新人三个月的免费试用。 我们将使用 OSS 进行图片的上传。 阿里云 OSS 使用流程 1. 注册登录 阿里云服务。 2. 找到 阿里云 OSS 对象存储服务。 3. 点击 立即开通。 4. 选择 立即开通。 5. 勾选服务点击立即开通。 6. 提示开通成功之后可以进行两个操作。 1. 点击 管理控制台 进入 OSS 控制台。 2. 点击 对象存储新手入门 查看文档。 OSS 基础概念 OSS 中包含了很多的基础概念可以点击 这里 直接进行访问。 需要大家了解的基础概念有 1. Bucket存储空间。 2. Object存储文件。 创建存储桶Bucket 在 控制台 左侧点击 Bucket 列表然后点击 创建 Bucket读写权限为 私有 使用 STS 临时访问凭证访问 OSS  在 Bucket 构建完成之后接下来我们就需要去处理 访问凭证。  注意构建访问凭证会涉及到服务端的配置。在实际开发中不需要 前端工程师来处理访问凭证相关的内容。 具体的构建流程可以点击 这里 进行查看。 名词解释 RAM(Resource Access Management) STS(Security Token Service) ARN是指云服务所定义的资源(Aliyun Resource Name) 上传图片到 Bucket 的流程分析 1. 想要上传文件到 Bucket我们需要使用 ali-sdk ali-oss。 2. 利用 ali-oss 生成 OSS 对象。 3. 在生成 OSS 对象时需要传递 文件上传凭证 1. accessKeyId。 2. accessKeySecret。 3. stsToken。 4. 需要通过接口 /user/sts 获取 文件上传凭证。 整体的文件上传流程为 1. 通过接口 /user/sts 获取 文件上传凭证。 2. 通过 npm i ali-oss 安装依赖包。 3. 使用凭证中的数据构建 OSS 对象。点击这里查看文档。 配置 CORS 跨域处理 当我们尝试使用 put 方法上传文件时会得到一个跨域的错误。 想要处理这个问题则需要 配置跨域规则。点击这里查看配置方案。 12. 使用临时凭证上传裁剪图片到阿里云 OSS 本小节我们将讲解如何将裁剪后的图片上传到阿里云 OSS。 具体步骤如下 1. 安装 ali-oss 依赖。 2. 通过接口获取临时访问凭证生成 OSS 实例。 3. 利用 ossClient.put 方法完成对应上传。 接下来我们一步一步去做 1. 安装 ali-oss 依赖。 npm i --save ali-oss6.17.0 2. 创建 src/utils/sts.js 模块用来生成 OSS 实例。 import OSS from ali-oss import { REGION, BUCKET } from /constants import { getSts } from /api/sysexport const getOSSClient async () {const res await getSts()return new OSS({// yourRegion填写Bucket所在地域。以华东1杭州为例Region填写为oss-cn-hangzhou。region: REGION,// 从STS服务获取的临时访问密钥AccessKey ID和AccessKey Secret。accessKeyId: res.Credentials.AccessKeyId,accessKeySecret: res.Credentials.AccessKeySecret,// 从STS服务获取的安全令牌SecurityToken。stsToken: res.Credentials.SecurityToken,// 填写Bucket名称。bucket: BUCKET,// 刷新 token在 token 过期后自动调用但是并不生效可能会在后续的版本中修复refreshSTSToken: async () {// 向您搭建的STS服务获取临时访问凭证。const res await getSts()return {accessKeyId: res.Credentials.AccessKeyId,accessKeySecret: res.Credentials.AccessKeySecret,stsToken: res.Credentials.SecurityToken}},// 刷新临时访问凭证的时间间隔单位为毫秒。refreshSTSTokenInterval: 5 * 1000}) }3. 在 constants 中定义 REGIONBUCKET // STS 上传数据 export const REGION oss-cn-beijing export const BUCKET imooc-front 4.  /*** 进行 OSS 上传*/ let ossClient null let store useStore() const putObjectToOSS async (file) {if (!ossClient) {ossClient await getOSSClient()}try {// 因为当前凭证只具备 images 文件夹下的访问权限所以图片需要上传到 images/xxx.xx 。否则你将得到一个 《AccessDeniedError: You have no right to access this object because of bucket acl.》 的错误const fileTypeArr file.type.split(/)const fileName ${store.getters.userInfo.username}/${Date.now()}.${fileTypeArr[fileTypeArr.length - 1]}// 文件存放路径文件const res await ossClient.put(images/${fileName}, file)// 通知服务器onChangeProfile(res.url)} catch (e) {message(error, e)} }/*** 上传新头像到服务器*/ const onChangeProfile async (avatar) {// 更新本地数据store.commit(user/setUserInfo, {...store.getters.userInfo,avatar})// 更新服务器数据await putProfile(store.getters.userInfo)// 通知用户message(success, 用户头像修改成功)// 关闭 loadingloading.value false// 关闭 dialogclose() }/*** 关闭事件*/ const close () {emits(EMITS_CLOSE) } 13. 完成头像更新操作 为了代码连贯性故代码写在上一小节中。 14. 登录鉴权解决方案 // src/permission.jsimport router from /router import store from /store import { message } from /libs/*** 处理需登录页面的访问权限*/ router.beforeEach((to, from) {// 无需登录的页面访问if (!to.meta.user) {return}// 已登录可进入if (store.getters.token) {return true}// 未登录警告然后返回首页message(warn, 登录失效请重新登录!)return / })15: 总结 在本篇文章中我们接触到了两个新的通用组件 1. input 2. dialog 除此之外我们还接触到了头像裁剪、OSS、COS 的概念。这些概念可能对有些同学而言会比较新奇。大家也可以自己申请一个对应的 OSS 或者 COS 的账号推荐 COS。走一遍完整的流程这样大家会对这个操作更加的熟悉。
http://www.dnsts.com.cn/news/161493.html

相关文章:

  • 黄石做网站公司室内装饰装修施工图集
  • 模版网站建设在谷歌上网站推广
  • 做我女朋友网站jsp网站开发目的及意义
  • 站点创建中小企业融资平台
  • 中国建设银银行招聘网站wordpress主页乱码
  • 建设类似衣联网的网站怎么做不花钱的网站
  • 嘉兴网站设计999 999长湖南营销型网站
  • 自己建站的网站织梦珠宝网站模板
  • 网站网上预定功能怎么做增加wordpress阅读量
  • 网站续费后还是无法访问wordpress 导出 word
  • 网站排名推广一般网站的后台
  • 网站 申请太原网站制作企业
  • 九网互联怎么建设网站昆明网站推广价格
  • 网站设计的资质叫什么seo的主要分析工具
  • 医院网站建设情况网页设计教程孟宪宁
  • 外贸建站推广公司有了域名怎么制作网站
  • 网站开发人员的 生活做互联网一个月挣多少钱
  • 搜索引擎主题网站模板网站没有服务器可以吗
  • 购买网站域名多少钱wordpress自动加载
  • 做推广的网站wechat in wordpress
  • 手机建行网站数字广东网络建设有限公司官网
  • 酒类网站建苏州网站建设设计公司
  • 烟台专业做网站公司有哪些WordPress 302重定向
  • 宁波高新区做网站的公司个人网站可以做音乐吗
  • 怎么申请 免费网站高中生做那个的网站
  • 深圳网站建设选哪家好无锡 网站开发
  • 网站制作手机版商洛做网站
  • 携程旅行的网站建设可以做ppt的网站有哪些方面
  • 北京高端网站开发外包公司和劳务派遣哪个好一点
  • 上虞市建设风机厂网站dede我的网站