In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail what are the front-end knowledge points of the vue project, and the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
After Wechat authorization, you can also return to the authorization page through the browser return key.
In the navigation guard, you can set replace: true in next ({}) to redirect to rerouting, the same as router.replace ().
Router.beforeEach ((to, from, next) = > {if (getToken ()) {.} else {/ / stored address for authorization to jump back to setUrl (to.fullPath) next ({path:'/ author', replace: true})})
The page does not automatically return to the top when the route is switched.
Const router = new VueRouter ({routes: [...], scrollBehavior (to, from, savedPosition) {return new Promise ((resolve, reject) = > {setTimeout () = > {resolve ({x: 0, y: 0})}, 0)})})
The ios system will not automatically rebound when the Wechat browser input loses focus.
The initial solution is to bind onblur events on input, but the disadvantage is that you have to bind multiple times, and some input exists in third-party components, so you can't bind events.
The later solution was to bind the focusin event globally, because the focusin event can bubble and be captured by the outermost body.
Util.wxNoScroll = function () {let myFunction let isWXAndIos = isWeiXinAndIos () if (isWXAndIos) {document.body.addEventListener ('focusin', () = > {clearTimeout (myFunction)}) document.body.addEventListener (' focusout', () = > {clearTimeout (myFunction) myFunction = setTimeout (function () {window.scrollTo ({top: 0, left: 0, behavior: 'smooth'})} Function isWeiXinAndIos () {let ua =''+ window.navigator.userAgent.toLowerCase () let isWeixin = / MicroMessenger/i.test (ua) let isIos = /\ (I [^) ] +; (U;)? CPU.+Mac OS X/i.test (ua) return isWeixin & & isIos}}
An error is reported when the value passed by the parent component is modified in the child component
Props in vue is one-way bound, but if the type of props is an array or object, the console will not warn you to change the value of props within the subcomponent. Because arrays or objects are address references, it is officially not recommended to change the value of the parent component within the child component, which violates the idea of props one-way binding in vue. So you need to use $emit when changing the props value, and it's easier to use the .sync modifier.
/ / this.$emit ('update:title', newTitle) / / use the Wechat JS-SDK API to upload pictures in the parent component
First, call wx.chooseImage () to guide users to take pictures or select pictures from mobile phone albums. If you successfully get the localId of the image, call wx.uploadImage () to temporarily store the local image on the Wechat server and return the server-side ID of the image, and then request the backend upload API to get the server address of the image.
ChooseImage (photoMustTake) {return new Promise (resolve = > {var sourceType = (photoMustTake & & photoMustTake = = 1)? ['camera']: [' album', 'camera'] wx.chooseImage ({count: 1, / / default 9 sizeType: [' original', 'compressed'], / / you can specify whether it is the original image or a compressed image. By default, both have sourceType: sourceType, / / you can specify whether the source is a photo album or a camera, and by default both have success: function (res) {/ / return the local ID list of the selected photos LocalId can display the picture wx.uploadImage ({localId: res.localIds [0], isShowProgressTips: 1, success: function (upRes) {const formdata= {mediaId:upRes.serverId} uploadImageByWx (qs.stringify (formdata)) .then (osRes = > {resolve (osRes.data)})}, fail: function (res) {/ / alert (JSON.stringify (res)) as the src attribute of the resolve tag. }});})
The treatment of disconnection and reconnection in chat room
Because the automatic disconnection time is set at the back end, the socket disconnection is required to reconnect automatically.
In the following attributes of data, beginTime represents the current real time, which is used to synchronize with the server time. OpenTime represents the creation time of socket, which is mainly used to determine paging and reconnection, and reconnection indicates whether to disconnect and reconnect.
Data () {return {reconnection: false, beginTime: null, openTime: null}}
When initializing the socket connection, the openTime is assigned to the current local time. After the socket connection is successful, the beginTime is assigned to the current time returned by the server, and then a timer is set to keep the time consistent with the server.
When sending messages, when there are multiple users, each user has a different local time of the system, which will cause the messages to be out of order. So you need to send beginTime parameters to record the time the user sent, and each user's beginTime is synchronized with the server time, which can solve this problem.
Chat rooms need to be paged, and the paging data varies at different times. For example, there are 10 messages at the current time, and 2 new data are added the next time. Therefore, when you request paging data, pass the openTime parameter, which means the query benchmark is based on the time when the socket was created.
/ / create socketcreateSocket () {_ that.openTime = new Date () .getTime () / record socket creation time _ that.socket = new WebSocket (...)} / / socket connection returned status COMMAND_LOGIN_RESP (data) {if (10007 = = data.code) {/ / login success this.page.beginTime = data.user.updateTime / / login time this.timeClock ()}} / / Update the clock of login time timeClock () {this.timer = setInterval (() = > {this.page.beginTime = this.page.beginTime + 1000}) 1000)}
When the socket is disconnected, it is determined whether the current time of the beginTime is more than 60 seconds, and if it does not exceed the description, it will not be disconnected normally.
_ that.socket.onerror = evt = > {if (! _ that.page.beginTime) {_ that.$vux.toast.text ('Network busy Please try') return false} / / do not reconnect if (this.noConnection = = true) {return false} / / socket disconnect reconnect var date = new Date (). GetTime () / determine whether the disconnection time exceeds 60 seconds if (date-_ that.openTime > 60000) {_ that.reconnection = true _ that.createSocket ()}}
The first authorization problem when sending audio
When sending audio, the first click will pop up to prompt authorization, and wx.startRecord () will be executed regardless of whether you click allow or reject, so there will be a problem when you call the recording again (because the previous recording did not end). Because the recording method is triggered by the touchstart event, you can use the touchcancel event to capture the status of the pop-up prompt authorization.
_ that.$refs.btnVoice.addEventListener ("touchcancel", function (event) {event.preventDefault () / / manually trigger touchend _ that.voice.isUpload = false _ that.voice.voiceText = 'hold down' _ that.voice.touchStart = false _ that.stopRecord ()})
The timer was not emptied when the component was destroyed
After the component instance is destroyed, setInterval () continues to execute and needs to be cleared manually, otherwise it will take up memory.
Mounted () {this.timer = () = > {...}, 1000)}, / / finally clears the timer beforeDestroy () {clearInterval (this.timer) this.timer = null} during the life cycle of beforeDestroy ()
Changes in watch listener objects
Watch: {chatList: {deep: true, / / change of listening object handler: function (newVal,oldVal) {...}
Backstage management system template problem
Because the backend management system adds menu permissions, routes are generated dynamically according to menu permissions. When there is only one menu permission, the menu may not be displayed. See the source code of the template:
{{generateTitle (item.children [0] .meta.title)}} {{generateTitle (item.meta.title)}} {{generateTitle (child.meta.title)}}
Where vMuif= "hasOneShowingChildren (item.children) & &! item.children [0] .children & &! item.alwaysShow" indicates that a special menu style is displayed when the node has only one child element and the first child element of the node has no child elements. The problem is that item.children [0] may be a hidden menu (item.hidden = true), so when this expression holds, it may render a hidden menu. Referring to the latest background source code, the author has fixed this problem.
Methods: {hasOneShowingChild (children = [], parent) {const showingChildren = children.filter (item = > {if (item.hidden) {return false} else {/ / Temp set (will be used if only has one showing child) this.onlyOneChild = item return true}}) / / When there is only one child router The child router is displayed by default if (showingChildren.length = 1) {return true} / / Show parent if there are no child router to display if (showingChildren.length = 0) {this.onlyOneChild = {... Parent, path:'', noShowingChildren: true} return true} return false}}
Creation of dynamic components
Sometimes we have a lot of similar components, only a little bit different, we can write such similar components into the configuration file, dynamically create and reference components
Var vm = new Vue ({el:'# example', data: {currentView: 'home'}, components: {home: {/ *... * /}, posts: {/ *... * /}, archive: {/ *... * /})
Dynamic menu permissions
Since menus are generated dynamically based on permissions, the default route requires only a few pages that do not require permission judgment, and the routes for other pages are placed in a map object asyncRouterMap
Set role to the code corresponding to the permission
Export const asyncRouterMap = [{path:'/ project', component: Layout, redirect: 'noredirect', name:' Project', meta: {title: 'project management', icon: 'project'}, children: [{path:' index', name: 'Index', component: () = > import (' @ / views/project/index'), meta: {title: 'project management' Role: 'PRO-01'}}
According to the judgment of the navigation guard, if there is a token and store.getters.allowGetRole indicating that the user has logged in, routers is the routing tree generated by the user according to the permissions. If it does not exist, call store.dispatch ('GetMenu') to request the user's menu permissions, and then call store.dispatch (' GenerateRoutes') to parse the obtained menu permissions into the routing structure.
Router.beforeEach ((to, from Next) = > {if (whiteList.indexOf (to.path)! =-1) {next ()} else {NProgress.start () / / determine whether there is a token and allow users to enter the menu list if (getToken () & & store.getters.allowGetRole) {if (to.path ='/ login') {next ({path:'/'}) NProgress.done ()} else {if (! store.getters.routers.length) {/ / pull user menu permissions store.dispatch ('GetMenu'). Then () = > {/ / generate accessible routing table store.dispatch (' GenerateRoutes'). Then () = > {router.addRoutes (store.getters.addRouters) next ({... to) Replace: true})} else {next ()}} else {next ('/ login') NProgress.done ()})
Actions in store
/ / obtain dynamic menu permissions GetMenu ({commit, state}) {return new Promise ((resolve, reject) = > {getMenu () .then (res = > {commit ('SET_MENU', res.data) resolve (res)}) .catch (error = > {reject (menu)})}, / / generate corresponding menu GenerateRoutes ({commit) based on permissions State}) {return new Promise (resolve = > {/ / Route mounted asynchronously in a loop var accessedRouters = [] asyncRouterMap.forEach ((item, index) = > {if (item.children & & item.children.length) {item.children = item.children.filter (child = > {if (child.hidden) {return true} else if (hasPermission (state.role.menu)) Child) {return true} else {return false}})} accessedRouters [index] = item}) / / Save the processed route to vuex commit ('SET_ROUTERS', accessedRouters) resolve ()})}
Deployment and version switching of the project
At present, the project has two environments, one is the test environment and the other is the production environment. The requested interface address is allocated in\ src\ utils\ global.js. When deploying the production environment, you only need to merge the code of the develop branch into the master branch, and global.js does not need to change the address.
What are the front-end knowledge points about the vue project shared here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.