Only look not to praise, or only collect not to praise is to play rascal, don’t go after school, I find my brother to pick up you.
Project address:https://github.com/jrainlau/wechat-subscriptor
Download & Run
git clone git@github.com:jrainlau/wechat-subscriptor.git
cd wechat-subscriptor && npm install
npm run dev // run in dev mode
cd backend-server && node crawler.js // turn on the crawler server
open `localhost:8080` in your broswer and enjoy it.
Project introduction
I have paid close attention to many public numbers on WeChat and often browse the contents. However, when I read articles, I was always interrupted by various WeChat messages, so I had to cut them out, reply to the messages, and then click back to the public number all the way to reopen the articles. The cycle was endless and annoying. Later, it occurred to me that WeChat has cooperation with sogou and can directly search for public numbers through sogou. So why not use this resource to make an application dedicated to collecting public numbers? This application can easily search the public number, then store it, and open it directly when you want to see it. Well, in fact, it is not difficult, so we should start from the architecture.
Overall structure
International practice, first look at the architecture diagram:
Then there is the technical selection:
-
The API of sogou is used as the interface for inquiring public numbers.
-
Due to cross-domain problems, it was passed
node
Crawler interface -
Use
vue
To develop,vuex
State management -
Use
mui
As a UI framework, it is convenient to package into mobile phone app in the future. -
Use
vue-cli
Initialize the project and passwebpack
Build
First of all, analyze the red circlevuex
Part of it. It is the core of the whole APP and the processing center of all data.
All components of the client are in theaction
To complete the processing of incoming data (such as asynchronous requests, etc.), and then pass through theaction
Triggermutation
Modifystate
, followed bystate
aftergetter
It is distributed to all components to meet the characteristics of “single data stream” and also conform to the officially recommended practices:
After understanding the most important thingvuex
After that, the rest of the story will come out smoothly. Arrows indicate the flow of data.LocalStorage
The node server is responsible for storing the contents of favorites so that the contents will not be lost when the application is opened next time. The node server is responsible for crawling the data provided by the sogou API according to the keywords.
Is it very simple? Let’s start coding together!
Initialization item
npm install vue-cli -g
Install the latest version ofvue-cli
, and thenvue init webpack wechat-subscriptor
After setting up and installing the dependency package step by step according to the prompts, enter the directory of the project and make minor changes. The final directory structure is as follows:
Please browse the specific contents directly.Projects
Server & Crawler
Enter/backend-server
Folder and create a new one namedcrawler-server.js
The code is as follows:
/*** crawler-server.js ***/
'use strict'
const http = require('http')
const url = require('url')
const util = require('util')
const superagent = require('superagent')
const cheerio = require('cheerio')
const onRequest = (req, res) => {
// CORS options
res.writeHead(200, {'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*'})
let keyWord = encodeURI(url.parse(req.url, true).query.query)
// recieve keyword from the client side and use it to make requests
if (keyWord) {
let resultArr = []
superagent.get('http://weixin.sogou.com/weixin? type=1&query=' + keyWord + '&ie=utf8&_sug_=n&_sug_type_=').end((err, response) => {
if (err) console.log(err)
let $ = cheerio.load(response.text)
$('.mt7 .wx-rb').each((index, item) => {
// define an object and update it
// then push to the result array
let resultObj = {
title: '',
wxNum: '',
link: '',
pic: '',
}
resultObj.title = $(item).find('h3').text()
resultObj.wxNum = $(item).find('label').text()
resultObj.link = $(item).attr('href')
resultObj.pic = $(item).find('img').attr('src')
resultArr.push(resultObj)
})
res.write(JSON.stringify(resultArr))
res.end()
})
}
}
http.createServer(onRequest).listen(process.env.PORT || 8090)
console.log('Server Start!' )
A simple crawler that sends requests to sogou through keywords provided by the client and then uses themcheerio
Analyze and obtain key information. The address of the sogou Public Number search is posted here. You can try it yourself:http://weixin.sogou.com/
When the server is turned on, just bring the parameter requestlocalhost:8090
You can get the content.
UseVuex
State management
Post it firstvuex
Official documents:http://vuex.vuejs.org/en/index.html, believe me, don’t read the Chinese version, or you will step on the pit, the English version is enough.
As can be seen from the previous architecture diagram, all data flows are throughvuex
Yes, I learned about it from the above documents.vuex
After the usage of, we enter/vuex
Folder to build the corestore.js
Code:
/*** store.js ***/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
collectItems: [],
searchResult: {}
}
localStorage.getItem("collectItems")?
state.collectItems = localStorage.getItem("collectItems").split(','):
false
const mutations = {
SET_RESULT (state, result) {
state.searchResult = result
},
COLLECT_IT (state, name) {
state.collectItems.push(name)
localStorage.setItem("collectItems", state.collectItems)
},
DELETE_COLLECTION (state, name) {
state.collectItems.splice(state.collectItems.indexOf(name), 1)
localStorage.setItem("collectItems", state.collectItems)
}
}
export default new Vuex.Store({
state,
mutations
})
Below we will focus on the analysis of the code.
First we define astate
Object, the two attributes in which correspond to favorite content and search results. In other words, the entire APP data is stored instate
Object, take as you like.
Next, we define anothermutations
Object. We can putmutations
To be understood as “for changestate
A series of methods of state “. Invuex
In the concept of “human rights and fundamental freedoms”,state
Only throughmutation
The advantage of modification is that it can manage the application status more intuitively and clearly, instead of throwing data everywhere.
It is not difficult to see through the code, threemutation
The role of respectively is:
-
SET_RESULT
: Store search results instate
-
COLLECT_IT
: Add to Favorite Actions (Includinglocalstorage
) -
DELETE_IT
: Remove from Favorites (includinglocalstorage
)
Component data processing
Our APP has two components.SearchBar.vue
AndSearchResult.vue
, respectively corresponding to the search part component and the result part component. The search component contains favorites, so it can also be understood as having three parts.
Search for some componentsSearchBar.vue
/*** SearchBar.vue ***/
vuex: {
getters: {
collectItem(state) {
return state.collectItems
}
},
actions: {
deleteCollection: ({ dispatch }, name) => {
dispatch('DELETE_COLLECTION', name)
},
searchFun: ({ dispatch }, keyword) => {
$.get('http://localhost:8090', { query: keyword }, (data) => {
dispatch('SET_RESULT', JSON.parse(data))
})
}
}
}
The code is a bit long, so I will only focus on it here.vuex
Part, complete code can refer toProjects.
-
getters
Obtainstore
The data are used for components. -
actions
The two methods of are responsible for distributing data tostore
Chinese supplymutation
Use
Look at the official example, in the component toaction
It seems that it is very complicated to pass the argument, but in fact it can be completely passed.methods
To process parameters, in the triggeractions
At the same time pass in the parameters.
Results partial componentSearchResult.vue
/*** SearchResult.vue ***/
vuex: {
getters: {
wordValue(state) {
return state.keyword
},
collectItems(state) {
return state.collectItems
},
searchResult(state) {
return state.searchResult
}
},
actions: {
collectIt: ({ dispatch }, name, collectArr) => {
for(let item of collectArr) {
if(item == name) return false
}
dispatch('COLLECT_IT', name)
}
}
}
The result part mainly lies in the demonstration and needs to be triggered.action
The only place for this is to add it to favorites. It should be noted that repeated additions should be avoided, so thefor...of
Loops are not added when the current element already exists in the array.
The end
After analyzing the code of the key logic part, this APP is the same thing. The UI part will not go into details. Just look at the source code of the project or DIY yourself. As for packaging into APP, first you need to download HBuilder, then you can package it directly through it and use it together.mui
Can experience better effect, do not know why so many people black it.
The API provided by sogou is very powerful, but remind us not to operate too frequently, or your IP will be blocked by it, mine has been blocked …
Weex
It has already come out. It can be used to build Native applications. It is exciting to think about it. I will finish this project on a whim.Weex
The version of play …
Finally, thank you for reading. If you think my article is good, please pay attention to my column. See you next time!