1.使用命令下载vue2项目

vue create deepseek

2.进入到deepseek项目里 下载依赖 启动

1.进入到项目里
cd deepseek

2.下载依赖
npm install

3.下载deepseek所需要的依赖
npm install axios
npm install markdown
npm install marked
npm install html-loader
npm install dompurify

3.启动
npm run serve

3.接下来就是核心代码了 搭建最基础问答页面

   3-1 App.vue    替换成以下内容

<template>
  <div id="app">
    <div class="chat-container">
      <div class="chat-content">
        <div class="chatBox">
          <div>
            <img
              src="https://cdn.deepseek.com/platform/favicon.png"
              style="color: blue; margin: 10px 10px 5px 10px"
              class="avatar"
              alt="机器人头像"
            />
            <h1 style="color: limegreen; margin: 0px 10px 0px 10px">嗨~Vue3-DeepSeek</h1>
            <div style="margin: 0px 10px 0px 10px">
              你身边的智能小帮手,我可以帮你搜索、答疑、写作,请把你的任务交给我吧~
            </div>
          </div>
          <div
            v-if="errorMessage"
            class="error-message"
          >
            {{ errorMessage }}
          </div>
          <div class="chat-messages">
            <div
              v-for="(message, index) in currentMessages"
              :key="index"
              class="message"
            >
              <div
                v-if="message.sender === 'user'"
                class="user-message-container"
              >
                <article class="message-content user-message">{{ message.text }}</article>
                <img
                  src="../src/assets/ermimi.jpg"
                  class="avatar user-avatar"
                  alt="用户头像"
                />
              </div>
              <div
                v-else
                class="bot-message-container"
              >
                <img
                  src="https://cdn.deepseek.com/platform/favicon.png"
                  class="avatar bot-avatar"
                  alt="机器人头像"
                />
                <article
                  class="message-content bot-message"
                  v-html="renderMarkdown(message.text)"
                  :data-completed="message.completed || !isStreaming"
                ></article>
              </div>
            </div>
          </div>
          <div class="chat-input">
            <textarea
              v-model="inputMessage"
              placeholder="请输入您的问题"
              @keyup.enter.exact="handleSend"
              rows="6"
              :disabled="isStreaming"
            />
            <button
              @click="handleButtonClick"
              :disabled="!inputMessage.trim() && !isStreaming"
            >
              {{ isStreaming ? "停止生成" : "发送" }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import marked from "marked";
import DOMPurify from "dompurify";
import { postStream } from "./deepSeek.js";

export default {
  name: "App",
  data() {
    return {
      currentMessages: [],
      inputMessage: "",
      errorMessage: "",
      currentBotMessage: "",
      isStreaming: false,
      abortController: null,
      conversationId: null,
      // 头像URL可以存储在data中以便动态更改
      userAvatar: "",
      botAvatar: "",
    };
  },
  created() {
    this.generateConversationId();
  },
  methods: {
    generateConversationId() {
      this.conversationId = "conv-" + Date.now();
    },

    renderMarkdown(content) {
      content = content || "";
      content = content.replace(
        /<think>/g,
        '<div class="thinking-container"><img src="https://cdn-icons-png.flaticon.com/512/1055/1055687.png" class="thinking-icon"><span class="deepThink">'
      );
      if (!content.includes("</think>")) {
        content = content.concat("</span></div>");
      }
      if (content.includes("</think>")) {
        content = content.replace(/<\/span><\/div>/g, "");
        content = content.replace(/<\/think>/g, "</span></div>");
      }
      const html = marked(content);
      const sanitizedHtml = DOMPurify.sanitize(html);
      const tempDiv = document.createElement("div");
      tempDiv.innerHTML = sanitizedHtml.toString();
      const deepThinkElements = tempDiv.querySelectorAll(".deepThink");
      deepThinkElements.forEach((element) => {
        if (element.textContent.trim() === "") {
          element.textContent = "暂无推理过程";
        }
      });
      return tempDiv.innerHTML;
    },
    async handleSend() {
      if (!this.inputMessage.trim() || this.isStreaming) return;
      this.abortController = new AbortController();
      const userMessage = {
        sender: "user",
        text: this.inputMessage,
        conversationId: this.conversationId,
      };
      this.currentMessages.push(userMessage);
      const botMessageIndex = this.currentMessages.length;
      this.currentMessages.push({
        sender: "system",
        text: "",
        completed: false,
        conversationId: this.conversationId,
      });
      const conversationHistory = this.buildConversationHistory();
      this.inputMessage = "";
      this.isStreaming = true;
      this.currentBotMessage = "";
      try {
        const response = await postStream(
          {
            messages: conversationHistory,
            model: "deepseek-chat",
            stream: true,
            conversation_id: this.conversationId,
          },
          {
            signal: this.abortController.signal,
          }
        );
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        while (this.isStreaming) {
          const { done, value } = await reader.read();
          if (done) break;
          const text = decoder.decode(value);
          const lines = text.split("\n\n").filter((line) => line.trim());
          for (const line of lines) {
            if (line.trim() === "data: [DONE]") {
              this.finishGeneration(botMessageIndex);
              return;
            }
            if (line.startsWith("data: ")) {
              try {
                const jsonStr = line.substring(6);
                const data = JSON.parse(jsonStr);
                console.log(data, "data==data");
                if (data.choices?.[0]?.delta?.content) {
                  this.currentBotMessage += data.choices[0].delta.content;
                  this.$set(this.currentMessages, botMessageIndex, {
                    sender: "system",
                    text: this.currentBotMessage,
                    completed: false,
                    conversationId: this.conversationId,
                  });
                  this.$nextTick(() => {
                    const container = this.$el.querySelector(".chat-messages");
                    container.scrollTop = container.scrollHeight;
                  });
                }
              } catch (e) {
                console.error("解析JSON出错:", e);
              }
            }
          }
        }
      } catch (error) {
        if (error.name !== "AbortError") {
          console.error("流式请求出错:", error);
          this.errorMessage = "请求出错: " + error.message;
          this.$set(this.currentMessages, botMessageIndex, {
            sender: "system",
            text: "请求出错: " + error.message,
            completed: true,
            conversationId: this.conversationId,
          });
        }
      } finally {
        if (this.isStreaming) {
          this.finishGeneration(botMessageIndex);
        }
      }
    },
    buildConversationHistory() {
      const currentConversationMessages = this.currentMessages.filter(
        (msg) => msg.conversationId === this.conversationId
      );
      const recentMessages = currentConversationMessages.slice(-10);
      return recentMessages.map((message) => {
        return {
          role: message.sender === "user" ? "user" : "assistant",
          content: message.text,
        };
      });
    },
    finishGeneration(index) {
      this.isStreaming = false;
      if (this.abortController) {
        this.abortController.abort();
        this.abortController = null;
      }
      this.$set(this.currentMessages, index, {
        ...this.currentMessages[index],
        completed: true,
      });
    },
    handleButtonClick() {
      if (this.isStreaming) {
        this.finishGeneration(this.currentMessages.length - 1);
      } else {
        this.handleSend();
      }
    },
    startNewConversation() {
      this.generateConversationId();
    },
  },
};
</script>
<style scoped>
#app {
  display: flex;
  height: 100vh;
  margin: 0;
  padding: 0;
  background-color: #f9f9f9;
}
.chat-container {
  display: flex;
  width: 100%;
  height: 100%;
  border: 1px solid #e0e0e0;
  border-radius: 10px;
  overflow: hidden;
  background-color: white;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.chat-content {
  width: 100%;
  height: 100%;
  padding: 15px;
  box-sizing: border-box;
}
.chatBox {
  display: flex;
  flex-direction: column;
  height: 92%;
  width: 100%;
  border: 1px solid #e0e0e0;
  border-radius: 10px;
  overflow: hidden;
  background-color: white;
}
.error-message {
  background-color: #f8d7da;
  color: #721c24;
  padding: 12px;
  margin-bottom: 12px;
  border-radius: 8px;
  text-align: center;
}
.chat-messages {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
}
.message {
  margin-bottom: 15px;
  display: flex;
  align-items: flex-start;
}
.user-message-container {
  display: flex;
  justify-content: flex-end;
  width: 100%;
  align-items: flex-start;
  gap: 10px;
}
.bot-message-container {
  display: flex;
  justify-content: flex-start;
  width: 100%;
  align-items: flex-start;
  gap: 10px;
}
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.user-avatar {
  border: 2px solid #2196f3;
}
.bot-avatar {
  border: 2px solid #4caf50;
}
.message-content {
  max-width: calc(80% - 50px);
  padding: 10px 15px;
  border-radius: 18px;
  line-height: 1.4;
  word-wrap: break-word;
}
.user-message {
  background-color: #e3f2fd;
  margin-left: 20%;
}
.bot-message {
  background-color: #f5f5f5;
  margin-right: 20%;
}
.chat-input {
  display: flex;
  padding: 15px;
  border-top: 1px solid #e0e0e0;
  background-color: #fff;
}
.chat-input textarea {
  flex: 1;
  padding: 12px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  margin-right: 12px;
  resize: none;
  min-height: 60px;
  max-height: 150px;
  font-family: inherit;
  font-size: 14px;
}
.chat-input textarea:focus {
  outline: none;
  border-color: #2196f3;
}
.chat-input button {
  padding: 0 20px;
  height: 48px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.2s;
}
.chat-input button:hover {
  background-color: #1976d2;
}
.chat-input button:disabled {
  background-color: #b0bec5;
  cursor: not-allowed;
}
.bot-message:not([data-completed="true"]):after {
  content: "|";
  animation: blink 1s infinite;
  color: #666;
}
@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}
/* 深度思考样式 */
.deepThink {
  color: #666;
  font-style: italic;
  background-color: #f0f0f0;
  padding: 8px 12px;
  border-radius: 8px;
  display: inline-block;
  margin-top: 5px;
}
.thinking-container {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 5px 0;
}
.thinking-icon {
  width: 16px;
  height: 16px;
  opacity: 0.6;
}
</style>

3-2 和App.vue 同级下 建个deepseek.js(接口及集合DeepSeek一些配置)

const DEEPSEEK_API_KEY = ""; // 替换为你的 DeepSeek API Key

// /**
//  * 调用 DeepSeek API 示例
//  * @param {Object} data 请求参数
//  * @returns {Promise} API 响应
//  */
// export function postStream(data) {
//   return fetch("https://api.deepseek.com/chat/completions", {
//     method: "post",
//     body: JSON.stringify(data),
//     headers: {
//       Authorization: `Bearer ${DEEPSEEK_API_KEY}`,
//       "Content-Type": "application/json",
//     },
//   });
// }

/**
 * 调用 DeepSeek API 示例
 * @param {Object} data 请求参数
 * @returns {Promise} API 响应
 */
export function postStream(data) {
  // 确保传入的data对象包含model和参数配置
  const requestData = {
    // 指定模型版本
    model: "deepseek-reasoner",
    // 模型版本配置
    model_version: "DeepSeek-V3.2-Exp",
    // 添加思考模式配置
    params: {
      // 是否启用思考模式
      thinking_mode: true,
      // 其他可选参数
      temperature: 0.7,
      max_tokens: 4096,
      // 更多参数...
    },
    // 合并用户传入的其他数据
    ...data,
  };

  return fetch("https://api.deepseek.com/chat/completions", {
    method: "post",
    body: JSON.stringify(requestData),
    headers: {
      Authorization: `Bearer ${DEEPSEEK_API_KEY}`,
      "Content-Type": "application/json",
    },
  });
}

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐