vue使用pdf.js预览
If you have ever used online stores like Amazon or eBay, you have definitely used the preview feature. It shows you images or videos of the product so you know what to expect before making a purchase.
如果您曾经使用过像Amazon或eBay这样的在线商店,那么您肯定使用过预览功能。 它会向您显示产品的图像或视频,以便您在购买前知道会发生什么。
In this article, we are going to examine how to build a single page Amazon-like preview app with Vue.js
在本文中,我们将研究如何使用Vue.js构建类似于亚马逊的单页预览应用程序
![](https://d2mxuefqeaa7sj.cloudfront.net/s_1DF4F1277063AE6CFDF4F8C6116D4E99C9150C4457B73A977A01F3A4E69BA9F0_1517791174909_Screen+Shot+2018-02-05+at+1.37.01+AM.png)
What we will build won’t look exactly like the Amazon website, but will exhibit the product preview characteristics.
我们将构建的内容与Amazon网站看起来并不完全一样,但是将展示产品预览功能。
依存关系 ( Dependencies )
To build this app, we are going to use a Node server for the back-end and Vue.js for our front-end. Before we get to work, you need to verify that you have a couple of things installed on your machine:
要构建此应用程序,我们将在后端使用Node服务器,在前端使用Vue.js。 在开始工作之前,您需要验证计算机上已安装了几件东西:
建立前端 ( Building the Front-end )
We going to use Vue.js to build the front-end. Vue.js is a progressive JavaScript framework that is quick and easy to use.
我们将使用Vue.js来构建前端。 Vue.js是一个快速且易于使用的渐进式JavaScript框架。
Installing Vue.js
安装Vue.js
You are going to need Vue.js installed on your machine. You can confirm your installation by running:
您将需要在计算机上安装Vue.js。 您可以通过运行以下命令确认安装:
vue --version
If you get a version number as a result then you have Vue.js installed. If not, it is recommended that you install the Vue CLI by running:
如果得到版本号,则说明已安装Vue.js。 如果不是,建议您通过运行以下命令安装Vue CLI:
npm install --global vue-cli
To create the frontend
server, run the following :
要创建frontend
服务器,请运行以下命令:
mkdir preview-app
vue init webpack frontend
This creates a vue example project which we are now going to tweak and adjust.
这将创建一个vue示例项目,我们现在将对其进行调整和调整。
Installing The Node Modules
安装 节点模块
We are going to use axios
to make get
requests from one of our Vue.js components so install it by running the following in the frontend
directory:
我们将使用axios
从我们的Vue.js组件之一get
请求,因此可以通过在frontend
目录中运行以下命令进行安装:
cd frontend
npm install axios
Creating the Listing Component
创建清单组件
![Listing Component](https://d2mxuefqeaa7sj.cloudfront.net/s_9C103C9E48AE94D2479C548603A0CD527FF29C5290C5A332D3B288F8A4A75F2C_1517846873046_Screen+Shot+2018-02-05+at+3.07.11+PM.png)
This Listing component is responsible for showing all the products we have in the store and adding a link to the view for the product.
这个列表组件负责显示我们商店中所有的产品,并添加指向该产品视图的链接。
To create the Listing
component, we run the following :
要创建Listing
组件,我们运行以下命令:
touch Listing.vue
In the Listing.vue
, we need to first import the axios
module:
在Listing.vue
,我们需要首先导入axios
模块:
<script>
import axios from 'axios'
//...
And now we use the module to fetch the product listing :
现在,我们使用该模块来获取产品清单:
//...
export default {
name: 'Listing',
data () {
return {
products : []
}
},
mounted : function(){
axios.get('http://localhost:3128/products').
then( result => {
console.log( result );
this.products = result.data;
})
}
}
</script>
We can see above that once the component is mounted, we make a call to our back-end server to fetch the available products and then assign it to the product
data of the component.
我们可以在上面看到,一旦安装了组件,我们就会调用后端服务器以获取可用产品,然后将其分配给该组件的product
数据。
The template for the component looks like this :
该组件的模板如下所示:
<template>
<div class="listing container">
<div class="title" style="margin-bottom:40px;">
<h1>Products on Sale</h1>
</div>
<div class="row">
<div class="col-sm-2">
<h2>#</h2>
</div>
<div class="col-sm-8">
<h2>PRODUCT NAME</h2>
</div>
<div class="col-sm-2">
<h2>GO TO</h2>
</div>
</div>
<template v-for="product in products">
<div class="row" style="margin-bottom:20px;">
<div class="col-sm-2" >
<p>{{ product.id }}</p>
</div>
<div class="col-sm-8">
<p>{{ product.name }}</p>
</div>
<div class="col-sm-2">
<router-link :to="{path: '/product/'+product.id }">View Product</router-link>
</div>
</div>
</template>
</div>
</template>
In the template above, we list
out the products as divs and add an action button that takes you to the single product page itself.
在上面的模板中,我们list
了产品的申报单,并添加一个动作按钮,把你的单品页面本身。
Creating the Preview Component
创建预览组件
![Product Preview Component](https://d2mxuefqeaa7sj.cloudfront.net/s_9C103C9E48AE94D2479C548603A0CD527FF29C5290C5A332D3B288F8A4A75F2C_1517847386885_Screen+Shot+2018-02-05+at+4.15.34+PM.png)
![Product Preview Component](https://d2mxuefqeaa7sj.cloudfront.net/s_9C103C9E48AE94D2479C548603A0CD527FF29C5290C5A332D3B288F8A4A75F2C_1517847294401_Screen+Shot+2018-02-05+at+4.14.26+PM.png)
The Preview component is responsible for displaying data and images related to the selected product from the previous view. When the component is created, we make a get request to the backend server to fetch all the data for the particular id
and then display the media in the form of a carousel
on the right side of the screen.
预览组件负责显示与上一视图中所选产品相关的数据和图像。 创建组件后,我们向后端服务器发出get请求,以获取特定id
所有数据,然后以carousel
的形式在屏幕右侧显示媒体。
Create the Preview.``v``ue
file by running :
通过运行以下命令创建Preview.``v``ue
文件:
touch Preview.vue
In the Vue.js file, we first import the axios
module :
在Vue.js文件中,我们首先导入axios
模块:
<script>
import axios from 'axios'
//...
Now, we build the component :
现在,我们构建组件:
//...
export default {
name: 'Preview',
data () {
return {
media :[],
product_name : "",
product_desc : "",
product_price : ""
}
},
mounted : function(){
// now we get all the related infomation for the particular product id
axios.get(`http://localhost:3128/getProductInfo/${this.$route.params.id}`)
.then( res => {
this.media = res.data.media;
this.product_name = res.data.product_name;
this.product_desc = res.data.product_desc;
this.product_price = res.data.product_price;
})
},
methods : {
initializePlayer : function(){
console.log('here')
var cld = cloudinary.Cloudinary.new({ cloud_name: "og-tech", secure: true});
var demoplayer = cld.videoPlayer('video-player');
}
}
</script>
After the post request is made, the model is updated with the data that was returned as a JSON response on the back-end.
发出发布请求后,将使用后端作为JSON响应返回的数据更新模型。
Our view has a template that looks as follows :
我们的视图具有一个如下所示的模板:
<template>
<div class="preview">
<div class="row">
<div class="col-sm-6">
<!-- this part will contain the product info -->
<h1> {{ product_name }} </h1>
<div>
<p> {{ product_desc }} </p>
<p> Price : ${{ product_price }} </p>
</div>
</div>
<div class="col-sm-6">
<!-- this part will contain the images -->
<div id="demo" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ul class="carousel-indicators">
<template v-for="single_media in media">
<template v-if="single_media.id == 0">
<li data-target="#demo" v-bind:data-slide-to="single_media.id" class="active"></li>
</template>
<template v-else>
<li data-target="#demo" v-bind:data-slide-to="single_media.id"></li>
</template>
</template>
<!-- <li data-target="#demo" data-slide-to="0" class="active"></li>
<li data-target="#demo" data-slide-to="2"></li> -->
</ul>
<!-- The slideshow -->
<div class="carousel-inner">
<template v-for="single_media in media">
<template v-if="single_media.id == 0">
<div class="carousel-item active">
<template v-if="single_media.type == 'image'">
<img class="img-responsive single-image" v-bind:src="single_media.url"/>
</template>
<template v-else>
<video
id="video-player"
controls
class="single-image cld-video-player cld-video-player-skin-dark"
v-bind:data-cld-source="single_media.url"
>
</video>
</template>
</div>
</template>
<template v-else>
<div class="carousel-item">
<template v-if="single_media.type == 'image'">
<img class="img-responsive single-image" v-bind:src="single_media.url"/>
</template>
<template v-else>
<video
id="video-player"
controls
class="single-image cld-video-player cld-video-player-skin-dark"
v-bind:data-cld-source="single_media.url"
>
</video>
</template>
</div>
</template>
</template>
</div>
<!-- Left and right controls -->
<a class="carobbusel-control-prev" href="#demo" data-slide="prev">
<span class="carousel-control-prev-icon"></span>
</a>
<a class="carousel-control-next" href="#demo" data-slide="next" v-on:click="initializePlayer()">
<span class="carousel-control-next-icon"></span>
</a>
</div>
</div>
</div>
</div>
</template>
In the template above, what we want to achieve is to display the media for the particular product. If you take a look at when we built the component, we make a request to the backend and then send the response to the Vue component.
在上面的模板中,我们要实现的是显示特定产品的媒体。 如果您看一下构建组件的时间,我们会向后端发出请求,然后将响应发送到Vue组件。
We need to know if the media being displayed is an image or a video. So we check in the template;
我们需要知道正在显示的媒体是图像还是视频。 因此,我们签入模板;
//..<template v-if="single_media.type == 'image'">
<img class="img-responsive single-image" v-bind:src="single_media.url"/>
</template>
<template v-else>
<video
id="video-player"
controls
class="single-image cld-video-player cld-video-player-skin-dark"
v-bind:data-cld-source="single_media.url"
>
</video>
</template>
//..
If it has type
of image
, we display the image in the carousel but if type
is a video, we use the Cloudinary VIdeo Player to display the video. To initialize the video player, we add v-on:click
event to the >
button. Once the button is clicked, the video player is initialized with the video.
如果它具有of image
type
of image
则在轮播中显示图像,但如果type
是视频,则使用Cloudinary VIdeo Player来显示视频。 要初始化视频播放器,我们将v-on:click
事件添加到>
按钮。 单击按钮后,将使用视频初始化视频播放器。
PS: Cloudinary’s video player also playing videos by tags and playing playlists. You can read more about it here.
PS:Cloudinary的视频播放器还会按标签播放视频并播放播放列表。 您可以在此处了解更多信息。
The preview view has some scoped styling as follows :
预览视图具有一些范围如下的样式:
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
.carousel-inner{
height : 500px;
}
.carousel-item{
height : 100%;
}
.single-image{
width : 100%;
height: 100%;
object-fit : fill;
}
#demo{
margin-left: 30px;
margin-right: 30px;
}
</style>
链接组件 (Linking Components)
To allow for flow from one component to another, Vue has what is called the vue-router
. Open the frontend/src/router/index.js
file and edit it to look like this:
为了允许从一个组件流到另一个组件,Vue具有所谓的vue-router
。 打开frontend/src/router/index.js
文件并对其进行编辑,如下所示:
// frontent/src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Listing from '@/components/Listing'
import Preview from '@/components/Preview'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Listing',
component: Listing
},
{
path: '/product/:id',
name: 'Product',
component: Preview
}
]
})
This specifies the available routes for the application. Earlier on in the components, we used <router-link>
to move from the Listing
component to the Preview
component and this is the file that handles what you get. You can add a lot more options when creating routers. To read more about it, head over here.
这指定了应用程序的可用路由。 在组件的前面,我们使用<router-link>
从Listing
组件移动到Preview
组件,这是处理所获得内容的文件。 创建路由器时,您可以添加更多选项。 要了解更多信息,请前往此处 。
建立后端 ( Building the Back-end )
To build our back-end, we need to change directory to the root directory of our application and then install the node modules:
要构建后端,我们需要将目录更改为应用程序的根目录,然后安装节点模块:
cd preview-app
npm install cors express body-parser dotenv request connect-multiparty cloudinary
Once this is done, you have successfully installed all the modules necessary for you to build the project.
完成此操作后,您已成功安装了构建项目所需的所有模块。
Create a server.js file
创建 一个 server.js文件
Now we need to create a file that will contain the instructions for our server to work In your video-suggestion
directory,
现在,我们需要创建一个文件,其中包含有关服务器工作的说明。在您的video-suggestion
目录中,
touch server.js
This will be the start-up file that will be referenced when your server is running In your server.js file, you need to
这是服务器运行时将引用的启动文件。在server.js文件中,您需要
Import the node modules
导入节点模块
require('dotenv').config()
const cors = require('cors')
const express = require('express')
const bodyParser = require('body-parser')
const multipart = require('connect-multiparty')
const request = require('request')
const cloudinary = require('cloudinary')
//...
Once you have imported your node modules, you can then use them freely all through your script.
导入节点模块后,就可以在脚本中自由使用它们。
Create your express app
创建您的快递应用
Now we create our express app instance by adding the following to the server.js
现在,我们通过将以下内容添加到server.js
来创建快速应用程序实例
//...
const app = express()
//...
Load the middlewares
加载中间件
We load the middlewares in our server.js
by adding the following
通过添加以下内容,将中间件加载到server.js
//...
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const multipartMiddleware = multipart();
//...
Here, we set our app to use cors
. We also instructed the app the parse the requests in JSON format.
在这里,我们将应用程序设置为使用cors
。 我们还指示应用程序以JSON格式解析请求。
Configure the Cloudinary Client
配置Cloudinary客户端
We need to configure our cloudinary client using your CLOUD_NAME
, API_KEY
and API_SECRET
我们需要使用您的CLOUD_NAME
, API_KEY
和API_SECRET
配置我们的cloudinary客户端
//...
cloudinary.config({
cloud_name: 'CLOUDINARY_CLOUD_NAME',
api_key: 'CLOUDINARY_API_KEY',
api_secret: 'CLOUDINARY_API_SECRET'
});
//...
Once this is done, then we have successfully configured our Cloudinary client.
完成此操作后,我们便成功配置了Cloudinary客户端。
Create app routes
创建应用路线
Our back-end server is very simple, it’s an express web server with two major routes:
我们的后端服务器非常简单,它是具有两个主要途径的快速Web服务器:
/products
- Lists all the products available for sale./products
列出所有可出售的产品。/getProductInfo
- Returns data for the selected product./getProductInfo
返回所选产品的数据。
//...
app.get('/products', multipartMiddleware, function(req, res){
return res.json([
{id: '1', name: 'UltraLight Mechanical Keyboard'},
{id: '121', name: 'IPhone X'},
{id: '23', name: 'Tesla S'},
{id: '42', name: 'Work Shoes'}
]);
});
app.get('/getProductInfo/:id', multipartMiddleware, function(req, res){
console.log( req.params.id );
return res.json({
media: [
{
id: '0',
type: 'image',
url: 'https://static.pexels.com/photos/265631/pexels-photo-265631.jpeg'
},
[...]
{
id: '3',
type: 'video',
url:
'http://res.cloudinary.com/og-tech/video/upload/s--ZWPqo282--/v1514966645/sea_turtle-short_z1pr4o.mp4'
},
],
product_name: 'Ultra Thin Mechanical Keyboard',
product_desc: 'This keyboard gives you the clack to your click',
product_price: '200'
})
});
//...
In the above, we see the routes returning responses in JSON format for it to be further used at the frontend. You may have observed that a lot (all) the data returned to the user was static. In a real-world application, you would return dynamic data to the user.
在上面,我们看到路由以JSON格式返回响应,以便在前端进一步使用它。 您可能已经观察到,返回给用户的很多(全部)数据都是静态的。 在实际的应用程序中,您会将动态数据返回给用户。
The /productInfo
route accepts the id
of your product so that is what you would use to identify what data to serve instead of just returning static json data. In other words, you can make further query to your database or cloud storage to fetch the information and return the data in the format used above.
/productInfo
路由接受您产品的id
,因此您将使用该id
来标识要提供的数据,而不仅仅是返回静态json数据。 换句话说,您可以进一步查询数据库或云存储以获取信息并以上面使用的格式返回数据。
Configure Application Port
配置应用程序端口
Now we set the port we want the app to listen on:
现在我们设置我们希望应用监听的端口:
[...]
let port = 3128 || process.env.PORT;
app.listen(port, function () {
console.log('App listening on port ' + port + '!');
});
![Application Demo](https://d2mxuefqeaa7sj.cloudfront.net/s_9C103C9E48AE94D2479C548603A0CD527FF29C5290C5A332D3B288F8A4A75F2C_1517846163895_ezgif.com-video-to-gif.gif)
结论 ( Conclusion )
In this article we have see how to leverage Cloudinary’s image and video capabilities using Vue.js to build an Amazon-like preview app for products.
在本文中,我们了解了如何使用Vue.js利用Cloudinary的图像和视频功能来为产品构建类似于Amazon的预览应用程序。
You also can head over here if you want to find out more about optimizing images served on your website f and more about improving your store’s SEO by engineering better Google mobile search ranking through image optimization.
如果您想了解更多有关优化网站上提供的图像的信息,以及有关通过图像优化设计更好的Google移动搜索排名来改善商店的SEO的信息,也可以前往此处 。
Now you can use concepts shared here in building your own application for the #NextBillionUsers
现在,您可以使用此处共享的概念为#NextBillionUsers构建自己的应用程序
Here a link to the GitHub repository for more references.
这里是GitHub存储库的链接,以获取更多参考。
翻译自: https://scotch.io/tutorials/build-an-amazon-like-product-preview-app-using-vuejs
vue使用pdf.js预览