A new series is out: Vue2 and Vue3 Tips Booklet
Wechat search [Great Relocation to the World], I will share with you the front-end industry trends, learning methods, etc. as soon as possible.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.
Most modern social networks include a feature where users can reply to comments by commenting on that particular comment. If we visualize it, our review data will look like the following structure:
- Comment A
- comment a1
- comment a12
- comment a2
- Comment B
- Comment C
Comment A
has comment a1
and comment a2
. Conversely, comment a1
has comment a12
, which can also have subcomments of its own.
With this structure, we can have an annotation have an infinite number of layers of sub-annotations. You may already be familiar with this method of structuring data, otherwise known as a tree structure. If you don't understand, you can think about the directory on the computer, a folder can have subfolders and so on.
In this lesson, let's take a look at how to use recursive components to manage tree-structured data in Vue. Before introducing recursive components in Vue, let's review what recursion is.
what is recursion
Recursion simply means calling itself. Consider the following function:
function sum_numbers(arr, n) {
return sum_numbers(arr, n - 1) + arr[n - 1];
}
Although somewhat flawed, the above function can be considered a recursive function because it calls itself within the function. However, this definition does not cover everything. Recursion is a way to solve problems. It is based on the premise that given a problem, if we know the solutions to its subproblems, we can find its solutions.
For example, the above sum_numbers
function finds the sum of all numbers in a given array arr = [1, 2, 3, 4, 5]
. In the summation problem, if we know the sum of all numbers before 5
, then we can reduce the problem to the sum of the numbers in arr
equal to the last element and the last element The sum of all previous numbers .
In the sum_numbers
function defined above, the expression return sum_numbers(arr, n - 1) + arr[n - 1];
does exactly what we just described.
To illustrate how the sum_numbers function executes from start to finish with an input [1, 2, 3, 4]
look at the code below:
**sum_numbers([1, 2, 3, 4], 4)
|
calls
|**
**sum_numbers([1, 2, 3], 3) + 4
|
calls
|
sum_numbers([1, 2], 2) + 3
|
calls
|
sum_numbers([1], 1) + 2
|
calls
|
sum_numbers([], 0) + 1 --** 这里有一个问题
Here's a question: our recursive function is trying to add an empty list to a number. In fact, the bigger problem is that our recursive function keeps calling itself indefinitely.
To make sure our recursive function doesn't call itself infinitely, we need a base case. You can think of the base as the point where we want our function to stop calling itself.
In the above example, if sum_numbers
the function has only one number, it should stop calling itself. If there is only one number left in the array, then there is nothing to add to it, in which case we just return that number.
function sum_numbers(arr, n) {
if(n <= 1){ //Base Case
return arr[0];
} else {
return sum_numbers(arr, n - 1) + arr[n - 1];
}
}
Fundamentally, that's what recursion is all about, but how does it relate to Vue's recursive components?
Vue recursive components
Components in Vue are reusable Vue instances. Most of the time, when we create a component in Vue, it's just to be able to reuse it elsewhere. For example, an e-commerce website, we can display products on multiple pages. It is also possible to have a Product Component
that can be rendered on different pages instead of repeating the code Product Component
on every page needed.
A Vue component is considered recursive if it references itself in its own template. Recursive components are different from normal components. In addition to being reused elsewhere, recursive components reference themselves in their templates.
Why would a component reference itself? When you render a component within another component, the object component is the child, and the component rendering it is the parent.
In the case of Product Component
, the component could have ProductReview
as its subcomponent. In this case, it makes sense for us to have two different components for the entities these components represent, since products and reviews are different in every way.
But if we take Comment
and Sub-comment
for example, then it is different. These two components represent the same thing. A subcomment is also a comment. So it doesn't make sense for us to have two different components for Comment
and Sub-comment
because they are structurally the same. We can have only one Comment component that references itself. Or is it too abstract? See the snippet below:
<template>
<li class="comment">
<span>{{ comment.comment }}</span>
<comment v-for="reply in comment.replies" :comment="reply"></comment>
</li>
</template>
<script>
export default {
name: "comment",
props: {
comment: Object
}
};
</script>
Although, the above component can be considered recursive because it references itself. Like recursive functions, recursive components must also have a termination condition, which is missing from the code above. Another important thing to note here is that in order for a component to be able to reference itself, the name
option must be defined.
Now that you understand what recursive components are in Vue, let's see how to use it to build a nested comment interface.
Build a comment interface
Set up the Vue development environment
First, initialize a new Vue project and run the vue create nested-comments
command in the terminal:
vue create nested-comments
After installing according to the prompts, you will get the following directory structure:
Use vue serve
to run the project.
Render nested comments with recursive components
To render nested comments to the DOM, first, delete all files in src/views
and src/components
. Then, create src/components/Comment.vue
, script
with the following contents:
<script>
export default {
name: "recursive-comment",
props: {
comment: {
type: String,
required: true,
},
replies: {
type: Array,
default: () => [],
},
},
};
</script>
In the code snippet above, the component is named recursive component ( recursive-component
). Remember, in Vue, a recursive component must have a declared name
. Additionally, our component expects to pass comment
and replies
props
it wherever it is referenced.
Then, template
content is as follows:
<template>
<li>
<span class="comment">{{ comment }}</span>
<ul class="replies" v-if="replies.length">
<div v-for="(item, index) in replies" :key="index">
<recursive-comment
v-bind="{
comment: item.comment,
replies: item.replies,
}"
/>
</div>
</ul>
</li>
</template>
recursive-comment
Component references itself in its own template. v-if="replies.length"
is the condition for the recursion finally. Once the condition is not established, the recursion is stopped.
Next, just quote it in App.vue
:
<template>
<ul v-for="(item, index) in comments" :key="index" class="comments">
<Comment
v-bind="{
comment: item.comment,
replies: item.replies,
}"
/>
</ul>
</template>
<script>
import Comment from "@/components/Comment";
export default {
data: () => ({
comments: [
{
comment: "First comment",
replies: [
{
comment: "sub-comment 1 for comment 1",
replies: [
{
comment: "sub-sub-comment 1",
replies: [
{
comment: "sub-sub-sub-comment 1",
},
{ comment: "sub-sub-sub-comment 2" },
],
},
{ comment: "sub-sub-comment 2" },
],
},
{ comment: "sub-comment 2 for comment 1" },
],
},
{
comment: "Second comment",
replies: [
{
comment: "sub-comment 1 for comment 2",
replies: [
{ comment: "sub-sub-comment 1" },
{ comment: "sub-sub-comment 2" },
],
},
{ comment: "sub-comment 2 for comment 2" },
],
},
],
}),
components: {
Comment,
},
};
</script>
<style>
.comments ul {
padding-left: 16px;
margin: 6px 0;
}
</style>
Run, the effect is as follows:
Summarize
While our example is not a typical comment component, our goal is to explore how to use the power of recursive components in Vue to render nested data.
We see that we can do this by creating a component that references itself in its own template. This recursive approach is especially useful when rendering data entities that appear to be different but have the same structure. For example, take our comments
and replies
for example.
At first glance, it looks like we need two components, one for comments
and one for replies
. However, recursively, we can render both with a single component. Most importantly, our component renders all comments and replies until it reaches a termination condition.
The bugs that may exist in editing cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. By the way, here is a useful bug monitoring tool , Fundebug .
Author: Nyior Clement Translator: Front-end Xiaozhi Source: logrocket
Original: https://blog.logrocket.com/author/nyiorclement/
comminicate
If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。