【Web开发手礼】探索Web开发的魅力(十二)-Vue(2)用户动态页面


前言

主要介绍了用vue框架创建用户动态页面的具体过程,可以帮助学习vue框架的基本知识!!!!


用户动态页面

Alt

用户信息

Alt

用户头像

通过 Bootstrap 所提供的 .img-fluid 类让图片支持响应式布局。其原理是将 max-width: 100%; 和 height: auto; 赋予图片,以便随父元素的宽度变化一起缩放。

 <img src="../assets/log.jpg" class="img-fluid" alt="用户头像">

将头像设置为圆形:

<style scoped>
img{border-radius: 50%;
}
</style>

Alt

用户信息体

<template><div class="card"><div class="card-body"><div class="row"><div class="col-3"><img src="../assets/log.jpg" class="img-fluid" alt="用户头像"></div><div class="col-9"><div class="username">hgq</div><div class="fans">粉丝:3000</div><button type="button" class="btn btn-info btn-sm" >关注</button></div></div></div></div>
</template><script>
export default{name: 'UserProfileInfo',
}
</script><style scoped>
img{border-radius: 50%;
}
.username{font-weight: bold;
}
.fans{font-size: 12px;color: gray;
}
button{padding: 2px 4px;font-size: 12px;
}
</style>

Alt
当我们需要动态的获取用户的头像、姓名、粉丝数等信息,我们需要把对象信息放在最高层,这样它的子组件也可以获取信息。
在UserProfileView.vue文件中:

<script>
import ContentBase from '@/components/ContentBase.vue';
import UserProfileInfo from '@/components/UserProfileInfo.vue';
import UserProfilePosts from '@/components/UserProfilePosts.vue';
import { reactive } from 'vue';export default{name: "UserProfileView",components: {ContentBase,UserProfileInfo,UserProfilePosts},setup(){const user = reactive({id: 1,username: 'hgq',lastName: 'h',firstName: 'gq',followerCount: 0,is_followed: false});return {user: user}}
}
</script>

reactive 和 setup 函数:

  • reactive 是 Vue 3 Composition API 中的一个函数,用于将普通对象转换为响应式对象。这意味着当对象的属性发生变化时,相关的视图会自动更新以反映这些变化。
  • reactive 是 Vue 3 Composition API 中的一个函数,用于将普通对象转换为响应式对象。这意味着当对象的属性发生变化时,相关的视图会自动更新以反映这些变化。

user 对象:

  • 在 setup 函数中,首先创建了一个名为 user 的响应式对象。这个对象包含了用户的各种信息
    • id: 用户的唯一标识符,这里设置为 1。
    • username: 用户名,设置为 ‘hgq’。
    • lastName 和 firstName: 用户的姓和名,分别设置为 ‘h’ 和 ‘gq’。
    • followerCount: 用户的粉丝数量,初始化为 0。
    • is_followed: 表示当前用户是否被关注,初始化为 false。

return 语句:

  • setup 函数通过 return 返回一个对象,对象中包含了 setup 函数中定义的 user 对象。在 Vue 3 中,通过 return 返回的属性和方法可以在模板中使用,也可以在组件逻辑中进行操作。
<UserProfileInfo v-bind:user="user"></UserProfileInfo>

v-bind:user=“user” 是 Vue.js 中用于将数据从父组件传递到子组件的方式。在这里,user 是一个父组件中定义的数据对象,它将作为 UserProfileInfo 组件的一个名为 user 的属性。
v-bind:user=“user” 可以缩写为 :user=“user”,这是 Vue.js 提供的语法糖,用来简化属性绑定的书写。

子组件获得高级传过来的参数

<div class="col-9"><div class="username">{{user.username}}</div><div class="fans">粉丝:{{user.followerCount}}</div><button type="button" class="btn btn-info btn-sm" >关注</button></div>
<script>
export default{name: 'UserProfileInfo',props: {user: {type: Object,required: true}}
}
</script>

user 的定义为:

  • type: Object 表示这个 user 属性的类型是一个对象。这是 Vue.js 中 props 的一个重要特性,通过类型声明可以进行类型检查,确保传入的数据符合预期的格式。
  • required: true 表示 user 这个属性是必须的,即父组件在使用 UserProfileInfo 组件时必须传递一个 user 对象作为属性。

动态改变,当父级对应的参数修改,子级对应修改

<div class="col-9"><div class="username">{{username}}</div><div class="fans">粉丝:{{followerCount}}</div><button type="button" class="btn btn-info btn-sm" >关注</button>
</div>
<script>
import { computed } from 'vue';
export default{name: 'UserProfileInfo',props: {user: {type: Object,required: true}},setup(props){let username = computed(() => props.user.username);let followerCount = computed(() => props.user.followerCount);return{username,followerCount}}
}
</script>

setup(props) 是 Vue 3 中组合式 API 的一部分,用于设置组件的响应式状态、计算属性、方法等。它接收一个参数 props,用来接收从父组件传递过来的属性数据。

计算属性的创建:

  • computed(() => props.user.username) 和 computed(() => props.user.followerCount) 是使用 computed 函数创建的计算属性。
  • computed 函数接收一个函数作为参数,这个函数返回计算后的值。Vue 3 会自动追踪计算属性所依赖的响应式数据(在这里是 props.user.username 和 props.user.followerCount),并在依赖数据变化时重新计算并更新计算属性的值。

现在我们要实现点击关注按钮,此时按钮变为取消关注,表示已经关注了;点击取消关注,按钮变为关注,表示取消关注了。

<button v-on:click="followed" v-if = "!user.is_followed" type="button" class="btn btn-info btn-sm" >关注</button><button v-on:click="unfollowed" v-if = "user.is_followed" type="button" class="btn btn-info btn-sm" >取消关注</button>

当然我们还得实现具体的followed和unfollowed函数。
UserProfileInfo.vue文件中的user是从父级UserProfileView.vue文件传过去的,此时我们想要修改user的is_followed,那么我们就需要从子级传送值到父级。
子组件向父组件传递信息是通过绑定事件的方法
子类通过触发followed和unfollowed函数来向高级即UserProfilieView.vue界面传达。

 setup(props,context){let username = computed(() => props.user.username);let followerCount = computed(() => props.user.followerCount);const followed = () =>{context.emit('followed');};const unfollowed = () =>{context.emit('unfollowed');};return{username,followerCount,followed,unfollowed}}
}
</script>

父级UserProfilieView.vue界面通过判断子级传过来哪个函数来进行具体的响应。

<UserProfileInfo v-bind:user="user" @followed = "followed" @unfollowed = "unfollowed"></UserProfileInfo><script>
import ContentBase from '@/components/ContentBase.vue';
import UserProfileInfo from '@/components/UserProfileInfo.vue';
import UserProfilePosts from '@/components/UserProfilePosts.vue';
import { reactive } from 'vue';export default{name: "UserProfileView",components: {ContentBase,UserProfileInfo,UserProfilePosts},setup(){const user = reactive({id: 1,username: 'hgq',lastName: 'h',firstName: 'gq',followerCount: 1000,is_followed: true});const followed = () => {if(user.is_followed){return;}user.is_followed = true;user.followerCount++;};const unfollowed = () => {if(!user.is_followed){return;}user.is_followed = false;user.followerCount--;};return {user: user,followed,unfollowed}}
}

UserProfileView 组件,它包含了一个 UserProfileInfo 组件,并向其传递了 user 数据和两个事件 followed 和 unfollowed。

  • 同时,使用 @followed=“followed” 和 @unfollowed=“unfollowed” 将 followed 和 unfollowed 事件绑定到子组件上,以便子组件可以在相应的操作时调用这两个方法。
  • followed 方法用来处理用户关注操作,当用户已关注时,不执行任何操作;否则将 user.is_followed 设置为 true,并增加 followerCount。
  • unfollowed 方法用来处理用户取消关注操作,当用户未关注时,不执行任何操作;否则将 user.is_followed 设置为 false,并减少 followerCount。
    Alt
    Alt

帖子列表

此时我们需要在UserProfileView.vue中先把帖子的内容声明出来,然后再将帖子的内容传到子组件UserProfilePosts.vue中。

<UserProfilePosts v-bind:posts="posts"></UserProfilePosts>
<script>
import ContentBase from '@/components/ContentBase.vue';
import UserProfileInfo from '@/components/UserProfileInfo.vue';
import UserProfilePosts from '@/components/UserProfilePosts.vue';
import { reactive } from 'vue';export default{name: "UserProfileView",components: {ContentBase,UserProfileInfo,UserProfilePosts},setup(){const user = reactive({id: 1,username: 'hgq',lastName: 'h',firstName: 'gq',followerCount: 0,is_followed: false});const posts = reactive({count: 3,posts: [{id: 1,userId: 1,content: 'vue框架练习!!!'},{id: 2,userId: 2,content: '玩梗大赛!!!'},{id: 3,userId: 3,content: '最喜欢的动物!!!'},]});const followed = () => {if(user.is_followed){return;}user.is_followed = true;user.followerCount++;};const unfollowed = () => {if(!user.is_followed){return;}user.is_followed = false;user.followerCount--;};return {user: user,followed,unfollowed,posts}}
}
</script>

将posts作为一个prop传递给名为UserProfilePosts的组件。在Vue中,可以使用v-bind或其简写形式:来传递prop。
在UserProfilePosts组件中接收和使用posts:在UserProfilePosts组件内部,定义posts作为一个prop,并根据需要使用它,类型为 Object,并且必须被传入(required: true)

<template><div class="card"><div class="card-body">{{ posts }}</div></div>
</template><script>
export default{name: 'UserProfilePosts',props: {posts: {type: Object,required: true},}
}
</script><style scoped></style>

Alt

<template><div class="card"><div class="card-body"><!--我们传过来的posts是对象,它的第一个值是count,第二个值是posts--><div v-for="post in posts.posts" :key="post.id"><div class="card single-post"><div class="card-body">{{ post.content }}</div></div></div></div></div>
</template><script>
export default{name: 'UserProfilePosts',props: {posts: {type: Object,required: true},}
}
</script><style scoped>
.single-post{margin-bottom: 10px;
}
</style>
  • div class=“card”> 和
    用来创建一个卡片样式的容器,用于包裹帖子列表。
  • v-for=“post in posts.posts” 遍历传入的 posts 对象的 posts 属性,这个属性应该是一个数组,包含了多个帖子对象。
  • :key=“post.id” 为每个帖子项提供唯一的标识符,Vue 使用这个标识符来高效地更新 DOM。
  • 单个帖子之间的底部间距10px

Alt

发帖子

整体框架

<template><div class="card edit-filed"><div class="card-body"><label for="edit-post" class="form-label">编辑帖子</label><textarea class="form-control" id="edit-post" rows="3"></textarea><button type="button" class="btn btn-primary btn-sm">发帖</button></div></div></template><script>
export default{name: 'UserProfileWrite',}
</script><style scoped>
.edit-filed{margin-top: 10px;
}
button{margin-top: 10px;
}
</style>

Alt

<textarea v-model="content" class="form-control" id="edit-post" rows="3"></textarea>
<script>
import { ref } from 'vue';
export default{name: 'UserProfileWrite',setup(){let content = ref('');return{content: content}}
}
</script>

在模板中使用 v-model 指令将 textarea 组件与 content 双向绑定。这意味着当用户在文本框中输入内容时,content 的值会自动更新;反之亦然。

  • import { ref } from ‘vue’:导入 Vue 3 的 ref 函数,用于创建响应式数据。
  • setup():是 Vue 3 Composition API 的入口点。在这里可以定义组件的数据、方法等。
  • let content = ref(‘’):使用 ref 创建一个名为 content 的响应式对象,初始值为空字符串 ‘’。
  • return { content: content }:将 content 对象暴露出去,以便模板可以访问和绑定它。
<template><div class="card edit-filed"><div class="card-body"><label for="edit-post" class="form-label">编辑帖子</label><textarea v-model="content" class="form-control" id="edit-post" rows="3"></textarea><button v-on:click="posted" type="button" class="btn btn-primary btn-sm">发帖</button></div></div></template><script>
import { ref } from 'vue';
export default{name: 'UserProfileWrite',setup(props,context){let content = ref('');const posted = () => {context.emit('posted',content.value);content.value = "";};return{content: content,posted}}
}
</script><style scoped>
.edit-filed{margin-top: 10px;
}
button{margin-top: 10px;
}
</style>
  • : 使用 v-on 指令绑定 click 事件到 posted 方法,点击按钮时触发 posted 方法。
  • const posted = () => { … }: 定义 posted 方法,在点击按钮时触发。它执行以下操作:
    • 使用 context.emit(‘posted’, content.value) 发送一个自定义事件 ‘posted’,并传递 content.value 作为参数。
    • 清空 content.value,以便下次编辑新帖子时开始空白。
  • return { content, posted }: 在 setup 函数中返回 content 和 posted,使它们能够在模板中使用。
    UserProfileView.vue中部分代码如下:
<UserProfileWrite @posted = "posted"></UserProfileWrite>
const posted = (content) => {posts.count++,posts.posts.unshift({id: posts.count,userId: 1,content: content})};return {user: user,followed,unfollowed,posts,posted}
  • 在父组件中使用了 组件,并且绑定了 posted 事件到父组件的 posted 方法。
  • posted 方法接收一个 content 参数,用于将新的帖子内容添加到 posts 数据中。具体操作包括:
    • posts.count++:增加帖子计数器。
    • posts.posts.unshift({ … }):将新的帖子对象添加到 posts.posts 数组的开头,保证最新的帖子显示在列表顶部。

通过 return 返回要使用的方法和变量。

Alt


总结

主要介绍了用vue框架创建用户动态页面的具体过程,可以帮助学习vue框架的基本知识!!!!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三子棋小程序

一.自定义头文件(game.h) 放入源文件需要用到的标准库头文件和函数的声明 ROW 和COL为棋盘的行和列&#xff0c;三子棋嘛&#xff0c;肯定为3啦 #pragma once #include<stdio.h> #include<String.h> #include<stdlib.h> #include<time.h> #define ROW…

《Java初阶数据结构》----10.<Map和Set---TreeSet和TreeMapHashSet和HashMap >

前言&#xff1a; 大家好&#xff0c;我目前在学习java。我准备利用这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论&#xff01;&#xff01;&#xff01; 喜欢我文…

C/C++大雪纷飞代码

目录 写在前面 C语言简介 EasyX简介 大雪纷飞 运行结果 写在后面 写在前面 本期博主给大家带来了C/C实现的大雪纷飞代码&#xff0c;一起来看看吧&#xff01; 系列推荐 序号目录直达链接1爱心代码https://want595.blog.csdn.net/article/details/1363606842李峋同款跳…

【LeetCode】141.环形链表、142. 环形链表 II(算法 + 图解)

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

AI学习记录 - 本地知识库实现的相关知识

在公司内部实现了个知识库&#xff0c;但这里只介绍在实现知识库的过程中用到的知识。 1、分词器 先分词&#xff0c;中文可以使用jieba分词 2、构造数据集 将词汇向量化是自然语言处理中的重要任务&#xff0c;它可以将文本数据转化为计算机能够理解和处理的向量形式。以…

在react中如何计算本地存储体积

1.定义useLocalStorageSize钩子函数 // 计算localStorage大小 function useLocalStorageSize() {const [size, setSize] useState(0);useEffect(() > {const calculateSize () > {let totalSize 0;for (let key in localStorage) {//过滤掉继承自原型链的属性if (loc…

抄作业-跟着《React通关秘籍》捣鼓React-playground-上集

文章目录 前言1. 搭建react 开发环境2、react hooks 知识3. 目标&#xff1a;跟着小册实现 react-playground3.1 整体布局初始化项目使用Alloment 来实现左右分屏的拖拉功能 3.2 代码编辑器Monaco Editor 3.3 实现了多文件的切换用 useContext 来共享数据。优化 tab的样式&…

扫雷游戏小程序

目录 一.文件 1.头文件 2.源文件 二.游戏界面和执行(test.c) 三.函数实现(void game部分,源文件game.c) 1.定义雷二维数组和展示二维数组 2.初始化地雷数组 3.初始化显示的数组 4.显示当前的情况 5.随机放置地雷 6.排雷 ps:深度优先遍历数组 四.结束 一.文件 1.头…

《Single-Stage Extensive Semantic Fusion for multi-modal sarcasm detection》

系列论文研读目录 文章目录 系列论文研读目录文章题目含义ABSTRACTKeywords1. Introduction2. Related work3. Method3.1. Multi-modal projection 多模态投影3.2. Extensive Semantic Fusion Multiway Transformer 可拓语义融合多路Transformer3.3. Multi-objective optimizat…

LeetCode 热题 HOT 100 (011/100)【宇宙最简单版】

【图论】No. 0200 岛屿数量 【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xf…

DjangoRF-10-过滤-django-filter

1、安装pip install django-filter https://pypi.org/ 搜索django-filter基础用法 2、进行配置 3、进行内容调试。 4、如果碰到没有关联的字段。interfaces和projects没有直接关联字段&#xff0c;但是interface和module有关联&#xff0c;而且module和projects关联&#x…

linux下使用yum安装mysql

本文使用常规方式手动安装mysql 第一步 下载mysql的repo源 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm第二步 安装mysql-community-release-el7-5.noarch.rpm包 rpm -ivh mysql-community-release-el7-5.noarch.rpm第三步 安装mysql-server yum -y…

Esp_server 安卓嵌入壳子,原创! 2024/7/28 20:58

用到的软件: uni-app 思路: 让用户感觉是,一个完整的程序.实际上只是一个类浏览器壳子.轻便小巧. 由于是第一次用uni-app开发类软件,所以前前后后耗费7小时! 隔行如隔山,不是白讲的. 软件界面: 软件功能: 简化输入: 输入ip地址,例:http:// www.baidu.com 完整网址 前面…

Javaer 5分钟入门 Golang

文章目录 前言一个 go 文件长啥样&#xff1f;Go 语言的变量变量类型变量声明 Go 语言的函数&方法Go 语言没有的概念访问修饰符面向对象模型异常处理机制 Go 语言高效简洁的并发编程总结 前言 这两年主流的编程语言 Golang&#xff0c;想必大家或多或少都接触过。云原生领…

使用 Docker Compose 部署 RabbitMQ 的一些经验与踩坑记录

前言 RabbitMQ 是一个功能强大的开源消息队列系统&#xff0c;它实现了高效的消息通信和异步处理。 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验。 特点 成熟&#xff0c;稳定消息持久化灵活的消息路由高性能&#xff0c;高可用性&#xff0c;可扩展性高支…

【PYTHON】多进程运行示例含共享数据

运行结果 Python多进程调用示例 import multiprocessing import time import os import sys# 注册多个函数用于不同进程分别调用 def testcase0():time.sleep(1)return "case0_"get_time()def testcase1(timestamp):return "case1_"timestampdef testcase…

Python | TypeError: ‘float’ object is not subscriptable

Python | TypeError: ‘float’ object is not subscriptable 在Python编程中&#xff0c;遇到“TypeError: ‘float’ object is not subscriptable”这一错误通常意味着你尝试对浮点数&#xff08;float&#xff09;使用了下标访问&#xff08;如数组或列表那样的访问方式&a…

Mindspore框架循环神经网络RNN模型实现情感分类|(四)损失函数与优化器

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…

探索 Blockly:自定义积木实例

3.实例 3.1.基础块 无输入 , 无输出 3.1.1.json var textOneJson {"type": "sql_test_text_one","message0": " one ","colour": 30,"tooltip": 无输入 , 无输出 };javascriptGenerator.forBlock[sql_test_te…

数据结构:二叉树(堆)的顺序存储

文章目录 1. 树1.1 树的概念和结构1.2 树的相关术语 2. 二叉树2.1 二叉树的概念和结构2.2 二叉树的特点2.3 特殊的二叉树2.3.1 满二叉树2.3.2 完全二叉树 2.4 二叉树的性质 3. 实现顺序结构二叉树3.1 堆的概念和结构3.2 初始化3.3 销毁3.4 插入数据3.5 向上调整算法3.6 删除数据…