首页
友链
导航
影视
壁纸
统计
留言板
Search
1
el-upload自定义触发按钮及触发上传前判断
869 阅读
2
vue配置二级目录以及nginx多网站部署
705 阅读
3
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
585 阅读
4
joe主题自定义导航页面
541 阅读
5
js获取昨天今天明天日期
485 阅读
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
登录
Search
标签搜索
web
vue
node项目实战
js
javascript
typecho
css
vuex
router
nginx
git
element
joe
utils
leaflet
dateFormat
map
date
axios
reg
辰漪
累计撰写
66
篇文章
累计收到
122
条评论
首页
栏目
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
页面
友链
导航
影视
壁纸
统计
留言板
搜索到
13
篇与
vue
的结果
2022-09-23
vue.draggable可拖动组件使用方法
安装方式npm install -S vuedraggable全局组件注册import Vue from 'vue'; import Draggable from 'vuedraggable' Vue.component('Draggable', Draggable)局部组件注册<script> import Draggable from 'vuedraggable' export default { data() { return {} }, components: { Draggable } } <script>基础使用使用Draggable包裹,使用animation属性设置过渡效果<template> <Draggable v-model="list" animation="300" > <transition-group> <div v-for="item in list" :key="item.id" class="drag-item"> {{ item.name }} </div> </transition-group> </Draggable> </template> <script> export default { data() { return { list: [ { name: 'zs', age: 18, id: 1 }, { name: 'lisi', age: 20, id: 2 }, { name: 'wangwu', age: 19, id: 3 } ] } } } </script>鼠标在指定元素上才允许拖动通过handle定义可拖动元素的样式名称<template> <Draggable v-model="list" animation="300" handle=".move-drag" > <transition-group> <div v-for="item in list" :key="item.id" class="drag-item"> <i class="el-icon-rank move-drag" /> {{ item.name }} </div> </transition-group> </Draggable> </template> <script> export default { data() { return { list: [ { name: 'zs', age: 18, id: 1 }, { name: 'lisi', age: 20, id: 2 }, { name: 'wangwu', age: 19, id: 3 } ] } } } </script>不允许拖动的元素filter属性定义不可拖动元素的样式名称,该元素则不可拖动,通过move事件,禁止其他元素拖动到它这一行<template> <Draggable v-model="list" animation="300" handle=".move-drag" filter=".forbid" :move="filterMove" > <transition-group> <div v-for="item in list" :key="item.id" class="drag-item" :class="{forbid: item.id === 1}" > <i class="el-icon-rank move-drag" /> {{ item.name }} </div> </transition-group> </Draggable> </template> <script> export default { data() { return { list: [ { name: 'zs(不允许停靠和拖拽)', age: 18, id: 1 }, { name: 'lisi', age: 20, id: 2 }, { name: 'wangwu', age: 19, id: 3 } ] } }, methods: { // 禁止拖动到id为1的那一行 filterMove(e) { console.log(e.relatedContext.element.id, '禁止拖动的id') if (e.relatedContext.element.id == 1) return false return true } } } </script>设置选中样式 和 目标位置的样式chosenClass属性用来设置选中时的样式,ghostClass属性用来设置目标位置的样式<template> <Draggable v-model="list" animation="300" handle=".move-drag" filter=".forbid" :move="filterMove" chosen-class="chose" ghost-class="ghost" > <transition-group> <div v-for="item in list" :key="item.id" class="drag-item" :class="{forbid: item.id === 1}" > <i class="el-icon-rank move-drag" /> {{ item.name }} </div> </transition-group> </Draggable> </template> <script> export default { data() { return { list: [ { name: 'zs(不允许停靠和拖拽)', age: 18, id: 1 }, { name: 'lisi', age: 20, id: 2 }, { name: 'wangwu', age: 19, id: 3 } ] } }, methods: { // 禁止拖动到id为1的那一行 filterMove(e) { console.log(e.relatedContext.element.id, '禁止拖动的id') if (e.relatedContext.element.id == 1) return false return true } } } </script> <style lang="scss" scoped> .drag-item { &.chose { background: skyblue; color: #fff; } &.ghost { background: pink; } } </style>
2022年09月23日
214 阅读
0 评论
2 点赞
2022-09-23
el-select下拉树的实现
el-select实现下拉树// template<el-select ref="el-select-ref" v-model="form.pid" @change="selectChange" @visible-change="showSelectTree" @clear="clearSelectTree" > <!-- 添加一个option选项 使用hidden隐藏 value是下拉选中的值,label是显示的名称 --> <el-option key="id" hidden :value="form.pid" :label="form.pidName" /> <el-tree ref="el-select-tree" :data="treeData" :props="defaultProps" node-key="menuId" highlight-current default-expand-all :expand-on-click-node="false" @node-click="handleNodeClick" /> </el-select>// script<script> export default { data() { return { tableData: [{ "menuId": 8, "pid": 0, "name": "系统管理", "children": [ { "menuId": 3, "pid": 8, "name": "用户管理", "children": [ { "menuId": 4, "pid": 3, "name": "用户列表", "children": [] }, { "menuId": 9, "pid": 3, "name": "用户添加", "children": [] }, { "menuId": 10, "pid": 3, "name": "用户编辑", "children": [] }, { "menuId": 11, "pid": 3, "name": "用户删除", "children": [] } ] }, { "menuId": 12, "pid": 8, "name": "角色管理", "children": [ { "menuId": 17, "pid": 12, "name": "角色列表", "children": [] }, { "menuId": 18, "pid": 12, "name": "角添加色", "children": [] }, { "menuId": 19, "pid": 12, "name": "编辑角色", "children": [] }, { "menuId": 20, "pid": 12, "name": "删除角色", "children": [] } ] }, { "menuId": 7, "pid": 8, "name": "字典管理", "children": [] }, { "menuId": 2, "pid": 8, "name": "菜单管理", "children": [ { "menuId": 13, "pid": 2, "name": "菜单列表", "children": [] }, { "menuId": 14, "pid": 2, "name": "添加菜单", "children": [] }, { "menuId": 15, "pid": 2, "name": "编辑菜单", "children": [] }, { "menuId": 16, "pid": 2, "name": "删除菜单", "children": [] } ] }, { "menuId": 21, "pid": 8, "name": "聚合图床", "icon": "tree", "children": [] } ] }], form: { pid: 0, pidName: '根目录' }, defaultProps: { children: 'children', label: 'name' } } }, methods: { showSelectTree(bool) { // el-select下拉框显示或隐藏触发 // 设置当前绑定的tree节点高亮 if (bool) this.$refs['el-select-tree'].setCurrentKey(this.form.pid) }, handleNodeClick(data, node, nodeRef) { // 点击tree下拉节点 // console.log(data, node, nodeRef) this.form.pid = data.menuId // 设置el-select绑定的value this.form.pidName = data.name // 设置el-select绑定的lable this.$refs['el-select-ref'].handleClose() // 关闭el-select下拉框 // this.$set(this.form, 'pid', data.menuId) }, clearSelectTree() { // 清空el-select触发 需要给el-select添加 clearable属性 this.form.pidName = '' this.$refs['el-select-tree'].setCurrentKey(null) }, } } </script>实现效果展示如需封装成组件,可以自行进行封装,这里就不再进行组件封装
2022年09月23日
28 阅读
0 评论
1 点赞
2022-05-06
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
1. 问题如图单选按钮点击后,没有进行懒加载,直接显示空数据2. 解决给el-cascader绑定change事件,手动调用lazyLoad方法<!-- 选择文件夹 --> <el-dialog title="选择文件夹" :visible.sync="dialogVisible" width="30%" append-to-body > <div class="" v-if="dialogVisible"> <span>文件夹:</span> <el-cascader class="cyupload-cascader" ref="folder-cascader-ref" :props="props" :show-all-levels="false" @change="change" clearable > </el-cascader> </div> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="sureBtn">确 定</el-button> </span> </el-dialog>// 级联状态变化 change (val) { // console.log(val); console.log(this.$refs['folder-cascader-ref'], 'ref'); this.folderId = val[val.length - 1] // this.$refs['folder-cascader-ref'].dropDownVisible = false // 关闭面板 const selectNode = this.$refs['folder-cascader-ref'].getCheckedNodes()[0] // node节点 if (selectNode && !selectNode.loaded) this.$refs['folder-cascader-ref'].$refs['panel'].lazyLoad(selectNode) // 选中加载 },3. 成功效果图
2022年05月06日
585 阅读
0 评论
1 点赞
2022-04-08
后端数据大数字精度缺失问题
1. 使用json-bigintnpm i json-bigint2. 如何使用import axios from 'axios' import jsonBig from 'json-bigint' // create an axios instance const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5 * 1000, // request timeout // 在响应数据前处理该数据 transformResponse: [function (data) { try { // 如果转换成功则返回转换的数据结果,会将大数字转换为bigint console.log(jsonBig.parse(data), 888); return jsonBig.parse(data) } catch (err) { // 如果转换失败,则包装为统一数据格式并返回 return { data } } }] })2. 使用时,将该字段转换为字符串res.data.pid.toString() // 4125411516516488
2022年04月08日
76 阅读
0 评论
0 点赞
2022-04-07
el-input type="number" 去掉上下箭头
先来看一下原图,会有一个上下箭头::v-deep input { &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { -webkit-appearance: none !important; } }去掉之后
2022年04月07日
372 阅读
0 评论
0 点赞
2022-03-22
如何在vue中优雅的使用svg
1. svg-sprite-loadernpm install svg-sprite-loader --save2. 在src中新建文件夹iconsicons/svg 存放svg图标icons/index.js 全局注册svg组件,导入所有svg图标// icons/index.js import Vue from 'vue' import SvgIcon from '@/components/SvgIcon/index.vue'// svg component // register globally Vue.component('SvgIcon', SvgIcon) const req = require.context('./svg', false, /\.svg$/) const requireAll = requireContext => requireContext.keys().map(requireContext) requireAll(req)3. 创建svg组件// src/components/ScgIcon/index.vue <template> <svg :class="svgClass" aria-hidden="true" v-on="$listeners"> <use :xlink:href="iconName" /> </svg> </template> <script> export default { name: 'SvgIcon', props: { iconClass: { type: String, required: true }, className: { type: String, default: '' } }, computed: { iconName () { return `#icon-${this.iconClass}` }, svgClass () { if (this.className) { return 'svg-icon ' + this.className } else { return 'svg-icon' } } } } </script> <style scoped> .svg-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } </style> 4. 在vue.config.js中使用loaderconst path = require('path') function resolve (dir) { return path.join(__dirname, dir) } module.exports = { devServer: { port: 8080, open: true }, chainWebpack (config) { // set svg-sprite-loader config.module .rule('svg') .exclude.add(resolve('src/icons')) .end() config.module .rule('icons') .test(/\.svg$/) .include.add(resolve('src/icons')) .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end() } }5. 在main.js中导入icons/index.js// main.js import '@/icons/index' // svg6. 在页面中使用组件<SvgIcon iconClass="eye-open"></SvgIcon>直接使用svg文件名作为iconClass
2022年03月22日
369 阅读
1 评论
0 点赞
2022-03-11
el-upload自定义触发按钮及触发上传前判断
1. 在页面中引用el-upload组件<!-- 自定义按钮div --> <div v-if="routerList.length !== 1" class="action upload" :class="{action_upload_radius: routerList.length === 1}" @click="uploadHandler" > <i class="el-icon el-icon-upload"></i>上传 </div> <!-- hidden upload --> <el-upload v-show="false" class="upload-demo" :action="uploadUrl" :on-success="actionUploadSucc" :show-file-list="false" :headers="headers" :data="actUploadParams" :multiple="false" :file-list="fileList"> <el-button ref="file-home-uploadBtnRef" v-show="false"> <i class="el-icon-upload"></i>上传文件 </el-button> </el-upload>使用一个div模拟一个上传按钮,使用v-show隐藏upload组件,在upload组件的触发按钮el-button上绑定ref2. 触发前条件判断及触发upload上传方式 // action bar 上传btn uploadHandler () { console.log(this.routerList); const len = this.routerList.length if(this.routerList.length === 1) return this.$message.info('请先进入文件夹!') const currFolderId = this.routerList[len-1].folderId // 当前操作的文件夹id this.actUploadParams.folderId = currFolderId // 触发upload组件上传 this.$refs['file-home-uploadBtnRef'].$el.click() },获取到upload触发按钮el-button的ref,在获取到ref上的$el,调用click()自点击触发upload上传
2022年03月11日
869 阅读
3 评论
3 点赞
2022-01-10
移动端适配(rem)
1. postcss-pxtorem该插件可以将项目中的px值转化为rem,注意:行内样式不会转化npm install postcss-pxtorem -D在项目根目录创建文件 .postcssrc.js 或 postcss.config.js// postcss.config.js module.exports = { plugins: { // 用到的插件都配置在这里 'postcss-pxtorem': { rootValue: 37.5, // 1rem = 37.5px rem基准值 750设计稿就改为 75 propList: ['*'], // 配置要转换的css属性 * 表示所有属性 }, }, }; module.exports = { plugins: { // postcss-pxtorem 插件的版本需要 >= 5.0.0 'postcss-pxtorem': { rootValue({ file }) { // Vant中是根据375来写 如果我们的不是,就需要使用 函数的形式做判断 return file.indexOf('vant') !== -1 ? 37.5 : 75; }, propList: ['*'], }, }, };2. lib-flexible该插件可以根据屏幕动态的设置html的font-size大小默认会将屏幕分成十份,然后给html的font-size, 比如屏幕宽度 750px 那么html的font-size就是 75px1rem = 75pxnpm install lib-flexible// 在main.js中导入 import 'amfe-flexible'
2022年01月10日
95 阅读
0 评论
2 点赞
2021-12-23
使用require.context()函数实现自动化导入
require.context()该函数接收三个参数directory {String} -读取文件的路径useSubdirectories {Boolean} -是否遍历文件的子目录regExp {RegExp} -匹配文件的正则该函数执行后会返回一个函数,包含三个属性resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径keys {Function} -返回匹配成功模块的名字组成的数组id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载实际应用场景vuex的module模块批量自动化导入const files = require.context('./modules', false, /\.js$/) // 导入modules目录下所有的js文件 const modules = {} // 所有的store模块 // files.keys() 拿到 ['./account.js', './log.js']组成的数组 // 使用replace将./和.js替换为空,当做键名 files(key).default当做键值 files.keys().forEach(key => { //files(key).default 可以拿到每一个模块 modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default }) export default { namespaced: true, modules }
2021年12月23日
320 阅读
2 评论
1 点赞
2021-12-22
封装localStorage本地存储
封装本地存储是为了更好更方便的实现本地存储,简洁明了实现本地存储的步骤1. 首先创建枚举列表,用来记录本地存储的键,可以清楚地知道,你本地都存了啥// storageEnum枚举列表 const storageEnum = { user: ['user', '用户'], // key:简写名称 value array[0]: 本地存储的键名, array[1]:描述是干嘛的 userToken: ['user::access_token', '用户token'], userInfo: ['sc_selfInfo', '用户信息'], cart: ['cart', 'cart购物车'], } module.exports = storageEnum2. 定义枚举工具/** * 枚举定义工具 * 示例: * const AA = createEnum({ * b: [1, '审核中'], * C: [2, '审核通过'] * }) * 获取枚举值:AA.b * 获取枚举描述:AA.getDesc('b') * 通过枚举值获取描述:AA.getDescFromValue(AA.b) * */ export function createEnum(definition) { const strToValueMap = {} const numToDescMap = {} for (const enumName of Object.keys(definition)) { const [value, desc] = definition[enumName] strToValueMap[enumName] = value numToDescMap[value] = desc } return { ...strToValueMap, getDesc(enumName) { return (definition[enumName] && definition[enumName][1]) || '' }, getDescFromValue(value) { return numToDescMap[value] || '' } } }3. 封装本地存储方法/* * @param param {Object} key值为 method name data */ Vue.prototype.$storageEnum = (param) => { let that = this; let { method, // get / set name, // 存储storageEnum的键名简写 data // 要存储的数据 } = param let storagelist = createEnum(storageEnum) let storageAction = new Map() .set('set', () => { uni.setStorageSync(storagelist[name], data) }) .set('get', () => { return uni.getStorageSync(storagelist[name]); }) try { return storageAction.get(method)(); } catch (e) { uni.showToast({ icon: 'none', title: `<${name}>缓存,使用错误请检查!` }); } }4. 使用this.$storageEnum({ method: 'set', name: 'userInfo', data: { username: 'zs', age: 18 } })
2021年12月22日
269 阅读
0 评论
1 点赞
1
2