前言
主要介绍了用vue框架创建用户动态页面的具体过程,可以帮助学习vue框架的基本知识!!!!
用户动态页面
用户信息
用户头像
通过 Bootstrap 所提供的 .img-fluid 类让图片支持响应式布局。其原理是将 max-width: 100%; 和 height: auto; 赋予图片,以便随父元素的宽度变化一起缩放。
<img src="../assets/log.jpg" class="img-fluid" alt="用户头像">
将头像设置为圆形:
<style scoped>
img{
border-radius: 50%;
}
</style>
用户信息体
<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>
当我们需要动态的获取用户的头像、姓名、粉丝数等信息,我们需要把对象信息放在最高层,这样它的子组件也可以获取信息。
在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。
帖子列表
此时我们需要在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>
<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
发帖子
整体框架
<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>
<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 返回要使用的方法和变量。
总结
主要介绍了用vue框架创建用户动态页面的具体过程,可以帮助学习vue框架的基本知识!!!!