如何 return 来自 Promise 的字符串
How to return string from a Promise
我在一个使用 vue 的网站上工作,我必须从服务器获取带有 axios 的图像并将它们作为 div 的背景图像。情况是我有 urls 但不是所有的都是正确的。所以我正在尝试制作一个发出 http 请求的函数,如果该请求成功,returns 我 url。
我想到了这样的事情:
模板:
<div class="element" :style="bgImg(url)"/>
脚本:
methods: {
bgImg(url) {
axios.get(url)
.then(response => {
return `background-image: url(${response.config.url})`;
})
.cath(e) {
throw new Error(e);
}
}
}
我期待从该函数返回 url,但没有任何反应。
You should use setAttribute method.
//add id to the element
<div id="element" class="element" />
var url = url(${response.config.url});
// select the element using id and set image
document.getElementById("element").setAttribute("style", "background-image:"+ url);
而不是从 then() 回调返回(它将块的结果传递给下一个 then()),您可以存储您从响应对象中寻找的数据以在承诺之外使用.
使用计算值或临时值,这样会更容易。
在此解决方案中,您将设置一个占位符图像以在加载时显示(或留空)。
然后使用一个mounted()
钩子加载数据,然后赋值给样式
模板:
<div class="element" :style="imgStyle"/>
脚本:
data:{
return () => {
imgStyle: {
'background-image': 'url(my-placeholder.png)' // or not included at all
}
}
},
mounted() {
axios.get(url)
.then(response => {
this.$set(this.imgStyle, 'background-image', `url(${response.config.url})`);
})
.cath(e) {
throw new Error(e);
}
}
作为旁注,请尽量远离模板中用于显示值的函数,这些函数可以使用计算完成。
您可以使用 custom vue directive 来完成这项工作:
Vue.directive('validate-bgimg', function (el, binding) {
el.style.backgroundImage = null // reset
var url = binding.value
if (!url) {
return
}
axios.get(`https://cors-anywhere.herokuapp.com/${url}`) // get around CORS limitations. Idealy you should call your own api to validate image urls
.then(response => {
if (response.status != 200) {
console.warn("Invalide image url", url, response)
} else {
el.style.backgroundImage = `url(${url})`
}
})
.catch(e => {
console.error("Could not validate image", url, e)
})
})
new Vue({
el: "#app",
data: {
imgUrl: undefined
}
})
#app {
background: lightgray;
border-radius: 4px;
padding: 20px;
margin: 20px;
transition: all 0.2s;
}
.element {
margin: 8px 0;
width: 200px;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<b>test case:</b>
<button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+1'">1</button>
<button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+2'">2</button>
<button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+3'">3</button>
<button @click="imgUrl='https://httpbin.org/status/404'">HTTP 404</button>
<button @click="imgUrl='https://httpbin.org/status/503'">HTTP 503</button>
<button @click="imgUrl='https://invalid.tld'">cannot resolve domain name</button>
<div class="element" v-validate-bgimg="imgUrl"/>
</div>
我在一个使用 vue 的网站上工作,我必须从服务器获取带有 axios 的图像并将它们作为 div 的背景图像。情况是我有 urls 但不是所有的都是正确的。所以我正在尝试制作一个发出 http 请求的函数,如果该请求成功,returns 我 url。
我想到了这样的事情:
模板:
<div class="element" :style="bgImg(url)"/>
脚本:
methods: {
bgImg(url) {
axios.get(url)
.then(response => {
return `background-image: url(${response.config.url})`;
})
.cath(e) {
throw new Error(e);
}
}
}
我期待从该函数返回 url,但没有任何反应。
You should use setAttribute method.
//add id to the element
<div id="element" class="element" />
var url = url(${response.config.url});
// select the element using id and set image
document.getElementById("element").setAttribute("style", "background-image:"+ url);
而不是从 then() 回调返回(它将块的结果传递给下一个 then()),您可以存储您从响应对象中寻找的数据以在承诺之外使用.
使用计算值或临时值,这样会更容易。
在此解决方案中,您将设置一个占位符图像以在加载时显示(或留空)。
然后使用一个mounted()
钩子加载数据,然后赋值给样式
模板:
<div class="element" :style="imgStyle"/>
脚本:
data:{
return () => {
imgStyle: {
'background-image': 'url(my-placeholder.png)' // or not included at all
}
}
},
mounted() {
axios.get(url)
.then(response => {
this.$set(this.imgStyle, 'background-image', `url(${response.config.url})`);
})
.cath(e) {
throw new Error(e);
}
}
作为旁注,请尽量远离模板中用于显示值的函数,这些函数可以使用计算完成。
您可以使用 custom vue directive 来完成这项工作:
Vue.directive('validate-bgimg', function (el, binding) {
el.style.backgroundImage = null // reset
var url = binding.value
if (!url) {
return
}
axios.get(`https://cors-anywhere.herokuapp.com/${url}`) // get around CORS limitations. Idealy you should call your own api to validate image urls
.then(response => {
if (response.status != 200) {
console.warn("Invalide image url", url, response)
} else {
el.style.backgroundImage = `url(${url})`
}
})
.catch(e => {
console.error("Could not validate image", url, e)
})
})
new Vue({
el: "#app",
data: {
imgUrl: undefined
}
})
#app {
background: lightgray;
border-radius: 4px;
padding: 20px;
margin: 20px;
transition: all 0.2s;
}
.element {
margin: 8px 0;
width: 200px;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<b>test case:</b>
<button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+1'">1</button>
<button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+2'">2</button>
<button @click="imgUrl='https://dummyimage.com/200x200/000/fff.gif&text=test+3'">3</button>
<button @click="imgUrl='https://httpbin.org/status/404'">HTTP 404</button>
<button @click="imgUrl='https://httpbin.org/status/503'">HTTP 503</button>
<button @click="imgUrl='https://invalid.tld'">cannot resolve domain name</button>
<div class="element" v-validate-bgimg="imgUrl"/>
</div>