您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Vue項目中實用小技巧有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
需求一:為路徑配置別名
在開發過程中,我們經常需要引入各種文件,如圖片、CSS、JS等,為了避免寫很長的相對路徑(../),我們可以為不同的目錄配置一個別名。
找到 webpack.base.config.js 中的 resolve 配置項,在其 alias 中增加別名,如下:
創建一個 CSS 文件,隨便寫點樣式:
.avatar display: flex; justify-content: center; align-items: center; .avatar-img padding 20px border solid 1px #ccc border-radius 5px
接著,在我們需要引入的文件中就可以直接使用了:
<template> <div class="avatar"> <img class="avatar-img" src="~img/avatar.png" alt=""> </div> </template> <script> export default { name: "Home" } </script> <style scoped lang="stylus"> @import "~css/avatar"; </style>
需要注意的是,如果不是通過 import 引入則需要在別名前加上 ~,效果如下:
需求二:要求實現在生產包中直接修改api地址
這個需求,怎么說呢,反正就是需求,就想辦法實現吧。
假設有一個 apiConfig.js 文件,用于對 axios 做一些配置,如下:
import axios from 'axios'; axios.defaults.timeout = 10000; axios.defaults.retry = 3; axios.defaults.retryDelay = 2000; axios.defaults.responseType = 'json'; axios.defaults.withCredentials = true; axios.defaults.headers.post["Content-type"] = "application/json"; // Add a request interceptor axios.interceptors.request.use(function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); }); // Add a response interceptor axios.interceptors.response.use(function (response) { // Do something with response data return response; }, function (error) { // Do something with response error return Promise.reject(error); }); export default axios
在 static 文件夾中增加一個 config.json 文件,用于統一管理所有的 api 地址:
{ "base": "/api", "static": "//static.com/api", "news": "//news.com.api" }
打開 main.js,寫入下列代碼:
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from 'js/apiConfig'; //import直接引入,不用添加~ Vue.config.productionTip = false; Vue.use(ElementUI); /* eslint-disable no-new */ let startApp = function () { let randomStamp = new Date().getTime(); axios.get(`/static/config.json?t=${randomStamp}`).then((data) => { axios.defaults.baseURL = data.base; //設置一個默認的根路徑 Vue.prototype.$axios = axios; Vue.prototype.$apiURL = data; //將所有路徑配置掛載到 Vue 原型上 /* eslint-disable no-new */ new Vue({ el: '#app', router, components: {App}, template: '<App/>' }); }) }; startApp();
就是先用 axios 獲取 api 文件,然后再初始化。
需求三:由后臺根據用戶權限值返回菜單
菜單是樹形結構(PS:就算不是樹形結構,你也得處理成樹形結構),我這里使用的是 ElementUI ,參考了道友的這篇文章,實現如下:
新建一個 Menu.vue 文件,寫入如下代碼:
<script> export default { name: "MenuItem", props: { data: { type: Array }, collapse: { type: Boolean } }, methods: { //生成菜單項 createMenuItem(data, createElement) { return data.map(item => { if (item.children && item.children.length) { return createElement('el-submenu', {props: {index: item.id.toString()}}, [ createElement('template', {slot: 'title'}, [ createElement('i', {class: item.icon}), createElement('span', [item.title]), ] ), this.createMenuItem(item.children, createElement) //遞歸 ] ) } else { return createElement('el-menu-item', {props: {index: item.path}}, [ createElement('i', {class: item.icon}), createElement('span', {slot: 'title'}, [item.title]), ] ) } }) }, //選中菜單 onSelect(key, keyPath) { console.log(key, keyPath); } }, render(createElement) { return createElement( 'el-menu', { props: { backgroundColor: "#545c64", textColor: "#fff", activeTextColor: "#ffd04b", collapse: this.collapse, router:true }, class:'el-menu-vertical-demo', on: { select: this.onSelect } }, this.createMenuItem(this.data, createElement) ) } } </script> <style scoped lang="stylus"> .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; min-height: 400px; } </style>
這里主要用到兩個東西,一個是 render 函數,一個是遞歸,如果不熟悉 render 函數的道友請點這里。可能有道友會問為什么不用模板,因為······做不到啊?,在 template 中只能有一個根元素,而 Vue 限制了不能對根元素使用 v-for;再者,通過在瀏覽器中查看代碼可以知道,菜單就是 ul 加上 li,如果有了根元素會破壞標簽結構(雖然不影響功能,但還是覺得不舒服?)。然后,在需要使用的地方:
<template> <el-container> <el-aside width="auto"> <Menu :data="menu" :collapse="isCollapsed"></Menu> </el-aside> <el-container> <el-header> <el-button type="text" icon="el-icon-d-arrow-left" @click="isCollapsed=!isCollapsed"></el-button> <h4>MenuName</h4> <span>MeFelixWang</span> </el-header> <el-main> <router-view></router-view> </el-main> </el-container> </el-container> </template> <script> import Menu from '@/components/Menu'; export default { name: 'App', data() { return { menu: [ { title: '導航一', id: 1, path: '', icon: 'el-icon-search', children: [ { title: '導航一杠一', id: 2, path: '', icon: '', children: [ {title: '導航一杠一杠一', id: 4, path: '/test', icon: '', children: []}, { title: '導航一杠一杠二', id: 5, path: '', icon: '', children: [ {title: '導航一杠一杠二杠一', id: 6, path: '/6', icon: '', children: []}, {title: '導航一杠一杠二杠二', id: 7, path: '/7', icon: '', children: []}, ] }, ] }, {title: '導航一杠二', id: 3, path: '/3', icon: '', children: []} ] }, {title: '導航二', id: 8, path: '/8', icon: 'el-icon-setting', children: []}, {title: '導航三', id: 9, path: '/9', icon: 'el-icon-document', children: []}, { title: '導航四', id: 10, path: '', icon: 'el-icon-date', children: [ {title: '導航四杠一', id: 11, path: '/11', icon: '', children: []}, { title: '導航四杠二', id: 12, path: '', icon: '', children: [ {title: '導航四杠二杠一', id: 14, path: '/14', icon: '', children: []} ] }, {title: '導航四杠三', id: 13, path: '/13', icon: '', children: []}, ] }, ], isCollapsed: false } }, methods: { handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); } }, components: { Menu } } </script> <style lang="stylus"> * margin 0 padding 0 html, body, .el-container, .el-aside height 100% .el-aside background-color rgb(84, 92, 100) .el-menu border-right solid 1px rgb(84, 92, 100) .el-header display flex justify-content space-between align-items center background-color aliceblue .el-button--text color: #606266; i font-weight bold </style>
效果如下:
需求四:這個 Select 選項是樹形結構,一定得是樹形結構
樹形結構就樹形結構吧,不就是樣式嘛,改改應該就可以了。
<template> <div> <el-select v-model="tree" placeholder="請選擇活動區域"> <el-option v-for="(item,index) in options" :key="index" :label="item.label" :value="item.id" : :class="item.level?'is-sub':''"></el-option> </el-select> 選擇的是:{{tree}} </div> </template> <script> export default { name: "Home", data() { return { tree: '', options: [], originData: [ { label: '這是根一', id: 1, children: [ {label: '這是莖一一', id: 2, children: []}, {label: '這是莖一二', id: 3, children: []}, { label: '這是莖一三', id: 4, children: [ {label: '這是葉一三一', id: 6, children: []}, {label: '這是葉一三二', id: 7, children: []}, ] }, {label: '這是莖一四', id: 5, children: []}, ] }, { label: '這是根二', id: 8, children: [], }, { label: '這是根三', id: 9, children: [ {label: '這是莖三一', id: 10, children: []}, { label: '這是莖三二', id: 11, children: [ {label: '這是葉三二一', id: 12, children: []} ] }, ], }, ] } }, created() { this.options = this.decomposeTree(this.originData, 0); }, methods: { //分解樹形結構 decomposeTree(array, level) { let tmpArr = []; (function decompose(arr, lev) { for (let i = 0; i < arr.length; i++) { let tmpObj = {}; let item = arr[i]; item.level = lev; tmpObj = Object.assign({}, item); tmpArr.push(tmpObj); if (item.children) { decompose(item.children, lev + 1); //遞歸 } delete tmpObj.children; //刪掉其 children,避免數據過大(不刪也可以,也許后面有用呢) } })(array, level); return tmpArr; } } } </script> <style scoped lang="stylus"> .is-sub:before content '- ' </style>
因為 option 接收的是一個一維數組,所以通過遞歸展平樹形結構,在展平的時候設置每項的層級,通過層級來設置縮進及前綴符號,效果如下:
之所以這樣做,是因為是管理系統,簡單有效,沒必要因為這一個組件引個新的插件或者自己寫一個(以后用得著的除外哈);也可以用 input 加上 tree 控件來模擬。
關于“Vue項目中實用小技巧有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。