遇见 4 years ago
parent
commit
9991e93172
  1. 1
      .gitignore
  2. 10
      README.md
  3. 3
      YuJian-Blog-Admin/package.json
  4. 20
      YuJian-Blog-Admin/src/views/Article/ArticleCreate.vue
  5. 69
      YuJian-Blog-Admin/src/views/Article/ArticleCreateEditor.vue
  6. 29
      YuJian-Blog-Admin/src/views/Article/ArticleEdit.vue
  7. 98
      YuJian-Blog-Admin/vue.config.js
  8. 1
      YuJian-Blog-Server/db/config.js
  9. 5
      YuJian-Blog-Web/src/views/Article/index.vue
  10. 4
      YuJian-Blog-Web/src/views/Home/components/Article.vue

1
.gitignore vendored

@ -26,3 +26,4 @@ pnpm-debug.log* @@ -26,3 +26,4 @@ pnpm-debug.log*
YuJian-Blog开发日志.md
Push时注意.md
Test.http
YuJian-Blog-Server/db/config.js

10
README.md

@ -2,7 +2,15 @@ @@ -2,7 +2,15 @@
### 基于Vue和Express的全栈博客系统。
基础博客功能实现:
- [x] 基础的博客前端搭建
- [x] 基础的后端增删改查
- [x] 博客前端的数据获取
- [ ] 实现富文本编辑
- [x] 实现富文本编辑
进阶功能实现:
- [ ] 使用ECharts.js实现后台管理系统数据可视化
- [ ] 使用Animes.js完善动画效果

3
YuJian-Blog-Admin/package.json

@ -23,7 +23,8 @@ @@ -23,7 +23,8 @@
"path-to-regexp": "2.4.0",
"vue": "2.6.10",
"vue-router": "3.0.6",
"vuex": "3.1.0"
"vuex": "3.1.0",
"wangeditor": "^4.6.3"
},
"devDependencies": {
"@babel/core": "7.0.0",

20
YuJian-Blog-Admin/src/views/Article/ArticleCreate.vue

@ -1,11 +1,23 @@ @@ -1,11 +1,23 @@
<template>
<div class="CreateFather">
<el-form @submit.native.prevent="createArticle" ref="form" :model="ArticleForm">
<el-form
@submit.native.prevent="createArticle"
ref="form"
:model="ArticleForm"
>
<el-form-item label="文章名称">
<el-input v-model="ArticleForm.title" class="ArticleTitleWidth"></el-input>
<el-input v-model="ArticleForm.title" class="ArticleTitleWidth" />
</el-form-item>
<el-form-item label="文章内容">
<el-input type="textarea" v-model="ArticleForm.content" style="width: 90%;"></el-input>
<article-create-editor
:PropsEditContentDate.sync="ArticleForm.content"
/>
<!-- <el-form-item label="HTML"></el-form-item> -->
<el-input
v-model="ArticleForm.content"
type="textarea"
style="display: none"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit">立即创建</el-button>
@ -16,8 +28,10 @@ @@ -16,8 +28,10 @@
<script>
import { AddArticle } from "@/api/article";
import ArticleCreateEditor from "./ArticleCreateEditor";
export default {
components: { ArticleCreateEditor },
name: "ArticleCreate",
data() {
return {

69
YuJian-Blog-Admin/src/views/Article/ArticleCreateEditor.vue

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
<template>
<div class="EditorFather">
<div ref="EditContent" style="margin-left: 70px"></div>
</div>
</template>
<script>
import wangEditor from "wangeditor";
export default {
name: "ArticleCreateEditor",
date() {
return {
Editor: null,
EditContentDate: {},
};
},
props: {
PropsEditContentDate: {
type: String,
default() {
return "";
},
},
},
watch: {
PropsEditContentDate() {
this.EditContentDate = this.PropsEditContentDate;
this.initEditor();
this._setInitContent(this.EditContentDate);
},
},
methods: {
initEditor() {
const EditContent = new wangEditor(this.$refs.EditContent);
EditContent.config.zIndex = 0;
this.Editor = EditContent;
this._syncContent();
EditContent.create();
},
_syncContent() {
this.Editor.config.onchange = (html) => {
this.EditContentDate = html;
this.$emit("update:PropsEditContentDate", html);
};
},
_setInitContent(content) {
this.Editor.txt.html(content);
},
},
mounted() {
this.EditContentDate = this.PropsEditContentDate;
// console.log("", this.PropsEditContentDate);
this.initEditor();
this._setInitContent(this.EditContentDate);
},
beforeDestroy() {
// API
this.Editor.destroy();
this.Editor = null;
},
};
</script>
<style scoped>
.EditorFather {
width: 90%;
}
</style>

29
YuJian-Blog-Admin/src/views/Article/ArticleEdit.vue

@ -1,11 +1,24 @@ @@ -1,11 +1,24 @@
<template>
<div class="CreateFather">
<el-form @submit.native.prevent="EditArticle" ref="form" :model="ArticleForm">
<div class="EditFather">
<el-form
@submit.native.prevent="EditArticle"
ref="form"
:model="ArticleForm"
>
<el-form-item label="文章名称">
<el-input v-model="ArticleForm.title" class="ArticleTitleWidth"></el-input>
<el-input
v-model="ArticleForm.title"
class="ArticleTitleWidth"
></el-input>
</el-form-item>
<el-form-item label="文章内容">
<el-input type="textarea" v-model="ArticleForm.content" style="width: 90%;"></el-input>
<article-create-editor
:PropsEditContentDate.sync="ArticleForm.content"
/>
<el-input
type="textarea"
v-model="ArticleForm.content"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit">保存修改</el-button>
@ -17,8 +30,10 @@ @@ -17,8 +30,10 @@
<script>
import { mapGetters } from "vuex";
import { UpdataArticle } from "@/api/article";
import ArticleCreateEditor from "./ArticleCreateEditor";
export default {
components: { ArticleCreateEditor },
name: "ArticleEdit",
data() {
return {
@ -33,10 +48,10 @@ export default { @@ -33,10 +48,10 @@ export default {
},
methods: {
fetchArticle() {
// console.log(this.$route.params.id);
this.$store.dispatch("article/getArticle").then(() => {
this.ArticleForm.title = this.article[this.$route.params.id].title;
this.ArticleForm.content = this.article[this.$route.params.id].content;
// this.ArticleForm = this.article[this.$route.params.id];
});
},
EditArticle() {
UpdataArticle(
@ -61,7 +76,7 @@ export default { @@ -61,7 +76,7 @@ export default {
};
</script>
<style scoped>
.CreateFather {
.EditFather {
margin: 30px 0px 0px 30px;
width: 100%;
}

98
YuJian-Blog-Admin/vue.config.js

@ -1,19 +1,19 @@ @@ -1,19 +1,19 @@
'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')
"use strict";
const path = require("path");
const defaultSettings = require("./src/settings.js");
function resolve(dir) {
return path.join(__dirname, dir)
return path.join(__dirname, dir);
}
const name = defaultSettings.title || 'YuJianBlog-Admin' // page title
const name = defaultSettings.title || "YuJianBlog-Admin"; // page title
// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following methods:
// port = 9528 npm run dev OR npm run dev --port = 9528
const port = process.env.port || process.env.npm_config_port || 9528 // dev port
const port = process.env.port || process.env.npm_config_port || 9528; // dev port
// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
@ -24,9 +24,9 @@ module.exports = { @@ -24,9 +24,9 @@ module.exports = {
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: '/',
outputDir: 'dist',
assetsDir: 'static',
publicPath: "/",
outputDir: "dist",
assetsDir: "static",
lintOnSave: false, //process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
@ -42,79 +42,83 @@ module.exports = { @@ -42,79 +42,83 @@ module.exports = {
name: name,
resolve: {
alias: {
'@': resolve('src')
"@": resolve("src")
}
}
},
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
config.plugins.delete("preload"); // TODO: need test
config.plugins.delete("prefetch"); // TODO: need test
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
.rule("svg")
.exclude.add(resolve("src/icons"))
.end();
config.module
.rule('icons')
.rule("icons")
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.include.add(resolve("src/icons"))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: 'icon-[name]'
symbolId: "icon-[name]"
})
.end()
.end();
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.rule("vue")
.use("vue-loader")
.loader("vue-loader")
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
options.compilerOptions.preserveWhitespace = true;
return options;
})
.end()
.end();
config
.when(process.env.NODE_ENV !== 'development',
config => {
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === "development", config =>
config.devtool("evel")
);
config.when(process.env.NODE_ENV !== "development", config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
.plugin("ScriptExtHtmlWebpackPlugin")
.after("html")
.use("script-ext-html-webpack-plugin", [
{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
}
])
.end();
config.optimization.splitChunks({
chunks: "all",
cacheGroups: {
libs: {
name: 'chunk-libs',
name: "chunk-libs",
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
chunks: "initial" // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
name: "chunk-elementUI", // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
name: "chunk-commons",
test: resolve("src/components"), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
}
)
}
});
config.optimization.runtimeChunk("single");
});
}
};

1
YuJian-Blog-Server/db/config.js

@ -0,0 +1 @@ @@ -0,0 +1 @@
No

5
YuJian-Blog-Web/src/views/Article/index.vue

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
<blog-header />
<index-top :TopInfo="TopInfo" />
<img class="ArticleMainCover" src="@/assets/images/test.png" />
<div class="ArticleMain">{{ TopInfo.content }}</div>
<div class="ArticleMain" v-html="TopInfo.content"></div>
<Footer />
</div>
</template>
@ -44,7 +44,7 @@ export default { @@ -44,7 +44,7 @@ export default {
},
mounted() {
this.getArticleData();
}
},
};
</script>
@ -56,7 +56,6 @@ export default { @@ -56,7 +56,6 @@ export default {
width: 800px;
}
.ArticleMain {
display: flex;
margin: 0 auto;
background-color: #ffffff;
border: 1px solid #000000;

4
YuJian-Blog-Web/src/views/Home/components/Article.vue

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
</div>
<div class="ArticleInfo">
<div class="ArticleTitle">{{ item.title }}</div>
<div class="ArticleCont">{{ item.content }}</div>
<!-- <div class="ArticleCont">{{ item.content }}</div> -->
<div class="ArticleData">{{ item.author }}</div>
</div>
</router-link>
@ -52,7 +52,7 @@ export default { @@ -52,7 +52,7 @@ export default {
.ArticleItem {
display: grid;
grid-template-columns: 720px;
grid-template-rows: 330px 110px;
grid-template-rows: 330px 70px;
margin-top: 40px;
border: 1px solid #757575;
border-radius: 5px;

Loading…
Cancel
Save