b station to watch the video, to make a summary
Video address: https://www.bilibili.com/video/BV18A411J7QT?p=21&spm_id_from=pageDriver
Technology selection
- vue + vue-router
- Network request axios
- Style layout: vant + less + vw/vh + flex + percentage layout
- Store locallstorage
Personal artificial technical knowledge points
route
Route load
const login = ()=> import ('../views/login') { path: '/login', component: login, }
Routing permission verification
// Use navigation guard to control access rights and dynamic titles router.beforeEach((to, from, next) => { /* When the route changes, modify the page title */ if (to.meta.title) { document.title = to.meta.title // Display of page title } const tokenStr = window.localStorage.getItem('Mail') if ((to.path === '/login' || to.path === '/registered') && tokenStr) { // console.log('There's nothing missing, just tune it to the protagonist ') return next('/create') } if (to.path === '/login' || to.path === '/registered') return next() if (!tokenStr) return next('/login') // If you enter the address of the main interface, but there is no token, you will return to the login page next() // Finally, be sure to next some })
Encapsulation of input
<template> <div> <van-field v-model="text" :label="label" :placeholder="placeholder" :rule="rule" :type="type" autofocus /> </div> </template> <script> export default { props: ["label", "placeholder", "rule", "type"], data() { return { text: "", }; }, methods: {}, watch: { text() { this.$emit("handleChange", this.text); }, }, }; </script> <style lang="less" scoped> </style> use <login-text label="Account number 2" placeholder="Please enter the account number" rule="^.{6,16}$" @handleChange="(res) => (model.username = res)" ></login-text>
The subtlety is that when I first talked about the input box, I thought of listening to events to observe the input parameters
But it's great to use watch to listen to the bound data. And pass the data to the parent component through $emit. Parent component reception is also great@ handleChange = res => model. username
This has the advantage that each input box can receive the correct data
If you write in the traditional way
@handleChange = handleChange handleChange (res) { this.model.username = res // In this way, you don't know how the transmitted data corresponds to the data in the input box. You have to use three events to receive it }
Use of slots
Why use slots: if some data is the same, the encapsulated components can write. If some data is different, then use slots to customize the data
Like this
The left side is the same. The components are handled uniformly, but the right side needs to display numbers, strings and pictures. So many uncertain factors, you have to use slots
Define named slots <slot name="right"> </slot> use <div name="right"></div>
Processing of upload components
<van-uploader :after-read="afterRead" />
The problem is that the components are like this
But this is what I want
Give him a layer, transparency 0 Width 100vw. position absolute
Parent element, overflow: hidden position: relative
<div class="uploadfile"> <div class="uploadimg"><van-uploader preview-size="100vw" :after-read="afterRead" /></div> <edit-banner left="head portrait"> <img :src="model.user_img" slot="right" alt="" v-if="model.user_img"> <img src="@/assets/default_img.jpg" slot="right" alt="" v-else> </edit-banner> </div> .uploadfile{ overflow: hidden; position: relative; .uploadimg{ opacity: 0; position: absolute; } }
After uploading the picture, remember to request the interface again, because now it is only the front-end display, not the real data at the back-end
Value Passing: String
Parent component left = "222"
Subcomponents
Pass string
Parent component left = "222"
Subcomponents
vant calls to other components
<div class="edit-banner" @click="handleEdit"> <div>{{ left }}</div> <div> <slot name="right"></slot> </div> </div> </template> <script> export default { props: ["left"], methods: { handleEdit() { this.$emit("handleEdit"); }, +++++++++++++++++++++++++ <edit-banner left="full name" @handleEdit="isGener = true"> <div slot="right">Li Si</div> </edit-banner> <div class="upload-file"> <div class="upload-img"> <van-uploader :after-read="afterRead" preview-size="100vw" /> </div> <edit-banner left="Upload Avatar" @handleEdit="isVantor = true"> <div slot="right"> <img src="" alt="" /> </div> </edit-banner> </div> <edit-banner left="nickname" @handleEdit="ismodel = true"> <div slot="right">floret</div> </edit-banner> <div class="editback" @click="$router.back()">Return to personal Center</div> <van-action-sheet v-model="isGener" :actions="actions" @select="onSelect" cancel-text="cancel" close-on-click-action @cancel="onCancel" /> <van-dialog v-model="ismodel" title="title" show-cancel-button> <van-field v-model="value" placeholder="enter one user name" /> </van-dialog> </div>
Some adaptive units
Traditional px, em,%
px:
em: inherit the font size of the parent element
rem: relative to root element (html)
vw: window relative to view
%: parent element
Caching of specific pages
Some pages need to be cached, and some pages do not need to be cached (keep the original state after refreshing)
In router:
meta:{ keepalive: true }
On app JS Li
<keep-alive v-if ="$route.meta.keepalive"> </App> </keep-alive> <router-view v-if="!$route.meta.keepalive"></router-view>
Transformation of data
const res = res.data this.getData = this.changeCategory(res) changeCategory(data) { const q = data.map((item,index)=>{ item.XXX = xxx return item }) return q }
Monitor routing changes
watch:{ $route(){ this.getData() } }
input
Recursive data
Idea: now the data is a level relationship, and null is a level 1 comment. Below is the cost_ ID and parent_ Correspondence of ID
Let's start with a simple recursion
Call yourself and have termination conditions
The thickness of a piece of paper is 0.1mm. How many times to fold it in half, its thickness can be 1000mm
let a = 0.1 let num = 0 function n () { a*=2 num++ console.log(num) if (a< 10000) { fn() } }
Deletion and addition of data
Add before delete this.del.push(this.new[index]) this.new.splice(index, 1)
The display of tag data is in the form of storage, which is matched with the listening attribute
watch:{ newCat () { localStorage.setItem('newCat', JSON.stringify(this.newCat)) localStorage.setItem('delCat', JSON.stringify(this.delCat)) } }
created() { if(localStorage.getItem('newCat')&&localStorage.getItem('delCat')) { this.newCat = JSON.parse(localStorage.getItem('newCat')) this.delCat = JSON.parse(localStorage.getItem('delCat')) return } this.SelectCategory()
Direct route jump
@click = "$router.push('/edit')"