1.vueフレームワーク上の注意と経験
この記事では、開発VUEプロジェクトが踏ま、フォローアップしますその後、簡単にポストリカバリディスクへの更新、希望のヘルプあなたがいくつかの実践的な経験とピットの一部をまとめたもの
Vueの1.1は、動的ルーティングパラメータを解決するため、ページのデータが更新されません
問題の説明:
動的に遭遇ルーティング:/ページ/:ID
から/ページ/ 1スイッチングへ/ページ/ 2が更新されていないページ・コンポーネントが見つかりました。
溶液:
<ルータビュー:キー=「とキー」> 別個の増加:キー値、識別VUEが異なることになるように
<router-view :key="key"></router-view>
...
computed:{
key(){
return this.$route.path + Math.random();
}
}
タイマーの破壊で1.2 VUEのコンポーネント
問題の説明:
あなたが見ることができ、Bのページにジャンプした後、1秒に1回、ページに印刷するタイマーを作成し、タイマーがまだ実行されています。
推奨される解決策:
あなたは、このイベントリスナーがあるいったん$でタイマーをクリアするためにタイマーを定義した後の位置。
const timer = setInterval(() => {
// 定时器操作
}, 1000)
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
1.3 VUEは、成分の二つの方法デマンドローディングで達成しました
1.解決=>以下のように、([ './ ComponentA']、決意)を必要とします。
const ComponentA = resolve => require(['./ComponentA'], resolve)
- 次のように()=>インポート()を使用して、特定のコードがあります。
const ComponentA = () => import('./ComponentA')
コンポーネント間1.4、コンポーネントサンズとの間の通信方式
コンポーネント間の通信方式:
- 投稿購読することで、イベントバス(バス)、により、
- vuex
- サンズコンポーネント:
- 親コンポーネントは、支柱によって自己集合にデータを渡します
- サブコンポーネントバインディングカスタムイベント,. $エミット(イベント、のparams)このによるカスタムイベントを起動します
- 使用VUEは$親/ $子供&$レフリー通信方法を提供しました
- 提供/注入
- $ ATTRS間の通信根深い部品、$リスナー
ます。https://m.jb51.net/article/167304.htm実装の詳細はを参照してください。
1.5 VUE $イベントの使用で - 現在の親要素を取得し、子要素、兄弟
<button @click = “fun($event)”>点击</button>
...
methods: {
fun(e) {
// e.target 是你当前点击的元素
// e.currentTarget 是你绑定事件的元素
#获得点击元素的前一个元素
e.currentTarget.previousElementSibling.innerHTML
#获得点击元素的第一个子元素
e.currentTarget.firstElementChild
# 获得点击元素的下一个元素
e.currentTarget.nextElementSibling
# 获得点击元素中id为string的元素
e.currentTarget.getElementById("string")
# 获得点击元素的string属性
e.currentTarget.getAttributeNode('string')
# 获得点击元素的父级元素
e.currentTarget.parentElement
# 获得点击元素的前一个元素的第一个子元素的HTML值
e.currentTarget.previousElementSibling.firstElementChild.innerHTML
}
},
1.6 VUE一般的なツールは、要約機能します
/*
日期相关 dateFormater:格式化时间
timestampToTime
* */
function dateFormater(formater, t){
let date = t ? new Date(t) : new Date(),
Y = date.getFullYear() + '',
M = date.getMonth() + 1,
D = date.getDate(),
H = date.getHours(),
m = date.getMinutes(),
s = date.getSeconds();
return formater.replace(/YYYY|yyyy/g,Y)
.replace(/YY|yy/g,Y.substr(2,2))
.replace(/MM/g,(M<10?'0':'') + M)
.replace(/DD/g,(D<10?'0':'') + D)
.replace(/HH|hh/g,(H<10?'0':'') + H)
.replace(/mm/g,(m<10?'0':'') + m)
.replace(/ss/g,(s<10?'0':'') + s)
}
// dateFormater('YYYY-MM-DD HH:mm', 1580787420000)//==> "2020-02-04 11:37"
// dateFormater('YYYYMMDDHHmm', new Date()) //==> 201906261830
/*
获取Url参数,返回一个对象
* */
function GetUrlParam(){
let url = document.location.toString();
let arrObj = url.split("?");
let params = Object.create(null)
if (arrObj.length > 1){
arrObj = arrObj[1].split("&");
arrObj.forEach(item=>{
item = item.split("=");
params[item[0]] = item[1]
})
}
return params;
}
// ?a=1&b=2&c=3 ==> {a: "1", b: "2", c: "3"}
//toFullScreen:全屏
function toFullScreen(){
let elem = document.body;
elem.webkitRequestFullScreen
? elem.webkitRequestFullScreen()
: elem.mozRequestFullScreen
? elem.mozRequestFullScreen()
: elem.msRequestFullscreen
? elem.msRequestFullscreen()
: elem.requestFullScreen
? elem.requestFullScreen()
: alert("浏览器不支持全屏");
}
//exitFullscreen:退出全屏
function exitFullscreen(){
let elem = parent.document;
elem.webkitCancelFullScreen
? elem.webkitCancelFullScreen()
: elem.mozCancelFullScreen
? elem.mozCancelFullScreen()
: elem.cancelFullScreen
? elem.cancelFullScreen()
: elem.msExitFullscreen
? elem.msExitFullscreen()
: elem.exitFullscreen
? elem.exitFullscreen()
: alert("切换失败,可尝试Esc退出");
}
第2のパッケージhttpリクエストaxios 1.7
import axios from 'axios'
import router from '@/router'
import {removeSessionStorage} from './storage';
import Vue from 'vue'
import { Message } from 'element-ui' // 引用element-ui的加载和消息提示组件
// 请求超时时间配置
axios.defaults.timeout = 30000;
// api地址配置
axios.defaults.baseURL = "";
// console.log(process.env.VUE_APP_BASE_API)
Vue.prototype.$http = axios
// 在全局请求和响应拦截器中添加请求状态
let loading = null
// 请求拦截器
axios.interceptors.request.use(
config => {
config.headers = {
'Content-Type': 'application/json'
};
// loading = Loading.service({ text: '拼命加载中' })
let token = sessionStorage.getItem('-_token_-');
if (token) {
config.headers['token'] = token;
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
axios.interceptors.response.use(
response => {
if (loading) {
loading.close()
}
//console.log(response)
const code = response.status
if ((code >= 200 && code < 300) || code === 304) {
let errorCode = response.data.errCode;
if(errorCode==='000000'){
return Promise.resolve(response.data)
}else {
if (errorCode === 'SYS0404') {
router.push({
name: 'error',
params: {
isTimeout: false,
path: router.currentRoute.path,
desc: '您请求的资源找不到(错误码:404) ',
},
});
} else if (errorCode === 'SYS0401') {
removeSessionStorage('-_token_-');
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}
// Message.error(response.data.message)
return Promise.resolve(response.data)
}
// return Promise.resolve(response.data)
} else {
return Promise.reject(response)
}
},
error => {
if (loading) {
loading.close();
}
console.log(error);
if (error.response) {
switch (error.response.status) {
case 401:
case 403:
// 返回401 清除token信息并跳转到登陆页面
removeSessionStorage('-_token_-');
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
case 404:
Message.error('网络请求不存在');
console.log('错误码:404 路由跳转 currentRoute %o ', router.currentRoute.path);
router.push({
name: 'error',
params: {
isTimeout: false,
path: router.currentRoute.path,
desc: '您请求的资源找不到(错误码:404) ',
},
});
break;
case 502:
router.push({
name: 'error',
params: {
isTimeout: false,
path: router.currentRoute.path,
desc: '网关错误(错误码:502),请联系系统管理员 ',
},
});
break;
default:
Message.error(error.response.data.message ||'系统出错,请联系系统管理员(错误码:'+error.response.status+')!');
}
} else {
let controlParam = {
desc: '',
path: router.currentRoute.path,
isTimeout: false,
};
// 请求超时或者网络有问题
if (error.message.includes('timeout')) {
Message.error('请求超时!请检查网络是否正常');
controlParam.desc = '网络断开,请检查您的网络 ';
controlParam.isTimeout = true;
} else {
Message.error('请求失败,请检查网络是否已连接');
controlParam.desc = '页面加载失败 ';
}
router.push({
name: 'error',
params: controlParam,
});
}
return Promise.reject(error);
}
);
2.elementui成分修飾エクスペリエンス
2.1要素-UIステップストリップを使用して深さ
2.1.1element-UIは、クリック、ホバーとして、1に各イベントを追加する手順ステップ
<el-steps :space="200" :active="1" finish-status="success">
<el-step @click.native="on_click(1)" title="已完成"></el-step>
<el-step @click.native="on_click(2)" title="进行中"></el-step>
<el-step @click.native="on_click(3)" title="步骤 3"></el-step>
</el-steps>
2.1.2特定のビジネスインタラクション
https://blog.csdn.net/weixin_40098371/article/details/88027949
テキスト方向は2.1.3変更
になり
CSS、セットmaginと背景を調整します
.el-step__main {
white-space: normal;
text-align: left;
margin-top: -31px;
margin-left: 25px;
}
}
i
.el-step__title {
font-size: 16px;
line-height: 38px;
background: #FFF;
width: 50px;
position: relative;
z-index: 1;
}
2.2 V-ロードプロンプトテキストボックスの折り返し
2.3メニュー項目のルーティングエラーコンソールをダブルクリックします
//解决菜单双击报错
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
3.Vueプロジェクト構成
3.1ヴュー・CLI3コンフィギュレーションの開発、生産およびテスト環境
- 開発環境変数を作成します.env.development
- 本番環境変数を作成します.env.production
- テスト環境変数を作成します.env.test
環境変数がVUE_APPが前置されている必要があります
ようにインタフェースファイル内のコードのように、他のドキュメントでprocess.env.VUE_APP_BASE_APIを介してアクセスします
import axios from 'axios'
import router from '@/router'
// 请求超时时间配置
axios.defaults.timeout = 30000;
// api地址配置
axios.defaults.baseURL = "process.env.VUE_APP_BASE_API";
設定package.jsonに対応
"scripts": {
"serve": "vue-cli-service serve --mode development",
"build": "vue-cli-service build --mode production",
"test": "vue-cli-service build --mode test",
},
3.2開発環境のプロキシスイッチング構成
試験された場合、バックエンドにローカルエージェントに、コード開発時には、そのようなクロスドメインのシナリオでdevServerを対処するには、だけでなく、テスト環境にエージェントを変更するために、ライン上で、新しい問題を委託することはオンライン環境機関であってよいです
vue.config.jsな構成であるために
const Timestamp = new Date().getTime(); //当前时间为了防止打包缓存不刷新,所以给每个js文件都加一个时间戳
const proxyTargetMap = {
prod: 'https://xxx.xxx.com/',
dev: 'http://192.168.200.230:6379',
test: 'http://test.xxx.com',
local: 'http://localhost:8080/'
}
let proxyTarget = proxyTargetMap[process.env.API_TYPE] || proxyTargetMap.local
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: false, // 是否开启eslint保存检测
productionSourceMap: false, // 是否在构建生产包时生成sourcdeMap
// 调整内部的 webpack 配置。
// 查阅 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/webpack.md
chainWebpack: () => { },
//configureWebpack 这部分打包文件添加时间戳,防止缓存不更新
configureWebpack: {
output: { // 输出重构 打包编译后的 文件名称 【模块名称.版本号.时间戳】
filename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`,
chunkFilename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`
},
},
devServer : {
proxy: {
'/api' : {
target: proxyTarget,
changeOrigin: true,
pathRewrite: {
'^/api' : ''
}
}
}
}
};
設定package.jsonに対応
"scripts": {
"serve": "vue-cli-service serve --mode development",
+ "serve:dev": "cross-env API_TYPE=dev vue-cli-service serve --mode development",
+ "serve:test": "cross-env API_TYPE=test vue-cli-service serve --mode development",
"build": "vue-cli-service build --mode production",
"test": "vue-cli-service build --mode test",
},