first commit

master
zfp 2 years ago
commit 9634cc0a91
  1. 25
      .gitignore
  2. 24
      README.md
  3. 5
      babel.config.js
  4. 19
      jsconfig.json
  5. 19388
      package-lock.json
  6. 51
      package.json
  7. BIN
      public/favicon.ico
  8. 17
      public/index.html
  9. 20
      src/App.vue
  10. BIN
      src/assets/logo.png
  11. 22
      src/components/ContentBase.vue
  12. 58
      src/components/HelloWorld.vue
  13. 81
      src/components/NavBar.vue
  14. 113
      src/components/UserProfileInfo.vue
  15. 71
      src/components/UserProfilePost.vue
  16. 68
      src/components/UserProfileWrite.vue
  17. 6
      src/main.js
  18. 48
      src/router/index.js
  19. 16
      src/store/index.js
  20. 100
      src/store/user.js
  21. 18
      src/views/HomeView.vue
  22. 85
      src/views/LoginView.vue
  23. 20
      src/views/NotFoundView.vue
  24. 117
      src/views/RegisterView.vue
  25. 99
      src/views/UserList.vue
  26. 146
      src/views/UserProfile.vue
  27. 4
      vue.config.js

25
.gitignore vendored

@ -0,0 +1,25 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.vercel

@ -0,0 +1,24 @@
# myspace
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

19388
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,51 @@
{
"name": "myspace",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@popperjs/core": "^2.11.5",
"bootstrap": "^5.2.0",
"core-js": "^3.8.3",
"jquery": "^3.6.0",
"jwt-decode": "^3.1.2",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vuex": "^4.0.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "^5.0.8",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

@ -0,0 +1,20 @@
<template>
<NavBar/>
<router-view :key="$route.fullPath"/>
</template>
<script>
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap';
import NavBar from "@/components/NavBar.vue"
export default {
name:'app',
components:{
NavBar,
}
}
</Script>
<style>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

@ -0,0 +1,22 @@
<template>
<div class="container">
<div class="card">
<div class="card-body">
<slot>
</slot>
</div>
</div>
</div>
</template>
<script>
export default {
name:"ContentBase",
}
</script>
<style scoped>
.container {
margin-top: 20px;
}
</style>

@ -0,0 +1,58 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

@ -0,0 +1,81 @@
<template>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<route-link class="navbar-brand" :to="{ name: 'home' }"
>MySpace</route-link
>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarText"
aria-controls="navbarText"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<router-link class="nav-link" :to="{ name: 'home' }"
>首页</router-link
>
</li>
<li class="nav-item">
<router-link class="nav-link" :to="{ name: 'userlist' }"
>好友列表</router-link
>
</li>
</ul>
<ul class="navbar-nav" v-if="!$store.state.user.is_login">
<li class="nav-item">
<router-link class="nav-link" :to="{ name: 'login' }"
>登陆</router-link
>
</li>
<li class="nav-item">
<router-link class="nav-link" :to="{ name: 'register' }"
>注册</router-link
>
</li>
</ul>
<ul class="navbar-nav" v-else>
<li class="nav-item">
<router-link
class="nav-link"
:to="{name:'userprofile',params: {userId: $store.state.user.id},}"
>{{ $store.state.user.username }}</router-link
>
</li>
<li class="nav-item">
<a class="nav-link" style="cursor: pointer" @click="logout">退出</a>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script>
import { useStore } from "vuex";
export default {
name: "NavBar",
setup(){
const store = useStore();
const logout = () => {
store.commit("logout");
};
return {
logout,
}
}
};
</script>
<style scoped>
</style>

@ -0,0 +1,113 @@
<template>
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-3 img-field">
<img class="img-fluid" :src="userInfo.photo" alt="">
</div>
<div class="col-9">
<div class="username">{{ userInfo.username }}</div>
<div class="fans">粉丝数: {{ userInfo.followerCount }}</div>
<button @click="follow" v-if="!userInfo.is_followed&&!is_me" type="button"
class="btn btn-success btn-sm">+关注</button>
<button @click="unfollow" v-if="userInfo.is_followed&&!is_me" type="button"
class="btn btn-danger btn-sm">取消关注</button>
</div>
</div>
</div>
</div>
</template>
<script>
import {useStore} from "vuex";
import {computed} from "vue";
import $ from "jquery";
export default {
name: "UserProfileInfo",
props: {
userInfo: {
type: Object,
required: true,
},
},
setup(props, context) {
const store = useStore();
const follow = () => {
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/follow/",
type: "POST",
headers: {
"Authorization": "Bearer " + store.state.user.access,
},
data: {
target_id: props.userInfo.id,
},
success(resp) {
if(resp.result === "success")
//
context.emit("follow123"); // follow123
}
});
};
const unfollow = () => {
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/follow/",
type: "POST",
headers: {
"Authorization": "Bearer " + store.state.user.access,
},
data: {
target_id: props.userInfo.id,
},
success(resp) {
if(resp.result === "success")
//
context.emit("unfollow1234"); // follow1234
}
});
};
//
let is_me = computed(()=> store.state.user.id === props.userInfo.id);
return {
follow,
unfollow,
is_me,
}
},
}
</script>
<style scoped>
img {
border-radius: 50%;
}
.username {
font-weight: bold;
}
.fans {
color: gray;
font-size: 12px;
}
button {
padding: 2px 4px;
font-size: 12px;
}
.img-field {
display: flex;
flex-direction: column;
justify-content: center;
}
</style>

@ -0,0 +1,71 @@
<template>
<div class="card">
<div class="card-body">
<div v-for="post in posts.posts" :key = "post.id">
<div class="card singlePost">
<div class="card-body">
{{post.content}}
<button @click="delete_a_post(post.id)" v-if="is_me" type="button" class="btn btn-danger btn-sm">删除该贴</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {computed} from "vue";
import {useStore} from "vuex";
import $ from "jquery";
export default {
name: "UserProfilePost",
props: {
// :postsuser
posts:{
type : Object,
required: true,
},
user: {
type : Object,
required: true,
}
},
setup(props,context) {
const store = useStore();
//
let is_me = computed(() => store.state.user.id === props.user.id);
const delete_a_post = post_id => $.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/post/",
type: "DELETE",
headers: {
"Authorization": "Bearer " + store.state.user.access,
},
data:{
post_id: post_id,
},
success(resp) {
if (resp.result === "success"){
context.emit("delete_a_post",post_id);
}
}
});
return {
is_me,
delete_a_post,
}
}
}
</script>
<style scoped>
.singlePost{
margin-bottom: 10px;
}
button {
float: right;
}
</style>

@ -0,0 +1,68 @@
<template>
<div class="card edit-field">
<div class="card-body">
<div class="mb-3">
<label for="edit-input" class="form-label">编辑区</label>
<textarea v-model="content" class="form-control" id="edit-input" rows="3"></textarea>
<!--点击button会触发子组件send_msg函数-->
<button @click="send_msg" type="button" class="btn btn-primary btn-sm">发送</button>
</div>
</div>
</div>
</template>
<script>
import { ref } from "vue";
import $ from "jquery";
import {useStore} from "vuex";
export default {
name: "UserProfileWrite",
setup(props, context) {
let content = ref('');
const store = useStore();
const send_msg = () => {
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/post/",
type: "POST",
headers: {
"Authorization": "Bearer " + store.state.user.access,
},
data: {
content: content.value,
},
success(resp){
//
if (resp.result === "success"){
// send_msg()
context.emit("send_msg", content.value);
content.value = "";
}
},
});
};
return {
content,
send_msg,
}
}
}
</script>
<style scoped>
.edit-field {
margin-top: 20px;
}
button {
margin-top: 10px;
}
</style>

@ -0,0 +1,6 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(store).use(store).use(router).mount('#app')

@ -0,0 +1,48 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '@/views/HomeView.vue'
import UserList from '@/views/UserList.vue'
import LoginView from "@/views/LoginView.vue"
import RegisterView from "@/views/RegisterView.vue"
import NotFound from "@/views/NotFoundView.vue"
import UserProfile from '@/views/UserProfile.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/userlist/',
name: 'userlist',
component: UserList
},
{
path: '/login/',
name: 'login',
component: LoginView
}, {
path: '/register/',
name: 'register',
component: RegisterView
}, {
path: '/userprofile/:userId/',
name: 'userprofile',
component: UserProfile
}, {
path: '/404/',
name: 'error',
component: NotFound
},{
path: '/:catchAll(.*)',
name: 'other',
redirect: '/404/',
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router

@ -0,0 +1,16 @@
import { createStore } from 'vuex'
import moduleUser from './user';
export default createStore({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
user: moduleUser,
}
});

@ -0,0 +1,100 @@
import $ from 'jquery';
import jwt_decode from 'jwt-decode';
const moduleUser = {
state: {
id: "",
username: "",
photo: "",
folllowerCount: 0,
access: "",
refresh: "",
is_login: false,
},
getters: {
},
mutations: {
updateUser(state,user) {
state.id = user.id;
state.username = user.username;
state.photo = user.photo;
state.folllowerCount = user.folllowerCount;
state.access = user.access;
state.refresh = user.refresh;
state.is_login = user.is_login;
},
updateAccess(state,access) {
state.access = access;
},
logout(state) {
state.id = "",
state.username = "";
state.photo = "";
state.folllowerCount = 0;
state.access = "";
state.refresh = "";
state.is_login = false;
}
},
actions: {
login(context,data) {
$.ajax({
url: "https://app165.acapp.acwing.com.cn/api/token/",
type: "POST",
data: {
username: data.username,
password: data.password,
},
success(resp) {
const {access,refresh} = resp;
const access_obj = jwt_decode(access);
// 每隔4.5分钟刷新依次令牌(access)
setInterval(()=> {
$.ajax({
url: "https://app165.acapp.acwing.com.cn/api/token/refresh/",
type: "POST",
data: {
refresh:refresh,
},
success(resp) {
context.commit("updateAccess",resp.access);
}
})
},4.5 * 60 * 1000);
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/getinfo/",
type: "get",
data: {
user_id: access_obj.user_id,
},
headers:{
'Authorization': "Bearer " + access,
},
success(resp) {
context.commit("updateUser",{
...resp,
access:access,
refresh:refresh,
is_login:true,
});
data.success();
},
});
},
error() {
data.error();
}
});
}
},
modules: {
},
};
export default moduleUser;

@ -0,0 +1,18 @@
<template>
<ContentBase>
首页
</ContentBase>
</template>
<script>
import ContentBase from '@/components/ContentBase.vue'
export default {
name: "HomeView",
components: {
ContentBase,
}
}
</script>
<style scoped>
</style>

@ -0,0 +1,85 @@
<template>
<ContentBase>
<div class="row justify-content-md-center">
<div class="col-3">
<form @submit.prevent="login">
<div class="mb-3">
<label for="username" class="form-label">用户名</label>
<input
v-model="username"
type="text"
class="form-control"
id="username"
/>
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input
v-model="password"
type="password"
class="form-control"
id="password"
/>
</div>
<div class="error-msg">{{error_msg}}</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>
</div>
</ContentBase>
</template>
<script>
import ContentBase from "@/components/ContentBase.vue";
import { ref } from "vue";
import {useStore} from "vuex";
import router from "@/router/index";
export default {
name: "LoginView",
components: {
ContentBase,
},
setup() {
const store = useStore();
let username = ref("");
let password = ref("");
let error_msg = ref("");
const login = ()=> {
// error_msg
error_msg.value = "";
// moduleUser
store.dispatch("login",{
username: username.value,
password: password.value,
success() { //
router.push({name: "userlist"});
},
error () { //
error_msg.value = "用户名不存在或者密码错误!";
}
});
};
return {
username,
password,
error_msg,
login,
};
},
};
</script>
<style scoped>
button {
width: 100%;
}
.error-msg {
font-weight: bold;
color: red;
margin-bottom: 20px;
}
</style>

@ -0,0 +1,20 @@
<template>
<ContentBase>404! Not Found!</ContentBase>
</template>
<script>
import ContentBase from "@/components/ContentBase.vue";
export default {
name:"NotFound",
components:{
ContentBase,
}
}
</script>
<style scoped>
</style>

@ -0,0 +1,117 @@
<template>
<ContentBase>
<div class="row justify-content-md-center">
<div class="col-3">
<form @submit.prevent="register">
<div class="mb-3">
<label for="username" class="form-label">用户名</label>
<input
v-model="username"
type="text"
class="form-control"
id="username"
/>
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input
v-model="password"
type="password"
class="form-control"
id="password"
/>
</div>
<div class="mb-3">
<label for="password_confirm" class="form-label">确认密码</label>
<input
v-model="password_confirm"
type="password"
class="form-control"
id="password"
/>
</div>
<div class="error-msg">{{error_msg}}</div>
<button type="submit" class="btn btn-primary">注册</button>
</form>
</div>
</div>
</ContentBase>
</template>
<script>
import ContentBase from "@/components/ContentBase.vue";
import { ref } from "vue";
import {useStore} from "vuex";
import router from "@/router/index";
import $ from "jquery";
export default {
name: "RegisterView",
components: {
ContentBase,
},
setup() {
const store = useStore();
let username = ref("");
let password = ref("");
let password_confirm = ref("");
let error_msg = ref("");
const register = ()=> {
// error_msg
error_msg.value = "";
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/user/",
type: "POST",
data: {
username: username.value,
password: password.value,
password_confirm: password_confirm.value,
},
success(resp) {
//
if(resp.result == "success"){
//
store.dispatch("login",{
username: username.value,
password: password.value,
success() {
router.push({name: "userlist"});
},
error () {
error_msg.value = "系统异常,请稍后重试!";
}
});
}
else {
//
error_msg.value = resp.result;
}
}
});
};
return {
username,
password,
error_msg,
password_confirm,
register,
};
},
};
</script>
<style scoped>
button {
width: 100%;
}
.error-msg {
font-weight: bold;
color: red;
margin-bottom: 20px;
}
</style>

@ -0,0 +1,99 @@
<template>
<ContentBase>
<div class="card" v-for="user in users" :key="user.id" @click="open_user_profile(user.id)">
<div class="card-body">
<div class="row">
<div class="col-1 img-field">
<!--将冒号后的字符串视为变量而不是一个字符串-->
<img class="img-fluid" :src="user.photo" alt="" />
</div>
<div class="col-11">
<div class="username">{{ user.username }}</div>
<div class="followcount">粉丝数: {{ user.followerCount }}</div>
</div>
</div>
</div>
</div>
</ContentBase>
</template>
<script>
import ContentBase from "@/components/ContentBase.vue";
import $ from "jquery";
import { ref } from "vue";
import router from "@/router/index";
import { useStore } from "vuex";
export default {
name: "UserList",
components: {
ContentBase,
},
setup() {
const store = useStore();
let users = ref([]);
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/userlist/",
type: "get",
success(resp) {
users.value = resp;
},
});
const open_user_profile = (userId) => {
//
if (store.state.user.is_login) {
router.push({
name: "userprofile",
params: {
userId: userId,
},
});
}
else { //
router.push({name: "login"});
}
};
return {
users,
open_user_profile,
};
},
};
</script>
<style scoped>
img {
border-radius: 50%;
}
.username {
font-weight: bold;
height: 40%;
}
.followcount {
font-size: 12px;
color: gray;
height: 60%; /*上下46开*/
}
.card {
margin-bottom: 20px;
cursor: pointer; /*选中卡片变成鼠标变成小手形状*/
}
.card:hover {
box-shadow: 2px 2px 10px lightblue;
transition: 500ms;
}
.img-field {
display: flex;
flex-direction: column;
justify-content: center;
}
</style>

@ -0,0 +1,146 @@
<template>
<ContentBase>
<div class="row">
<div class="col-3">
<!--将user信息传递给子组件的userInfo-->
<!--触发了follow123事件会调用follow函数-->
<!--触发了follow1234事件会调用unfollow函数-->
<UserProfileInfo @follow123="follow" @unfollow1234="unfollow" :userInfo="user" />
<!--父组件的send_msg事件会调用父组件send_msg函数(@某事件="某个函数"事件与函数绑定起来了)-->
<UserProfileWrite v-if="is_me" @send_msg="send_msg" />
</div>
<div class="col-9">
<div class="alert alert-primary" role="alert">
<div class="all-post"> 我的帖子 </div>
</div>
<UserProfilePost :user="user" :posts="posts" @delete_a_post="delete_a_post" />
</div>
</div>
</ContentBase>
</template>
<!--父组件的信息发送给子组件利用prop实现-->
<!--子组件想更新父组件的内容通过emit实现-->
<script>
import ContentBase from "@/components/ContentBase.vue";
import UserProfileInfo from "@/components/UserProfileInfo.vue";
import UserProfilePost from "@/components/UserProfilePost.vue";
import UserProfileWrite from "@/components/UserProfileWrite.vue";
import { reactive } from "vue";
import { useRoute } from "vue-router";
import $ from "jquery";
import {useStore} from "vuex";
import {computed} from "vue";
export default {
name: "UserProfile",
components: {
ContentBase,
UserProfileInfo,
UserProfilePost,
UserProfileWrite,
},
setup() {
const route = useRoute();
const store = useStore();
// id
const userId = parseInt(route.params.userId);
//
const user = reactive({});
const posts = reactive({});
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/getinfo/",
type: "GET",
headers: {
"Authorization": "Bearer " + store.state.user.access,
},
data: {
user_id : userId,
},
success(resp) {
user.id = resp.id;
user.username = resp.username;
user.photo = resp.photo;
user.followerCount = resp.followerCount;
user.is_followed = resp.is_followed;
}
});
$.ajax({
url: "https://app165.acapp.acwing.com.cn/myspace/post/",
type: "GET",
headers: {
"Authorization": "Bearer " + store.state.user.access,
},
data: {
user_id : userId,
},
success(resp) {
posts.count = resp.count;
posts.posts = resp;
}
});
//
const is_me = computed(() => userId === store.state.user.id);
//
const follow = () => {
if (user.is_followed) return; //
user.is_followed = true;
user.followerCount++;
}
//
const unfollow = () => {
if (!user.is_followed) return; //
user.is_followed = false;
user.followerCount--;
}
// content
const send_msg = (content) => {
posts.count++;
//
//
posts.posts.unshift({
id: posts.count,
userId: 2,
content: content,
})
};
// ,post_idpost_id
const delete_a_post = post_id => {
posts.posts = posts.posts.filter(post=> post.id !== post_id);
posts.count = posts.posts.length;
}
return {
user: user,
follow,
unfollow,
posts: posts,
send_msg: send_msg,
is_me,
delete_a_post,
}
}
}
</script>
<style scoped>
.all-post {
font-weight: bold;
font-size: 20px;
color: red;
}
</style>

@ -0,0 +1,4 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})
Loading…
Cancel
Save