- 使用ref本质原因:
- 在 JavaScript 中,Number 、String 、Boolean等基本类型是在方法(函数)里面通过值而非引用传递,故不可以修改。
-
使用uni-app的uni-icons组件无法添加监听事件。
-
深度选择器:
示例:
.sltree为自己所定义的类;.ly-tree-node > span:last-child为官方组件的类名。故修改官方组件的样式时,一般需要使用深度选择器。 -
父组件调用子组件里面的方法: 详解:关于父组件调用子组件里面的方法
-
接口的二次封装:
-
路径传参后:参数类型会自动变为string。
-
修改element UI组件样式不生效:
解决方法:
查看DOM结构
- 若所使用组件位于APP组件之内
通过/deep/等穿透方法修改其样式 - 若所使用组件独立于APP组件之外
通过重新写style的方法修改其样式
示例:👉参考资料
-
使用element UI组件时,在子组件里调用父组件传入的方法去修改prop出现反模式的问题:使用组件的属性进行解决,例如:el-dialog(before-close)。
-
upload组件自定义上传逻辑:http-request(返回值可为一个promise)👉参考资料
-
如何监听props:若props为字符串则直接使用watch监听即可;若props为对象,则在使用watch监听时要加上immediate和deep(true)属性。 👉参考资料一 👉参考资料二
注意事项:vue监听多个props且渲染需要多个props满足不同的条件,则可以采用以下方法进行监听。
-
若需要在多个模块分别加上v-if、v-else时,模块出现渲染不及时或者重复的问题:
解决方法:可以通过给不同的模块绑定一个key值用于在创建或者销毁时确定其唯一性。
//自定义上传进度条
//canceltokenStore.js
const state = {
// file_id: '',
// source_token: '',
fileCancelTokenList: []
}
const mutations = {
// 当执行一个axios的post请求时, 存入该文件的file_id和对应的source_token,维护一个全局变量
UPDATE_FILE_CANCEL_TOKEN: (state, { file_id, source_token }) => {
state.fileCancelTokenList.push({ file_id, source_token })
},
// 执行完取消操作后, 删除缓存中的token, 避免冗余
DELETE_FILE_CANCEL_TOKEN: (
state, file_id) => {
if (file_id) {
state.fileCancelTokenList = state.fileCancelTokenList.filter((file) => file.file_id !== file_id)
}
}
}
export default {
namespaced: true,
state,
mutations
}
//filemgtApi.js
export function uploadFileList(data, uploadProgressFn, cancelToken) {
return request({
url: '/file/fileFolder/uploadFile',
method: 'post',
data: data,
headers: {
'showLoading': false
},
onUploadProgress: (process) => {
// console.log('process:', process)
uploadProgressFn(process)
},
cancelToken: cancelToken
})
}
//上传按钮
<el-row style="margin-top: 25px">
<el-col :span="24">
<el-upload
v-show="!nodeId && authFlag!==1 ? false : true"
:action="uploadAction"
:show-file-list="false"
:http-request="handleUpload"
:auto-upload="true"
>
<el-button size="small" type="primary">上传</el-button>
</el-upload>
</el-col>
<el-col v-if="showProgress" :span="24" style="margin: 20px 0px;display:flex;justify-content:flex-start;align-items: center;">
<el-progress :percentage="percentage" style="width:90%" />
<el-button v-if="percentage === 100" icon="el-icon-circle-check" type="text" />
<el-button v-else icon="el-icon-circle-close" type="text" @click="handleAbort" />
</el-col>
</el-row>
// 上传
async handleUpload (options) {
const file = options.file
const formData = new FormData()
this.cancelFileId = file.uid
this.showProgress = true
const uploadEvent = (progressEvent) => {
// console.log('progressEvent:', progressEvent)
this.percentage = Number(((progressEvent.loaded / progressEvent.total) * 100).toFixed(0))
}
formData.append('file', file)
formData.append('folderId', this.nodeId)
const CancelToken = axios.CancelToken
const source = CancelToken.source()
// console.log('CancelToken:', CancelToken)
// console.log('source:', source)
this.handleUpdateCancelToken(this.$store, file.uid, source)
try {
const res = await uploadFileList(formData, uploadEvent, source.token)
if (res.success) {
this.initialList()
this.$message({
message: '上传成功!',
type: 'success'
})
} else {
this.$message({
message: '上传失败!',
type: 'error'
})
this.showProgress = false
}
} catch (err) {
throw Error(err)
}
},
// 获取待取消文件
handleUpdateCancelToken(store, file_id, source_token) {
if (store) {
store.commit('canceltoken/UPDATE_FILE_CANCEL_TOKEN', { file_id, source_token })
}
},
// 取消上传
handleAbort() {
if (this.$store.state.canceltoken.fileCancelTokenList) {
const fileCancel = this.$store.state.canceltoken.fileCancelTokenList.find(file => file.file_id === this.cancelFileId)
const tokenCancel = fileCancel.source_token
if (tokenCancel) {
tokenCancel.cancel()
this.$store.commit('canceltoken/DELETE_FILE_CANCEL_TOKEN', this.cancelFileId)
this.showProgress = false
} else {
this.$message({
message: '未找到需要取消的文件!',
type: 'error'
})
}
}
},
- vue通过ref获取不到$refs问题:
- 原因一:在created中调用组件还未挂载,故this.$refs无法获取到对应的DOM节点。
- 原因二:在某个DOM节点中使用了v-if、v-show、v-for,而该DOM节点在mounted阶段不存在(在mounted阶段请求回来的数据不会更新到DOM中),故this. r e f s 无法获取到对应的 D O M 节点。解决方法:方法一:不在 m u n t e d 中获取元素,在 u p d a t e d 中获取。方法二:使用 refs无法获取到对应的DOM节点。 解决方法:方法一:不在munted中获取元素,在updated中获取。方法二:使用 refs无法获取到对应的DOM节点。解决方法:方法一:不在munted中获取元素,在updated中获取。方法二:使用nextTick。👉参考资料
- key为随机数能触发重新渲染而为传入的id等不能触发重新渲染的原因:
使用v-for时,若直接使用data里定义的数据源list同时list初始化值为[],并通过异步获取数据更新list时,此时若item.id作为循环体的key即:key="item.id"时,则当页面渲染时由于list的初始化值为[],因此拿到的key的值都为undefined,从而导致Vue 认为这些元素是“相同”的(即它们的 key 相同),又由于Vue 的就地复用策略(即Vue会尽可能的复用旧元素的 DOM 节点,而不是重新创建一个新的元素),故不会再重新替换渲染的组件/模块。若要解决该问题,则要保证使用动态key,所以无论是使用随机数(由于可能出现重复导致DOM结构混乱,故非必要不推荐)还是uuid这种都行,只要保证初始渲染时,key拿到的是不同值就行。(动态key:数据驱动的,即它的值依赖于数据的变化;静态key:指的是一个固定不变的值,通常是一个字符串字面量或者一个固定的变量。)
//使用静态key示例:
<template>
<div>
<component-a v-if="showA" key="a"></component-a>
<component-b v-else key="b"></component-b>
</div>
</template>
//使用动态key示例:
<template>
<div
v-for="(item, index) in list"
:key="item.id"
>
{{ item.text }}
</div>
</template>
-
啊这:
-
啊这:
-
啊这:
-
啊这: