Vue開發中遇到的問題
1、選中二級路由高亮時保持它的父路由也保持高亮
給路由添加前置守衛beforeEach(to,from,next) ,在路由前置守衛中判斷要去的路徑信息,如果是二級路由,則給一級路由也加上高亮樣式
直接在路由跳轉標簽中獲取路徑信息,判斷是否需要添加高亮樣式
2、使用? keep-alive 包裹動態組件時數據發生重復渲染
直接把<keep-alive></keep-alive>干掉或者使用exclude屬性讓他直接重新渲染
keep-alive 的三個參數:
include:包含的組件(只有匹配的組件可以被緩存)
exclude:排除的組件(只有匹配的組件不會被緩存)
max:緩存組件的最大值
keep-alive可以包裹<route-view></route-view>使用,也可以配合<Component? :is="aaa"></Component>使用 (其中aaa為動態組件的名稱)
3、vue3.x中廢棄了filter過濾器
vue3.x中新增了setup(),數據、方法、生命周期都定義在了setup()中,響應式數據使用 ref 和 active 包裹
生命周期的名稱也發生了變化,如:beforedestory --> onUnmounted , mounted --> onMounted 并且使用前都需要先從vue中導入
在視圖中需要使用的數據和方法都需要在setup()最后return出去才可以使用
4、vant組件庫 自定義輪播圖大小時 添加外邊距 輪播圖最后一頁顯示不完全
在導入vant庫中的輪播圖 自定義輪播圖大小時,如果加上外邊距,會把最后面的幾個選項擠出范圍導致顯示不全
在使用tab標簽頁時設置寬度,然后向內壓縮形成margin的效果,內容可以顯示完全
5、vant組件庫底部Tabber標簽欄開啟路由模式后,路由跳轉會報錯
問題描述: 使用vant的tabber標簽欄的路由跳轉時,路由可以跳轉,但是會拋出一個錯誤
問題原因:vant與新版本路由不匹配
解決方法:降低路由版本vue-router@3.0.0
6、移動端使用插件進行rem適配
插件:postcss-pxtorem、lib-flexible
// yarn add amfe-flexible
// yarn add postcss-pxtorem@5.1.1
// 在main.js中 導入import 'amfe-flexible'
// 創建postcss.config.js文件,配置
module.exports={
plugins: {
'autoprefixer': {
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
? ?? ]
?? },
'postcss-pxtorem': {
rootValue:37.5,
propList: ['*']
?? }
? }
}
7、數據已經拿到但是頁面渲染不出來,在下一次嘀嗒也沒有作用、vue不支持 ?. 的寫法
因為vue不支持 ?. 的寫法
所以如果想要拿到數據并成功渲染需要添加一層判斷 && 表示數據得到后渲染
obj.arr[0] && obj.arr[0].name
8、props父子組件傳值,當接收的數據類型是對象或者數組時 default需要設置為 ()=> {} 、()=>[]的形式
props: {
tableConfig: {
type: Array,
default: () => [
{ label: '日期', prop: 'date' },
{ label: '姓名', prop: 'name' },
{ label: '地址', prop: 'address' }
]
}
}
9、@后添加路徑
// 項目根目錄創建jsconfig.json文件
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"target": "ES6",
"module": "commonjs",
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
10、單行、多行文本溢出省略號代替
/* 單行文本溢出隱藏 省略號代替 */
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* 多行文本溢出隱藏 省略號代替*/
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
/*設置對其模式*/
-webkit-line-clamp: 2;
/*設置多行的行數*/
11、通過cdn引入減小打包體積,配置vue.config.js
module.exports = {
// 發布模式
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
// 通過CDN加載
config.set('externals', {
vue: 'Vue',
axios: 'axios',
echarts: 'echarts',
"element-ui": 'ElementUI',
"vue-quil-editor": 'VueQuillEditor'
})
config.plugin('html').tap(args => {
args[0].isProd = true
return args
})
})
}
}
// 利用webpack的externals,把第三方庫的js文件從打包文件里去掉
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'axios': 'axios',
'element-ui':'ElementUI'
}
12、element-ui中的el-scrollbar
// 外層用一個標簽包裹并設置寬高,給el-scrollbar標簽必須設置height:100%
// 內容區
// 設置樣式時必須添加穿透
.box {
height: 300px;
width: 200px;
}
::v-deep .el-scrollbar__view {
padding-top: 60px;
}
::v-deep .el-scrollbar__wrap {
overflow-x: hidden;
}
13、vue初始化頁面閃動問題
使用vue開發時,在vue初始化之前,由于div是不歸vue管的
所以我們寫的代碼在還沒有解析的情況下會容易出現花屏現象,看到類似于{{message}}的字樣,雖然一般情況下這個時間很短暫,但是還是有必要讓解決這個問題的。
首先:在css里加上以下代碼:
[v-cloak] { display: none;}
如果沒有徹底解決問題,則在根元素加上style="display: none;" :style="{display: 'block'}"
React開發中遇到的問題
1、移動端使用插件vw適配
插件: postcss-px-to-viewport
在react項目中想要配置vw,先將webpack配置暴露出來yarn eject
git提交保存版本
在config的webpack.congfig.js中配置
require('postcss-px-to-viewport')({
viewportWidth: 375, // (Number) The width of the viewport.
viewportHeight: 667, // (Number) The height of the viewport.
unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
viewportUnit: "vw", // (String) Expected units.
selectorBlackList: [], // (Array) The selectors to ignore and leave as px.
minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
mediaQuery: false // (Boolean) Allow px to be converted in media queries.
}),
2、react數據拿到但是頁面渲染不出來
為了節約性能,在類組件的render函數里 return模板之前先根據數據進行一層判斷,如果想要的數據還沒有拿到,直接return null;
在函數組件中 return之前加上同樣的判斷,如果數據還沒有拿到就return null;
3、react路由6.x和5.x
路由6.x不再有withRouter,于是在類組件中通過this.props無法拿到路由信息,這時我們便需要封裝HOC高階組件后在類組件中使用
路由6.x在定義路由信息的時候,掛載需要使用標簽內的element={}
路由5.x則可以直接在閉合標簽內部直接使用 ,或者是用標簽中的component={}
4、react的鉤子hooks
在類組件中沒有hook,hook只能在函數組件中使用,但是我們可以通過封裝HOC(高階組件)使類組件中擁有函數組件的hook功能,其中最明顯的用處是拿到路由信息
5、類組件中想要在this.props中獲取路由信息,封裝高階組件
// 創建withRouter.jsx文件,配置
// 引入需要用到的模塊
import { useParams, useLocation, useNavigate, useSearchParams } from "react-router-dom";
// withRouter本質上就是一個組件,它的特點:它的參數是一個組件,它的返回值是一個新組件。
// 我們稱這樣的組件是HOC(High Order Component高階組件),高階組件本質上就是一個閉包的應用
export default function withRouter(Component) {
// 相當于給Student組件添加各種props屬性,還添加三個重要的屬性params,location,navigate
return (props) => (
{...props}
searchParams={useSearchParams()} // 通過里面的get方法可以獲取路徑里傳遞的參數,不需要自己切割
params={useParams()} // 獲取參數
location={useLocation()} // 查看路徑信息
navigate={useNavigate()} // 允許跳轉其他頁面
/>
);
}
6、react 函數組件修改數據方法? 數據刷新數據繼續請求變得更多
建議使用 :
a、箭頭函數 setState((pre)=>([...pre],...res.data))? // 用() 包裹,不是{}
b、擴展重新賦值 setState([...state, ...res.data])
7、redux
import { createStore } from 'redux'
let store =? createStore((state, action) => {
switch (action.type) {
case "setNational": {
return {
...state,
national: action.national
}
break
}
default: {
return {
national: '全國'
}
}
}
})
export default store;
// 獲取數據
store.getState().national
// 修改
this.$store.dispatch({
type: 'setNational',
national: name
})
小程序遇到的問題
輪播圖響應式布局
輪播圖下放置的圖片 <image src="" / >標簽上 添加mode="widthFix"高度根據寬度自適應
<image src="" mode="widthFix" />
樣式中設置圖片寬度100%
swiper image {
width: 100%;
}
但是由于swiper自身有高度,所以換更大屏幕時,圖片仍然顯示不完全,給swiper根據圖片設置高度
// 設計稿iphone6,假設圖片高度150px,則swiper設置高度300rpx
swiper {
height: 300rpx;
}
懶加載獲取到數據總數后 判斷列表長度===total時return但是沒有結束
需要把請求過來的數據里的數據總數進行類型轉換 Number(res.total)才能進入判斷
粘性
cnpm i @miniprogram-component-plus/sticky
使用mp-slideview組件時,添加的提示文字消失不見
// 例如: 左滑可以刪除功能,但是刪除兩個字顯示不出來
標簽中間的內容有圖片的時候如果圖片模式 mode=“widthFix” 會導致左滑顯示的刪除按鈕上內容不顯示
可以設置 mode="aspectFit" 自己定義圖片大小
封裝請求
// 封裝文件夾util/request.js文件
// isHeader判斷是否需要獲取響應頭中的數據
function request(obj, isHeader) {
// 顯示loading
return new Promise((resolve, reject) => {
wx.showLoading({
title: '正在加載中',
})
wx.request({
...obj,
url: 'http://localhost:5000' + obj.url,
success: (res) => {
// console.log(res.header["X-Total-Count"]);
if (isHeader) {
resolve({
list: res.data,
total: res.header["X-Total-Count"]
})
} else {
resolve(res.data);
}
},
fail: (err) => {
reject(err)
},
complete: () => {
// 隱藏loading
wx.hideLoading({
success: (res) => { },
})
}
})
})
}
export default request;
封裝權限管理
// 調用時傳入一個回調函數
function CheckAuth(callback) {
if (wx.getStorageSync('tel')) {
// 直接執行回調函數
callback()
} else {
// 是否存在token
if (wx.getStorageSync('token')) {
// 跳轉綁定手機頁面
wx.navigateTo({
url: '/pages/telform/telform',
})
} else {
// 跳轉綁定微信頁面
wx.navigateTo({
url: '/pages/auth/auth',
})
}
}
}
export default CheckAuth;
// 在生命周期onShow中調用例子,傳入一個回調函數作為參數
CheckAuth(() => {
let { nickName } = wx.getStorageSync('token')
let tel = wx.getStorageSync('tel')
request({
url: url
}).then(res => {
console.log(res)
this.setData({
list: res
})
})
})