The main functions to be implemented are as follows:

Information list, TAB page switch, article report, channel management, article details, reading memory, focus on function, like function, comment function, reply to comment, search function, login function, personal center, edit information, xiaozhi students…

First review: yesterday we implemented secondary routing, encapsulating time filters, image lazy loading, etc

Today we want to achieve the main function is: the article is not interested in, report function

1 Optimization of token function

1.1 Encapsulating The Token (The token was stored in vuEX, so the token will be cleared every time the page is refreshed and you need to log in again)

Create a new page storage.js in utils

// Encapsulate three operations on tokens (store, delete, Export const saveToken = (tokenObj) => {localstorage.setitem (TOKEN, Json.stringify (tokenObj))} export const getToken = () => {return json.parse (localstorage.getitem (TOKEN))} // Delete  export const delToken = () => { localStorage.removeItem(TOKEN) }Copy the code

1.2 Add the following code to SRC /store/index.js:

+ import {saveToken, getToken} from '@/utils/storage' state: { GetToken () | | {}}, actions: {/ / the context object will automatically incoming, it and store the sample with the same methods and the context object action: the name of the function (context, load) {/ / 1. MIT ('mutation name ', payload)} async setToken (context, async setToken) userInfo) { try { // console.log(2) const { data: { data } } = await login(userInfo) // console.log(data) // console.log(3) context.commit('getToken', Data) // Store the token locally in the browser + saveToken(data) // this.$toast.success(' login succeeded ')} catch (err) {// throw the error to the function that calls the actions new Error(err) } } },Copy the code

This will solve the problem that the token is cleared after each page refresh

2. Start today’s function

2.1 Display of target functions

2.2 Add an x icon to articlelist. vue

<! - the text area - - > < div class = "meta" > < span > {{item. Aut_name}} < / span > < span > {{item.com m_count}} comments < / span > < span > {{ item.pubdate | relativeTime }}</span> <span class="close"> <van-icon name="cross" /> </span> </div>Copy the code

I’m going to style it so that it shows up on the right

.meta { span { margin-right: 10px; } display: flex; Close {// Its parent is flex, and setting the left margin of the current element to auto makes the element at the right of the parent // margin-left: auto; }}Copy the code

2.2 This icon can only be seen when the user logs in, so the decision should be added

Determine whether the token exists in the state variable of VUEX, if so, display, otherwise not display

<span class="close">
   <van-icon name="cross" v-if="$store.state.tokenInfo.token"/>
</span>
Copy the code

2.3 Create click events for the close button

<span class="close"> <van-icon name="cross" v-if="$store.state.tokenInfo.token" @click="hActionMore(item.art_id)" /> </span> methods:{data(){return{isShowMoreAction:false, // Default does not display popup layer articleId:null, }} MoreAction (id) {this.isshowMoreaction = true // Save the current id this.articleId = id},}Copy the code

3 Using the PopUp Component

Because the contents in the pop-up layer are more complex, we split it out as a new component

3.1 insrc/views/home/Create the moreAction. Vue file

<template> <div class="more-action"> <! -- State one --> <van-cell-group> <van-cell> Not interested </van-cell> <van-cell IS-link > Feedback spam </van-cell> <van-cell> Block author </van-cell> </van-cell-group> <! -- Status 2 Feedback --> <van-cell group> <van-cell icon="arrow-left"> Return </van-cell> <van-cell> Infringement </van-cell> <van-cell> Pornography </van-cell> <van-cell> Violence </van-cell> <van-cell> Vulgar </van-cell> <van-cell> Discomfort </van-cell> <van-cell> Error </van-cell> <van-cell> Other </van-cell> </van-cell-group> </div> </template> <script> export default { name: 'MoreAction', } </script>Copy the code

3.2 Establish parent-child component relationship with articlelist. vue

+ import MoreAction from './moreAction'
+ components: {
    MoreAction
  },
Copy the code

Outside the van-pull-Refresh tag (outside the loop)

<! <van-popup v-model="isShowMoreAction" :style="{width: '80%'}"> <MoreAction></MoreAction> </van-popup>Copy the code

3.3 Viewing debugging Tools

The two pop-up layers are displayed together, and we have them displayed separately to show only one

<template> <div class="more-action"> <! + <van-cell-group v-if="! IsReport "> <van-cell> Not interested </van-cell> + <van-cell is-link @click="isReport=true"> </van-cell> <van-cell> shield author </van-cell> </van-cell-group> <! <van-cell group V-else > + <van-cell icon="arrow-left" @click="isReport=false"> Return </van-cell> // omit others </van-cell-group> </div> </template> <script> export default { name: 'MoreAction', data () { return { + isReport: False // Whether to display report}}} </script>Copy the code

4 Implement uninterested functions

4.1 train of thought

  1. To call the interface. Tell the server to stop tweeting similar articles to me.

  2. Close the layer thickness

  3. Delete the article I clicked on.

Deletes the article in the current articleList component

4.2 Using the principle of child to parent (custom events)

Listen for events and callbacks in the parent articlelist. vue

    <van-popup v-model="isShowMoreAction" :style="{ width: '80%' }">
      <moreAction 
+      @un-like="hUnlike"
      ></moreAction>
    </van-popup>
Copy the code

The callback function

async hUnlike () { try { // 1. This. IsShowMoreAction = false // 3. This.$toast.success(' error ')} catch (err) {this.$toast.fail(' error ')}}Copy the code

The child componentsmoreAction.vueThrow event in

<! <van-cell @click="hUnlike"> </van-cell> methods: HUnlike () {this.$emit('un-like')}} {this.$emit('un-like')}}Copy the code

4.3 Encapsulating the request function is called in the previous callback function

insrc/api/article.jsAdd a method to the

export const unLike = (articleId) => {
  return request({
    url: 'v1_0/article/dislikes',
    method: 'POST',
    data: {
      target: articleId
    }
  })
}
Copy the code

call

import { unLike } from '@/api/article.js' async hUnlike () { // 1. Try {await unLike(this.articleid) this.$toast.success(' operation succeeded ') // 2. This.isshowmoreaction = false} Catch (err) {console.log(err) this.$toast.fail(' failed ') }}Copy the code

4.4 Deleting Articles

Later functions may also use this function, so encapsulate it in local methods and call it when used

delAirticle (articleId) { const idx = this.list.findIndex(item => { return item.art_id === articleId }) if (idx ! == -1) { this.list.splice(idx, 1) } },Copy the code

Call (add the following code in the previous delete article)

this.delAirticle()
Copy the code

5 Report articles

5.1 Encapsulation of report Types

The content of the data format that should be passed to the back end is more complicated, so we still wrap it in a new page and create a new reports.js file in SRC /constant/

Const reports = [{value: 0, label: 'Other issues'}, {value: 1, label:' Title exaggeration '}, {value: 2, label: 'vulgar pornography'}, {value: 3, label: 'wrong'}, {value: 4, label: 'old news'}, {value: 5, label:' advertising '}, {value: 5, label: 'advertising'}, {value: 5, label: 'advertising'}, {value: 6, label: 'False content'}, {value: 7, label: 'suspected criminal'}, {value: 8, label: 'infringement'}] export default reportsCopy the code

5.2 Render the page

In moreAction. Vue

Import reports from '@/constant/reports.js' export default {name: 'MoreAction', data () {return {+ reports: reports, isReport: false}},Copy the code
<van-cell-group v-else> <van-cell icon="arrow-left" @click="isReport=false"> Return </van-cell> <van-cell v-for="report in reports" :key="report.value" > {{report.label}} </van-cell> </van-cell-group>Copy the code

Implementation effect

5.3 Implement the function of reporting articles

Repeat the previous parent function (custom event) and listen for events in home/ articlelist. vue.

<more-action ref="moreAction" + @report="hReport" @un-like="hUnlike" ></more-action> // The user clicks one of the hReports (reportTypeId) {console.log(' Received report type is reportTypeId ')}Copy the code

Throw events are summarized in child components

<van-cell
        v-for="report in reports"
        :key="report.value"
        @click="$emit('report', report.value)"
      >
        {{report.label}}
      </van-cell>
Copy the code

5.4 Encapsulation Interfaces

Add a method to SRC/API /article.js

export const report = (articleId, reportType) => {
  return request({
    method: 'POST',
    url: 'v1_0/article/reports',
    data: {
      target: articleId,
      type: reportType
    }
  })
}
Copy the code

In the parent component SRC /home/articlelist. vue, introduce API (delete article function directly call)

import { dislike, report } from '@/api/article.js' async hReport (reportTypeId) { try { // 1. Report await Report (this.articleId, reportTypeId) // 2. Delete this.delarticle (this.articleid) // 3. This. IsShowMoreAction = false this.$toast.success(' operation succeeded ')} Catch (err) {console.log(err) this.$toast.fail(' operation failed ') }}Copy the code

5.5 BUG (when the report page is closed, click again or report page problem)

The open report popup is controlled by isReport in moreAction, we just need to set isReport to false as soon as it opens

This requires the ref attribute (the parent controls the child’s data)

Set isReport to false in the child component

How do I modify the child’s data in the parent?

Ref = ref; this.$refs.xxxx = ref;

Add a ref to the component, and the component is automatically collected into this.$refs.

IsReport is undefined, because the first click of the pop-up layer has not been created, so the error will be determined when it is created after the first time

Add the following code

 <more-action
+        ref="moreAction"
        @un-like="hUnlike"
      ></more-action>
Copy the code
HMoreAction (id) {// 1. Display more operations this.isShowMoreAction = true // 2. This.articleid = id // Get a reference to the subcomponent with ref, then modify the data in the subcomponent with ref // The subcomponent is not created when first opened. If (this.$refs.moreaction) {this.$refs.moreaction. IsReport = false}}Copy the code