通过find找到指定条件的对象
let obj = [{id:1},{id:2}] , aid = 1
let item = obj.find((item)=>{
return item.id == aid
})
// item =>{id: 1}
判断环境
const prefix = process.env.NODE_ENV === 'development' ? '/api' : 'http://www.abc.com'
//判断手机网站
<script type="text/javascript">
var mobileAgent = new Array("iphone", "ipod", "ipad", "android", "mobile", "blackberry", "webos", "incognito", "webmate", "bada", "nokia", "lg", "ucweb", "skyfire");
var browser = navigator.userAgent.toLowerCase();
var isMobile = false;
for (var i=0; i<mobileAgent.length; i++){ if (browser.indexOf(mobileAgent[i])!=-1){ isMobile = true;
//alert(mobileAgent[i]);
location.href = 'http://m.0071515.com';
break; } }
</script>
api请求封装
//api.js
const prefix = process.env.NODE_ENV === 'development' ? '/api' : 'http://www.abc.com'
export default (config => {
let data = {};
let a = Object.keys(config)
for (let k of a) {
data[k] = prefix + config[k]
}
return data
})({
'bindPhone' : "/api/index.php/other/bindPhone ", // 微信授权地址
'openCity' : "/api/index.php/other/city" // 开放城市
})
//http.js
import axios from 'axios'
import qs from 'qs'
import 'es6-promise'
// 配置axios的默认URL
// axios.defauls.baseURL = 'xxx'
// 配置允许跨域携带cookie
axios.defaults.withCredentials = true
// 配置超时时间
axios.defaults.timeout = 100000
// axios拦截器 请求拦截
axios.interceptors.request.use(config => {
// config.setHeaders([
// // 在这里设置请求头与携带token信息
// ])
return config
})
// axios拦截器 响应拦截
axios.interceptors.response.use(response => {
// 在这里你可以判断后台返回数据携带的请求码
// if (response.data.retcode === 200 || response.data.retcode === '200') {
// return response.data.data || response.data
// }else {
// // 非200请求抱错
// throw Error(response.data.msg || '服务异常')
// }
// Toast.hide();
return response
})
export function get(url, params) {
return new Promise((resolve, reject) => {
axios.get(url, {params: params}).then(res => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
}
export function post(url, data) {
return new Promise((resolve, reject) => {
axios.post(url, qs.stringify(data), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}).then(res => {
//可以在这里判断code是否是未登录状态
resolve(res.data)
}).catch(err => {
reject(err)
})
})
}
//server.js
import {get, post} from './http'
import apis from './apis'
export const bindPhone = (phone, code) => {
return post(apis.bindPhone, {phoen: phone, code: code})
}
export const openCity = () => {
return get(apis.openCity, {})
}
// console.log(apis)
{
openCity : "/api/index.php/other/city",
bindPhone : "/api/index.php/other/bindPhone "
}
// console.log(typeof apis) Object
vue 维护倒计时
import React, { Component } from 'react';
// import {connect} from 'react-redux';
import './mainTian.less'
class mainTian extends Component {
constructor(props) {
super(props);
this.state = {
day: 0,
hour: 0,
minute: 0,
second: 0
}
}
countFun(end) {
let now_time = Date.parse(new Date());
var remaining = end - now_time;
this.timer = setInterval(() => {
//防止出现负数
if (remaining > 1000) {
remaining -= 1000;
let day = Math.floor((remaining / 1000 / 3600) / 24);
let hour = Math.floor((remaining / 1000 / 3600) % 24);
let minute = Math.floor((remaining / 1000 / 60) % 60);
let second = Math.floor(remaining / 1000 % 60);
this.setState({
day: day,
hour: hour < 10 ? "0" + hour : hour,
minute: minute < 10 ? "0" + minute : minute,
second: second < 10 ? "0" + second : second
})
} else {
clearInterval(this.timer);
}
}, 1000);
}
componentDidMount() {
const end = Date.parse(new Date('2019-09-01 09:00'))
this.countFun(end);
}
componentWillMount() {
setTitle('首页');
// clearInterval(settime);
}
//卸载组件取消倒计时
componentWillUnmount() {
clearInterval(this.timer);
}
shouldComponentUpdate(nextProps, nextState) {
return true;
}
render() {
return (
<div className='mainTian'>
<div className="content" style={{
textAlign: "center",
fontSize: "16px",
fontWeight: "bold",
height: "60px",
lineHeight: "35px",
}}>
<p className="span">本网站系统正在升级维护中....</p>
<p className="span" style={{
fontSize: "14px",
fontWeight: "normal",
}}>
{/* {this.state.day}天 */}
恢复正常访问倒计时 <span>{this.state.day}天 {this.state.hour}:{this.state.minute}:{this.state.second}</span></p>
<p className="span"><a href="tel:1662610000" >了解详情点击联系客服</a></p>
<p className="span">敬请期待</p>
</div>
</div>
);
}
}
export default mainTian;
vuex状态管理
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
import {
getMemberList,
getContactList
} from '../common/http/services.js'
import orderInfo from './orderInfo/';
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
hasLogin: false, // 登陆状态
citycode:null
userInfo: null, // 用户信息
},
getters: {
checkLogin: state => {
return state.hasLogin;
},
getCityCode: state => {
return state.citycode
},
},
mutations: {
setCitycode(state, citycode) {
state.citycode = citycode
},
login(state, loginData) {
state.hasLogin = true;
state.userInfo = loginData
},
},
actions: {
getUserOpenId: async function({
commit,
state
}) {
return await new Promise((resolve, reject) => {
if (state.openid) {
resolve(state.openid)
} else {
uni.login({
success: (data) => {
commit('login')
setTimeout(function() { //模拟异步请求服务器获取 openid
const openid = '123456789'
console.log('uni.request mock openid[' + openid + ']');
commit('setOpenid', openid)
resolve(openid)
}, 1000)
},
fail: (err) => {
console.log('uni.login 接口调用失败,将无法正常使用开放接口等服务', err)
reject(err)
}
})
}
})
},
//用户信息
getUserInfo(context) {
getMemberList().then(res => {
if (res.code === 200 || res.code === 0 ) {
console.log(res.data)
context.commit('login', res.data)
}
})
},
getAddressList(context) {
getContactList().then(res => {
if (res.code === 200 ) {
context.commit('address', res.data.list)
} else if ( res.code === 222) {
uni.showToast({
icon: 'none',
title: res.msg,
success: () => {
//未登录跳转/处理
uni.navigateTo({
url: '../login/login'
})
}
})
}
}).catch(err => {
console.log(err);
})
}
},
modules: {
orderInfo
}
})
export default store
//调用的js
<script>
import { mapState } from 'vuex'
export default {
onLaunch: function(e) {
console.log('App Launch now');
},
computed:{
...mapState(['userInfo']),
},
created: function() {
console.log(this.userInfo)
this.$store.commit("login",this.userInfo) // 将当前用户保存到store
this.$store.dispatch('getAddressList') //触发actions
}
}
</script>
<style>
</style>
vue项目常用记录
路由篇
异步1
加载组件,当你访问 / ,才会加载 home.vue。
{
path: '/',
component: resolve=>require(["@/components/pages/home.vue"],resolve),
meta: {
title: 'home'
}
}
异步2
import a from './components/a.vue'
export default ({
{
path: '/signIn',
component: ()=>import("@/components/pages/signIn/signIn"),
}
})
二叉树(地区递归,侧边导航 实战)
//element-ui menu 递归
<template>
<div>
<div class="sidebar-container">
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
mode="vertical"
background-color="#304156"
text-color="#bfcbd9"
active-text-color="#409EFF"
>
<sidebar-item v-for="menu in menuList" :key="menu.path" :item="menu" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import SidebarItem from './../components/SidebarItem'
export default {
name: 'Sidebar',
components: { SidebarItem },
props: {
menuList: {
type: Array,
// required: true,
default: () => {
return [
{
path: '/func1', // 菜单项所对应的路由路径
title: '功能1', // 菜单项名称
children: [] // 是否有子菜单,若没有,则为[]
},
{
path: '/func2',
title: '功能2',
children: []
},
{
path: '/func3',
title: '功能3',
children: [
{
path: '/func41',
title: '功能4-1',
children: []
},
{
path: '/func42',
title: '功能4-2',
children: []
},
{
path: '/func43',
title: '功能4-3',
children: [
{
path: '/func51',
title: '功能5-1',
children: []
},
{
path: '/func52',
title: '功能5-2',
children: []
},
{
path: '/func53',
title: '功能5-3',
children: []
}
]
}
]
}
]
}
}
},
data () {
return {
pagedefault: ''
}
},
}
</script>
<style lang="less">
.sidebar-container {
transition: width 0.28s;
width: 180px !important;
height: 100%;
position: fixed;
font-size: 0px;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out,
0s padding-right ease-in-out;
}
.el-scrollbar {
height: 100%;
}
.scrollbar-wrapper {
overflow-x: hidden !important;
.el-scrollbar__view {
height: 100%;
}
}
.el-scrollbar__bar.is-vertical {
right: 0px;
}
.is-horizontal {
display: none;
}
a {
display: inline-block;
width: 100%;
overflow: hidden;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
}
.is-active > .el-submenu__title {
color: #f4f4f5 !important;
}
}
</style>
//SidebarItem.vue
<template>
<div v-if="item.children">
<template v-if="item.children.length == 0">
<el-menu-item :index="item.path">
<i class="el-icon-menu"></i>
a{{item.title}}
</el-menu-item>
</template>
<el-submenu v-else :index="item.path">
<template slot="title" ><i class="el-icon-menu"></i>b{{item.title}}</template>
<template v-for="child in item.children">
<sidebar-item
v-if="child.children&&child.children.length>0"
:item="child"
:key="child.path"/>
<el-menu-item v-else :key="child.path" :index="child.path"> <i class="el-icon-location"></i> c {{child.title}} </el-menu-item>
</template>
</el-submenu>
</div>
</template>
<script>
export default {
name: 'SidebarItem',
props: {
item: {
type: Object,
required: true
}
}
}
</script>
动态加载路由权限(直接贴代码)
SidebarItem.vue
<template>
<div v-if="item.children">
<template v-if="item.children.length == 0">
<el-menu-item :index="item.path">
<i class="el-icon-menu"></i>
{{item.title}}
</el-menu-item>
</template>
<el-submenu v-else :index="item.path">
<template slot="title" ><i class="el-icon-menu"></i> {{item.title}}</template>
<template v-for="child in item.children">
<sidebar-item
v-if="child.children&&child.children.length>0"
:item="child"
:key="child.path"/>
<el-menu-item v-else :key="child.path" :index="child.path"> <i class="el-icon-location"></i> {{child.title}} </el-menu-item>
</template>
</el-submenu>
</div>
</template>
<script>
export default {
name: 'SidebarItem',
props: {
item: {
type: Object,
required: true
}
}
}
</script>
SideBarAdmin.vue
<template>
<div>
<div class="sidebar-container">
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
mode="vertical"
background-color="#304156"
text-color="#bfcbd9"
active-text-color="#409EFF"
router
default-active="1"
>
<sidebar-item v-for="menu in menuList" :key="menu.path" :item="menu" />
</el-menu>
</el-scrollbar>
</div>
</div>
</template>
<script>
import SidebarItem from './../components/SidebarItem'
export default {
name: 'Sidebar',
components: { SidebarItem },
props: {
menuList: {
type: Array,
// required: true,
default: () => {
return [
{
path: '1', // 菜单项所对应的路由路径
title: '功能1', // 菜单项名称
children: [] // 是否有子菜单,若没有,则为[]
},
{
path: '2',
title: '功能2',
children: []
},
{
path: '3',
title: '功能3',
children: [
{
path: '3-1',
title: '功能3-1',
children: []
},
{
path: '3-2',
title: '功能3-2',
children: []
},
{
path: '3-3',
title: '功能3-3',
children: [
{
path: '3-31',
title: '功能3-31',
children: []
},
{
path: '3-32',
title: '功能3-32',
children: []
},
{
path: '3-33',
title: '功能3-33',
children: []
}
]
}
]
}
]
}
}
},
data () {
return {
pagedefault: '',
addList: [],
default: 1
}
},
watch: {
},
created () {
this.addMenuRouter()
},
methods: {
creatRouteList (list) {
//原有的路由添加 vue会自动处理覆盖原有相同的路由
let obj = [ {
path: '/',
component: resolve => require(['../page/Main.vue'], resolve),
meta: {title: '自述文件'},
children: [
{
path: '/dashboard',
component: resolve => require(['../tag/Dashboard.vue'], resolve),
meta: { title: '首页' }
},
{
path: '/user',
component: resolve => require(['../tag/Reigster.vue'], resolve),
meta: { title: '注册用户' }
}
]
} ]
list.map((res, index) => {
let item = {
path: res.path,
name: res.title,
component: () => import(`../components/demo/${res.path}.vue`)
}
obj[0].children.push(item)
console.log(obj)
console.log(res.children.length)
if (res.children.length > 0) {
this.creatRouteList(res.children)
}
})
this.$router.addRoutes(obj)
},
addMenuRouter () {
this.creatRouteList(this.menuList)
}
}
}
</script>
<style lang="less">
.sidebar-container {
transition: width 0.28s;
width: 180px !important;
height: 100%;
position: fixed;
font-size: 0px;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out,
0s padding-right ease-in-out;
}
.el-scrollbar {
height: 100%;
}
.scrollbar-wrapper {
overflow-x: hidden !important;
.el-scrollbar__view {
height: 100%;
}
}
.el-scrollbar__bar.is-vertical {
right: 0px;
}
.is-horizontal {
display: none;
}
a {
display: inline-block;
width: 100%;
overflow: hidden;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
}
.is-active > .el-submenu__title {
color: #f4f4f5 !important;
}
}
.is-opened .el-submenu__title{
background: #BFDFFA;
color: #00afff;
padding-left: 12px !important;
}
</style>
效果图(小部分路由截图,左边是导航栏右边是内容 即children里面的路由)
嵌套路由
router.js
routes: [
{
path: '/',
redirect: '/dashboard'
},
//左右布局
{
path: '/',
component: resolve => require(['../page/Main.vue'], resolve),
meta: {title: '自述文件'},
children: [
{
path: '/dashboard',
component: resolve => require(['../tag/Dashboard.vue'], resolve),
meta: { title: '首页' }
},
{
path: '/user',
component: resolve => require(['../tag/Reigster.vue'], resolve),
meta: { title: '注册用户' }
}
]
},
//全页面
{
path: '/login',
component: resolve => require(['../page/Login.vue'], resolve)
}
]
app.js
<template>
<div id="app">
<router-view/>
</div>
</template>
main.js
<template>
<div class="wrapper">
<vHead/>
<vSidebar/>
<div class="content-box" :class="{'content-collapse':collapse}">
<v-tags></v-tags>
<div class="content">
<transition name="move" mode="out-in">
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
</div>
</div>
</div>
</template>