问题
写了一个输入查询参数和url
返回加载中状态、请求方法、接口返回列表的hooks
,出现的结果是只有请求方法有效,加载状态无效,接口返回了数据,页面却不显示数据。
代码如下
只展示部分关键代码
vue
import { ref, toRefs, toRef, onMounted, onActivated, reactive } from 'vue';
import baseService from '@/service/baseService';
export default (props) => {
const defaultOptions = {
getListURL: '',
dataForm: {},
loading: false,
dataList: []
};
const state = ref({ ...defaultOptions, ...props });
const fetchList = () => {
if (!state.value.getListURL) {
return;
}
state.value.loading = true;
baseService
.get(state.value.getListURL, { ...state.value.dataForm })
.then((res) => {
if (res.code === 0) {
state.value.dataList = [...res.data ];
}
})
.finally(() => {
state.value.loading = false;
});
};
onMounted(() => {
fetchList();
});
return {
fetchList,
dataList: state.value.dataList,
loading: state.value.loading,
};
};
页面使用
vue
<el-row :gutter="20" v-loading="loading">
<el-col :span="12" v-for="item in dataList" :key="item.id">
<div class="item">
{{ item.name }}
</div>
</el-col>
</el-row>
const params = ref({
name: '', // 搜索框名称
});
const { loading, fetchList, dataList } = useDataList({
dataForm: params.value,
getListURL: '/page/list',
});
分析
好久没用vue3
,写出来的代码让自己一时找不出来问题,唉。。。
第一次尝试
在使用文件下面打印列表查看一下
vue
const { loading, fetchList, dataList } = useDataList({
dataForm: params.value,
getListURL: '/page/list',
});
console.log(dataList);
是Proxy包裹的空数组,这应该是响应的数据,不像解构赋值出现的响应丢失啊。
为防止真的是这个问题,在hooks
导出时使用toRefs
包裹一下看看
vue
import { ref, toRefs, toRef, onMounted, onActivated, reactive } from 'vue';
import baseService from '@/service/baseService';
export default (props) => {
const defaultOptions = {
getListURL: '',
dataForm: {},
loading: false,
dataList: []
};
const state = ref({ ...defaultOptions, ...props });
const fetchList = () => {
if (!state.value.getListURL) {
return;
}
state.value.loading = true;
baseService
.get(state.value.getListURL, { ...state.value.dataForm })
.then((res) => {
if (res.code === 0) {
state.value.dataList = [...res.data ];
}
})
.finally(() => {
state.value.loading = false;
});
};
onMounted(() => {
fetchList();
});
return {
fetchList,
...toRefs({
dataList: state.value.dataList,
loading: state.value.loading,
})
};
};
这下真好,打印的是ObjectRefImpl
,然而查看里面看到还是空数组。
第二次尝试
接口响应里面有问题吗?那就在接口成功里面打印一下试试看
import { ref, toRefs, toRef, onMounted, onActivated, reactive } from 'vue';
import baseService from '@/service/baseService';
export default (props) => {
const defaultOptions = {
getListURL: '',
dataForm: {},
loading: false,
dataList: []
};
const state = ref({ ...defaultOptions, ...props });
const fetchList = () => {
if (!state.value.getListURL) {
return;
}
state.value.loading = true;
baseService
.get(state.value.getListURL, { ...state.value.dataForm })
.then((res) => {
if (res.code === 0) {
state.value.dataList = [...res.data ];
console.log(state.value.dataList);
}
})
.finally(() => {
state.value.loading = false;
});
};
onMounted(() => {
fetchList();
});
return {
fetchList,
dataList: state.value.dataList,
loading: state.value.loading,
};
};
发现这里打印是有数据的,那在hooks方法里面返回前打印看看
import { ref, toRefs, toRef, onMounted, onActivated, reactive } from 'vue';
import baseService from '@/service/baseService';
export default (props) => {
const defaultOptions = {
getListURL: '',
dataForm: {},
loading: false,
dataList: []
};
const state = ref({ ...defaultOptions, ...props });
const fetchList = () => {
if (!state.value.getListURL) {
return;
}
state.value.loading = true;
baseService
.get(state.value.getListURL, { ...state.value.dataForm })
.then((res) => {
if (res.code === 0) {
state.value.dataList = [...res.data ];
}
})
.finally(() => {
state.value.loading = false;
});
};
onMounted(() => {
fetchList();
});
console.log(state.value.dataList);
return {
fetchList,
dataList: state.value.dataList,
loading: state.value.loading,
};
};
啊?这里也是空对象,看来问题还是出现在hooks
里面啊。直接打印state
看看吧(应该上一次打印,这两个都打印试试的)
import { ref, toRefs, toRef, onMounted, onActivated, reactive } from 'vue';
import baseService from '@/service/baseService';
export default (props) => {
const defaultOptions = {
getListURL: '',
dataForm: {},
loading: false,
dataList: []
};
const state = ref({ ...defaultOptions, ...props });
const fetchList = () => {
if (!state.value.getListURL) {
return;
}
state.value.loading = true;
baseService
.get(state.value.getListURL, { ...state.value.dataForm })
.then((res) => {
if (res.code === 0) {
state.value.dataList = [...res.data ];
}
})
.finally(() => {
state.value.loading = false;
});
};
onMounted(() => {
fetchList();
});
console.log(state.value.dataList);
console.log(state);
return {
fetchList,
dataList: state.value.dataList,
loading: state.value.loading,
};
};
此时可以看到state里面是有接口返回的数据的,这样应该就说明不能使用.value
获取之后返回使用,这时候的数据是接口响应前的。
那就改造一下直接返回ref
(reactive
的数据结构赋值之后是响应丢失的)
import { ref, toRefs, toRef, onMounted, onActivated, reactive } from 'vue';
import baseService from '@/service/baseService';
export default (props) => {
const defaultOptions = {
getListURL: '',
dataForm: {},
};
const state = ref({ ...defaultOptions, ...props });
const loading = ref(false);
const dataList = ref({});
const fetchList = () => {
if (!state.value.getListURL) {
return;
}
loading.value = true;
baseService
.get(state.value.getListURL, { ...state.value.dataForm })
.then((res) => {
if (res.code === 0) {
dataList.value = [...res.data ];
}
})
.finally(() => {
loading.value = false;
});
};
onMounted(() => {
fetchList();
});
return {
fetchList,
dataList,
loading,
};
};
<el-row :gutter="20" v-loading="loading.value">
<el-col :span="12" v-for="item in dataList.value" :key="item.id">
<div class="item">
{{ item.name }}
</div>
</el-col>
</el-row>
const params = ref({
name: '', // 搜索框名称
});
const { loading, fetchList, dataList } = useDataList({
dataForm: params.value,
getListURL: '/page/list',
});
但是这是为什么,还是有问题啊?崩溃啊!
第三次尝试
在使用里面打印一下
<el-row :gutter="20" v-loading="loading.value">
<el-col :span="12" v-for="item in dataList.value" :key="item.id">
<div class="item">
{{ item.name }}
</div>
</el-col>
</el-row>
const params = ref({
name: '', // 搜索框名称
});
const { loading, fetchList, dataList } = useDataList({
dataForm: params.value,
getListURL: '/page/list',
});
console.log(dataList)
发现数据已经更新到接口返回的了,怎么页面没反应呢?额。。。好像页面模版里面可以省略.value
,修改一下看看
<el-row :gutter="20" v-loading="loading">
<el-col :span="12" v-for="item in dataList" :key="item.id">
<div class="item">
{{ item.name }}
</div>
</el-col>
</el-row>
const params = ref({
name: '', // 搜索框名称
});
const { loading, fetchList, dataList } = useDataList({
dataForm: params.value,
getListURL: '/page/list',
});
console.log(dataList)
撒花,终于解决完问题了(刚才不手欠加个.value
,就不用耽误一次修改了)
结尾
- 自定义
hooks
,要想返回响应式ref
数据,不要使用.value
转一层,直接返回ref
数据。 - 模板里面使用
ref
数据时候,不要加.value
彩蛋
使用css
实现多行超出显示...无效
超出一行没换行
有的换行,但是超出没显示...
css
overflow:hidden;
text-overflow:ellipsis;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
这可能是英文文字太长导致的,这需要加上强制换行的css
就可以
css
word-break: break-all;
