《花100块做个摸鱼小网站! 》第四篇—前端应用搭建和完成第一个热搜组件

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
可观测链路 OpenTelemetry 版,每月50GB免费额度
性能测试 PTS,5000VUM额度
简介: 本文档详细介绍了从零开始搭建一个包含前后端交互的热搜展示项目的全过程。通过本教程,读者不仅能学习到完整的项目开发流程,还能掌握爬虫技术和前后端交互的具体实践。适合有一定编程基础并对项目实战感兴趣的开发者参考。

⭐️基础链接导航⭐️

服务器 → ☁️ 阿里云活动地址

看样例 → 🐟 摸鱼小网站地址

学代码 → 💻 源码库地址

一、前言

在本系列文章的早期章节中,我们已经成功地购买了服务器并配置了MySQL、Redis等核心中间件。紧接着,我们不仅建立了后端服务,还开发了我们的首个爬虫程序。后面我们还把爬取到的数据进行了保存,生成了一整套MVC的后端代码,并且提供了一个接口出来。

这篇文章呢我要开始前端开发部分了。与后端开发相比,前端开发的优势在于其直观性和即时反馈。开发者可以迅速看到自己代码的成果,这种“所见即所得”的体验极大地提升了开发的乐趣和满足感。在接下来的篇章中,我将展示如何将爬取到的热搜数据整合到前端界面中,使之以一种用户友好的方式呈现,大家姑妄看之。

二、前端应用搭建

我的前端技术栈还停留在四年前,那时候我主要使用的是Vue2和ElementUI。并不是说我认为Vue3或React不好,只是我更习惯使用我熟悉的技术。即便如此,这些技术依然能够带来不错的效果。如果你想要尝试不同的技术或组件库,那也是完全可以的。

1. 前端环境搭建

(1)安装node.js,下载相应版本的node.js,下载地址:https://nodejs.org/en/download/ ,下载完双击安装,点击下一步直到安装完成,建议下载版本的是:v16.20.2

(2)安装完成后,附件里选择命令提示符(或者在开始的搜索框里输入cmd回车调出命令面板)输入:node -v回车,出现相应版本证明安装成功, node环境已经安装完成。
image.png

由于有些npm有些资源被屏蔽或者是国外资源的原因,经常会导致用npm安装依赖包的时候失败,所有我还需要npm的 国内镜像---cnpm。在命令行中输入:npm install -g cnpm --registry=https://registry.npmmirror.com 回车,大约需要3分钟,如果一直没有反应使用管理员身份运行cmd重试。

(3)安装全局vue-cli脚手架,用于帮助搭建所需的模板框架。输入命令:cnpm install -g @vue/cli回车等待完成。

(4)创建项目,首先我们要选定目录,然后再命令行中把目录转到选定的目录,假如我们打算把项目新建在e盘下的vue文件夹中则输入下面的命令: e:回车,然后cd vue,然后输入命令:vue create summo-sbmy-front-web,回车,然后它就会让你选择vue2还是vue3,选择vue2后点击enter,它就会创建好项目并且下载好依赖。
image.png

(5)启动项目,首先切换到summo-sbmy-front-web目录,然后执行npm run serve,项目运行成功后,浏览器会自动打开localhost:8080(如果浏览器没有自动打开 ,可以手动输入)。运行成功后,会看到Welcome to Your Vue.js App页面。
image.png

2. 脚手架处理

我的开发工具是VS Code,免费的,下载地址如下:https://code.visualstudio.com/

(1)文件和代码清理

删除components下的HelloWorld.vue文件
删除assets下的logo.png文件

原始App.vue代码如下

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
    
    
  name: 'App',
  components: {
    
    
    HelloWorld
  }
}
</script>

<style>
#app {
    
    
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

删除不必要的代码,不然启动会报错

<template>
  <div id="app">
  </div>
</template>

<script>

export default {
    
    
  name: 'App',
  components: {
    
    
  }
}
</script>

<style>
#app {
    
    
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

(2)axios和element-ui依赖引入

执行安装命令

//axios依赖引入
cnpm install axios

//element-ui依赖引入
cnpm install element-ui

下载完上面这两个组件后,去main.js中注册组件,然后才能使用,main.js代码如下:

import Vue from 'vue'
import App from './App.vue'

//引入饿了么UI
import {
   
   
  Calendar,
  Row,
  Col,
  Link,
  Button,
  Loading,
  Container,
  Header,
  Footer,
  Main,
  Form,
  Autocomplete,
  Tooltip,
  Card,
  Dialog
}  from 'element-ui';
Vue.use(Calendar)
Vue.use(Row)
Vue.use(Col)
Vue.use(Link)
Vue.use(Button)
Vue.use(Loading)
Vue.use(Container)
Vue.use(Header)
Vue.use(Footer)
Vue.use(Form)
Vue.use(Autocomplete)
Vue.use(Tooltip)
Vue.use(Card)
Vue.use(Main)
Vue.use(Dialog)
import "element-ui/lib/theme-chalk/index.css"

//引入axios
import axios from 'axios';
Vue.prototype.$ajax = axios;

Vue.config.productionTip = false

new Vue({
   
   
  render: h => h(App),
}).$mount('#app')

(3)封装apiService.js方便调用接口

在src目录下创建一个文件夹名为config,创建一个apiService.js,代码如下:

// apiService.js
import axios from "axios";

// 创建axios实例并配置基础URL
const apiClient = axios.create({
   
   
  baseURL: "http://localhost:80/api",
  headers: {
   
   
    "Content-Type": "application/json"
  },
});

export default {
   
   
  // 封装Get接口
  get(fetchUrl) {
   
   
    return apiClient.get(fetchUrl);
  }
};

三、前端热搜组件

1. 组件介绍

首先,成品的热搜组件样式如下,包括标题(图标+名称)、内容区(排序、标题、热度),点击标题可以跳转到指定的热搜文章。
image.png

2. 组件实现

在components目录下创建HotSearchBoard.vue文件,代码如下:

<template>
  <el-card class="custom-card" v-loading="loading">
    <template #header>
      <div class="card-title">
        <img :src="icon" class="card-title-icon" />
        {
  
  { title }}热榜
      </div>
    </template>
    <div class="cell-group-scrollable">
      <div
        v-for="item in hotSearchData"
        :key="item.hotSearchOrder"
        :class="getRankingClass(item.hotSearchOrder)"
        class="cell-wrapper"
      >
        <span class="cell-order">{
  
  { item.hotSearchOrder }}</span>
        <span
          class="cell-title hover-effect"
          @click="openLink(item.hotSearchUrl)"
        >
          {
  
  { item.hotSearchTitle }}
        </span>
        <span class="cell-heat">{
  
  { formatHeat(item.hotSearchHeat) }}</span>
      </div>
    </div>
  </el-card>
</template>

<script>
import apiService from "@/config/apiService.js";
export default {
    
    
  props: {
    
    
    title: String,
    icon: String,
    type: String,
  },
  data() {
    
    
    return {
    
    
      hotSearchData: [],
      loading:false
    };
  },
  created() {
    
    
    this.fetchData(this.type);
  },
  methods: {
    
    
    fetchData(type) {
    
    
      this.loading = true
      apiService
        .get("/hotSearch/queryByType?type=" + type)
        .then((res) => {
    
    
          // 处理响应数据
          this.hotSearchData = res.data.data;
        })
        .catch((error) => {
    
    
          // 处理错误情况
          console.error(error);
        }).finally(() => {
    
    
          // 加载结束
          this.loading = false; 
        });
    },
    getRankingClass(order) {
    
    
      if (order === 1) return "top-ranking-1";
      if (order === 2) return "top-ranking-2";
      if (order === 3) return "top-ranking-3";
      return "";
    },
    formatHeat(heat) {
    
    
      // 如果 heat 已经是字符串,并且以 "万" 结尾,那么直接返回
      if (typeof heat === "string" && heat.endsWith("万")) {
    
    
        return heat;
      }
      let number = parseFloat(heat); // 确保转换为数值类型进行比较
      if (isNaN(number)) {
    
    
        return heat; // 如果无法转换为数值,则原样返回
      }

      // 如果数值小于1000,直接返回该数值
      if (number < 1000) {
    
    
        return number.toString();
      }

      // 如果数值在1000到9999之间,转换为k为单位
      if (number >= 1000 && number < 10000) {
    
    
        return (number / 1000).toFixed(1) + "k";
      }

      // 如果数值大于等于10000,转换为万为单位
      if (number >= 10000) {
    
    
        return (number / 10000).toFixed(1) + "万";
      }
    },
    openLink(url) {
    
    
      if (url) {
    
    
        // 使用window.open在新标签页中打开链接
        window.open(url, "_blank");
      }
    },
  },
};
</script>

<style scoped>
.custom-card {
    
    
  background-color: #ffffff;
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}
.custom-card:hover {
    
    
  box-shadow: 0 6px 8px rgba(0, 0, 0, 0.25);
}

>>> .el-card__header {
    
    
  padding: 10px 18px;
}
>>> .el-card__body {
    
    
  display: flex;
  padding: 10px 0px 10px 10px;
}
.card-title {
    
    
  display: flex;
  align-items: center;
  font-weight: bold;
  font-size: 16px;
}

.card-title-icon {
    
    
  fill: currentColor;
  width: 24px;
  height: 24px;
  margin-right: 8px;
}

.cell-group-scrollable {
    
    
  max-height: 350px;
  overflow-y: auto;
  padding-right: 16px; /* 恢复内容区域的内边距 */
  flex: 1;
}

.cell-wrapper {
    
    
  display: flex;
  align-items: center;
  padding: 8px 8px; /* 减小上下内边距以减少间隔 */
  border-bottom: 1px solid #e8e8e8; /* 为每个项之间添加分割线 */
}

.cell-order {
    
    
  width: 20px;
  text-align: left;
  font-size: 16px;
  font-weight: 700;
  margin-right: 8px;
  color: #7a7a7a; /* 统一非特殊序号颜色 */
}

/* 通过在cell-heat类前面添加更多的父级选择器,提高了特异性 */
.cell-heat {
    
    
  min-width: 50px;
  text-align: right;
  font-size: 12px;
  color: #7a7a7a;
}
.cell-title {
    
    
  font-size: 13px;
  color: #495060;
  line-height: 22px;
  flex-grow: 1;
  overflow: hidden;
  text-align: left; /* 左对齐 */
  text-overflow: ellipsis; /* 超出部分显示省略号 */
}
.top-ranking-1 .cell-order {
    
    
  color: #fadb14;
} /* 金色 */
.top-ranking-2 .cell-order {
    
    
  color: #a9a9a9;
} /* 银色 */
.top-ranking-3 .cell-order {
    
    
  color: #d48806;
} /* 铜色 */
/* 新增的.hover-effect类用于标题的hover状态 */
.cell-title.hover-effect {
    
    
  cursor: pointer; /* 鼠标悬停时显示指针形状 */
  transition: color 0.3s ease; /* 平滑地过渡颜色变化 */
}

/* 当鼠标悬停在带有.hover-effect类的元素上时改变颜色 */
.cell-title.hover-effect:hover {
    
    
  color: #409eff; /* 或者使用你喜欢的颜色 */
}
</style>

在App.vue中添加热搜组件,由于不止一个热搜,我把它做成了一个数组

<template>
  <div id="app">
    <el-row :gutter="10">
      <el-col :span="6" v-for="(board, index) in hotBoards" :key="index">
        <hot-search-board
          :title="board.title"
          :icon="board.icon"
          :fetch-url="board.fetchUrl"
          :type="board.type"
        />
      </el-col>
    </el-row>
  </div>
</template>

<script>
import HotSearchBoard from "@/components/HotSearchBoard.vue";
export default {
    
    
  name: "App",
  components: {
    
    
    HotSearchBoard,
  },
  data() {
    
    
    return {
    
    
      hotBoards: [
        {
    
    
          title: "百度",
          icon: require("@/assets/icons/baidu-icon.svg"),
          type: "baidu",
        },
        {
    
    
          title: "抖音",
          icon: require("@/assets/icons/douyin-icon.svg"),
          type: "douyin",
        },
      ],
    };
  },
};
</script>

<style>
#app {
    
    
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  background: #f8f9fa; /* 提供一个柔和的背景色 */
  min-height: 100vh; /* 使用视口高度确保填满整个屏幕 */
  padding: 0; /* 保持整体布局紧凑,无额外内边距 */
}
</style>

最终的项目结构和文件如下
image.png

代码不难,无非就是使用卡片和列表对热搜进行展示,还有就是我加了一些样式,比如前三名的排序有颜色,字体改了改。

四、小结一下

在本篇文章中,我主要展示前端代码逻辑。至于后端,也做了一些更新,比如新增了queryType接口和跨域请求的处理,但这些内容都是基础的,你下载代码后就能一目了然,不懂的评论区交流,或者加我微信:hb1766435296。之前的准备工作终于开始见到成效,虽然看起来简单,但实际上解决了不少复杂问题。现在,服务器、前端和后端的基础都打好了,接下来我会继续开发,增加更多功能。

关于爬虫部分,我已经成功实现了针对12个不同网站的爬取功能。考虑到爬虫的逻辑相对简单,无需单独撰写文章来详细说明。因此,我计划在每篇文章的附录或额外部分简要介绍各个热搜网站的爬虫逻辑。这样的安排既能保证信息的完整性,又不会让文章显得过于冗长。

番外:知乎热搜爬虫

1. 爬虫方案评估

知乎热搜是这样的, 接口是:https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total
image.png

数据还算完备,有标题、热度、封面、排序等,知乎的热搜接口返回的数据格式是JSON,这种比返回HTML更简单。

2. 网页解析代码

这个就可以使用Postman生成调用代码,流程我就不赘述了,直接上代码,ZhihuHotSearchJob:

package com.summo.sbmy.job.zhihu;

import java.io.IOException;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.google.common.collect.Lists;
import com.summo.sbmy.dao.entity.SbmyHotSearchDO;
import com.summo.sbmy.service.SbmyHotSearchService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import static com.summo.sbmy.common.enums.HotSearchEnum.ZHIHU;

/**
 * @author summo
 * @version DouyinHotSearchJob.java, 1.0.0
 * @description 知乎热搜Java爬虫代码
 * @date 2024年08月09
 */
@Component
@Slf4j
public class ZhihuHotSearchJob {
   
   

    @Autowired
    private SbmyHotSearchService sbmyHotSearchService;

    /**
     * 定时触发爬虫方法,1个小时执行一次
     */
    @Scheduled(fixedRate = 1000 * 60 * 60)
    public void hotSearch() throws IOException {
   
   
        try {
   
   
            //查询知乎热搜数据
            OkHttpClient client = new OkHttpClient().newBuilder().build();
            Request request = new Request.Builder().url("https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total")
                .method("GET", null).build();
            Response response = client.newCall(request).execute();
            JSONObject jsonObject = JSONObject.parseObject(response.body().string());
            JSONArray array = jsonObject.getJSONArray("data");
            List<SbmyHotSearchDO> sbmyHotSearchDOList = Lists.newArrayList();
            for (int i = 0, len = array.size(); i < len; i++) {
   
   
                //获取知乎热搜信息
                JSONObject object = (JSONObject)array.get(i);
                JSONObject target = object.getJSONObject("target");
                //构建热搜信息榜
                SbmyHotSearchDO sbmyHotSearchDO = SbmyHotSearchDO.builder().hotSearchResource(ZHIHU.getCode()).build();
                //设置知乎三方ID
                sbmyHotSearchDO.setHotSearchId(target.getString("id"));
                //设置文章连接
                sbmyHotSearchDO.setHotSearchUrl("https://www.zhihu.com/question/" + sbmyHotSearchDO.getHotSearchId());
                //设置文章标题
                sbmyHotSearchDO.setHotSearchTitle(target.getString("title"));
                //设置作者名称
                sbmyHotSearchDO.setHotSearchAuthor(target.getJSONObject("author").getString("name"));
                //设置作者头像
                sbmyHotSearchDO.setHotSearchAuthorAvatar(target.getJSONObject("author").getString("avatar_url"));
                //设置文章摘要
                sbmyHotSearchDO.setHotSearchExcerpt(target.getString("excerpt"));
                //设置热搜热度
                sbmyHotSearchDO.setHotSearchHeat(object.getString("detail_text").replace("热度", ""));
                //按顺序排名
                sbmyHotSearchDO.setHotSearchOrder(i + 1);
                sbmyHotSearchDOList.add(sbmyHotSearchDO);
            }
            //数据持久化
            sbmyHotSearchService.saveCache2DB(sbmyHotSearchDOList);
        } catch (IOException e) {
   
   
            log.error("获取知乎数据异常", e);
        }
    }

}

知乎的热搜数据是自带唯一ID的,不需要我们手动生成,非常方便。

目录
相关文章
|
15天前
|
JavaScript 前端开发 开发者
哇塞!Vue.js 与 Web Components 携手,掀起前端组件复用风暴,震撼你的开发世界!
【8月更文挑战第30天】这段内容介绍了Vue.js和Web Components在前端开发中的优势及二者结合的可能性。Vue.js提供高效简洁的组件化开发,单个组件包含模板、脚本和样式,方便构建复杂用户界面。Web Components作为新兴技术标准,利用自定义元素、Shadow DOM等技术创建封装性强的自定义HTML元素,实现跨框架复用。结合二者,不仅增强了Web Components的逻辑和交互功能,还实现了Vue.js组件在不同框架中的复用,提高了开发效率和可维护性。未来前端开发中,这种结合将大有可为。
57 0
|
15天前
|
JavaScript 前端开发 API
揭秘现代前端开发秘籍:Vue.js与ES6如何联手打造惊艳应用?
【8月更文挑战第30天】本文介绍如何从零开始使用Vue.js与ES6创建现代前端应用。首先,通过简要介绍Vue.js和ES6的新特性,使读者了解这两者为何能有效提升开发效率。接着,指导读者使用Vue CLI初始化项目,并展示如何运用ES6语法编写Vue组件。最后,通过运行项目验证组件功能,为后续开发打下基础。适用于希望快速入门Vue.js与ES6的前端开发者。
33 3
|
14天前
|
机器学习/深度学习 存储 前端开发
实战揭秘:如何借助TensorFlow.js的强大力量,轻松将高效能的机器学习模型无缝集成到Web浏览器中,从而打造智能化的前端应用并优化用户体验
【8月更文挑战第31天】将机器学习模型集成到Web应用中,可让用户在浏览器内体验智能化功能。TensorFlow.js作为在客户端浏览器中运行的库,提供了强大支持。本文通过问答形式详细介绍如何使用TensorFlow.js将机器学习模型带入Web浏览器,并通过具体示例代码展示最佳实践。首先,需在HTML文件中引入TensorFlow.js库;接着,可通过加载预训练模型如MobileNet实现图像分类;然后,编写代码处理图像识别并显示结果;此外,还介绍了如何训练自定义模型及优化模型性能的方法,包括模型量化、剪枝和压缩等。
25 1
|
14天前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
32 0
|
14天前
|
开发者 存储 API
Xamarin 开发者的社区资源概览:从官方文档到GitHub示例,全面探索提升开发技能与解决问题的多元化渠道与实用工具
【8月更文挑战第31天】Xamarin 开发者社区资源概览旨在提升开发效率与解决问题,涵盖官方文档、社区论坛、GitHub 项目等。官方文档详尽,涵盖 Xamarin.Forms 使用、性能优化等;社区论坛供交流心得;GitHub 提供示例代码。此外,第三方博客、视频教程及 Xamarin University 等资源也丰富多样,适合各阶段开发者学习与提升。通过综合利用这些资源,开发者可不断进步,应对技术挑战。
29 0
|
14天前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
26 0
|
14天前
|
开发者 自然语言处理 存储
语言不再是壁垒:掌握 JSF 国际化技巧,轻松构建多语言支持的 Web 应用
【8月更文挑战第31天】JavaServer Faces (JSF) 框架提供了强大的国际化 (I18N) 和本地化 (L10N) 支持,使开发者能轻松添加多语言功能。本文通过具体案例展示如何在 JSF 应用中实现多语言支持,包括创建项目、配置语言资源文件 (`messages_xx.properties`)、设置 `web.xml`、编写 Managed Bean (`LanguageBean`) 处理语言选择,以及使用 Facelets 页面 (`index.xhtml`) 显示多语言消息。通过这些步骤,你将学会如何配置 JSF 环境、编写语言资源文件,并实现动态语言切换。
21 0
|
14天前
|
iOS开发 Android开发 MacOS
从零到全能开发者:解锁Uno Platform,一键跨越多平台应用开发的神奇之旅,让你的代码飞遍Windows、iOS、Android、macOS及Web,技术小白也能秒变跨平台大神!
【8月更文挑战第31天】从零开始,踏上使用Uno Platform开发跨平台应用的旅程。只需编写一次代码,即可轻松部署到Windows、iOS、macOS、Android及Web(通过WASM)等多个平台。Uno Platform为.NET生态带来前所未有的灵活性和效率,简化跨平台开发。首先确保安装了Visual Studio或VS Code及.NET SDK,然后选择合适的项目模板创建新项目。项目结构类似传统.NET MAUI或WPF项目,包含核心NuGet包。通过简单的按钮示例,你可以快速上手并构建应用。Uno Platform让你的技术探索之旅充满无限可能。
21 0
|
14天前
|
前端开发 JavaScript 开发者
JSF与WebSockets,打造实时通信魔法!让你的Web应用秒变聊天室,用户体验飞升!
【8月更文挑战第31天】在现代Web应用开发中,实时通信对于提升用户体验至关重要。本文探讨了如何在主要面向Web应用开发的JSF(JavaServer Faces)框架中引入WebSockets支持,以实现客户端与服务器之间的全双工通信。通过具体示例展示了在JSF应用中实现WebSockets的基本步骤:添加依赖、创建服务器端点以及在前端页面中嵌入JavaScript客户端代码。尽管这一过程中可能会遇到一些挑战,如复杂代码编写和额外配置需求,但借助AWS等云服务平台,开发者仍能高效地完成部署和管理工作,从而增强Web应用的实时通信能力。
20 0
|
14天前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
38 0