JS循环对象的方法
const obj = {
id:1,
name:'zhangsan',
age:18
}
1.for…in,类似于for循环
for(let key in obj){
console.log(key + '---' + obj[key])
}
结果输出:id—1 name—zhangsan age—18
2.obect.keys(obj)
console.log(Object.keys(obj))
输出结果: [‘id’,‘name’,‘age’]
3.obect.values(obj)
console.log(Object.values(obj))
结果输出: [‘1’,‘zhangsan’,‘18’]
将对象的键和键值分别提取的操作:
for (var key of Object.keys(answer)) {
obj.push({
questionId: key,
optionsId: answer[key][i]
})
}
动态路由
当需要路由映射到同一个组件,就可以使用动态路由来实现,使用动态路由后可以使用$route.params.xxx获得到路由上传递的参数
在路由跳转的时候采用:to="/detail/:userid"
或者
this.router.push({
path: detail/${userid}
})
在路由配置文件中采用
{
path:‘/detail/:id’
componemt: Detail
}
路由中的Match:
matcher对象对外提供match()和addRoutes()两个方法,addRoutes()的作用是动态添加路由配置,match()根据传入的rawLocation类型的raw和当前的currentRoute计算出一个新的路径并返回
match():
作用是匹配一个路径并找到映射的组件,执行过程:
1.先normalizeLocation,得到一个标准化定位描述location{ normalized: true, path:"/foo", query:{}, hash:"" }
2.(1)name存在时,通过name从nameMap中拿到路由记录record,接着处理记录record中的参数,将location、record和VueRouter对象作为参数传入createRoute()中生成新路径
(2)name不存在而path值存在,遍历路径和集合pathlist,有渠道的record和location匹配罗乳沟匹配就去生成一个新路径
match会根据传入放入位置和路径计算新的位置,并匹配对应的路由记录,然后根据新的路径生成新的route路径
组件传值:
1.父传子
父组件在子组件标签上绑定自己传递给子组件的值
<m-navbar title="职业价值观倾向测试题" :left-arrow="false" :right-arrow="false" :left-solt="true" :border="false">
<van-icon name="arrow-left" @click="onClickLeft" />
</m-navbar>
2.子组件中通过prop接收父组件传递过来的值,再在HTML中渲染
<van-nav-bar :title="title" :border="border" :left-text="leftText" :left-arrow="leftArrow" @click-left="onClickLeft" @click-right="onClickRight">
<template v-if="leftSolt" #left>
<slot />
</template>
<template v-if="rightArrow" #right>
<slot />
</template>
</van-nav-bar>
props: {
title: {
type: String,
default: ''
},
leftText: {
type: String,
default: ''
},
icon: {
type: String,
default: 'arrow'
},
leftArrow: {
type: Boolean,
default: true
},
leftSolt: {
type: Boolean,
default: false
},
rightArrow: {
type: Boolean,
default: false
},
border: {
type: Boolean,
default: true
}
},
2.父传子
子组件通过事件触发this.$emit(“父组件触发的事件名”,传给父组件的值)
<template>
<div id="container">
<input type="text" v-model="msg">
<button @click="setData">传递到父组件</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "传递给父组件的值"
};
},
methods: {
setData() {
this.$emit("getData", this.msg);
}
}
};
</script>
父组件调用子组件处罚的方法接收参数
<template>
<div id="container">
<Child @getData="getData"></Child>
<p>{{msg}}</p>
</div>
</template>
<script>
import Child from "@/components/Child";
export default {
data() {
return {
msg: "父组件默认值"
};
},
methods: {
getData(data) {
this.msg = data;
}
},
components: {
Child
}
};
</script>
插槽
子组件
<van-nav-bar :title="title" :border="border" :left-text="leftText" :left-arrow="leftArrow" @click-left="onClickLeft" @click-right="onClickRight">
<template v-if="leftSolt" #left>
<slot />
</template>
<template v-if="rightArrow" #right>
<slot />
</template>
</van-nav-bar>
父组件
<m-navbar title="职业价值观倾向测试题" :left-arrow="false" :right-arrow="false" :left-solt="true" :border="false">
<van-icon name="arrow-left" @click="onClickLeft" />
</m-navbar>
子传父
<van-search
v-model="searchValue"
show-action
:placeholder="searchStr"
shape="round"
@search="onSearch"
@clear="onClear"
>
<template #action>
<div
v-show="!getIsSearch"
@click="clickSearch"
>搜索</div>
</template>
</van-search>
methods: {
onSearch(val) {
this.$emit('onSearch', this.searchValue)
},
onClear() {
this.$emit('onClear', this.searchValue)
},
clickSearch() {
this.$emit('clickSearch', this.searchValue)
}
}
父组件
<common-search
:search-str="text"
@clickSearch="gosearch"
@onClear="canclesearch"
@onSearch="onSearch"
/>
gosearch(searchValue) {
this.college = searchValue
this.pageNum = 1
this.universitylist = []
this.getuniversityList1()
},
canclesearch(searchvalue) {
this.college = searchvalue
this.pageNum = 1
this.universitylist = []
this.getuniversityList1()
},
onSearch (searchvalue) {
this.college = searchvalue
this.pageNum = 1
this.universitylist = []
this.getuniversityList1()
}
axios封装
1.创建axios实例
// 请求超时时间
const requestTimeOut = 10 * 1000
const success = 200
const service = axios.create({
// 将自动加在url前面,可以通过设置一个baseURL便于为axios实例的方法传递相对URL,这里设置的是config文件中配置的proxy代理的路径
baseURL: process.env.VUE_APP_BASE_API,
timeout: requestTimeOut,
// 表示服务器响应数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json',
// 即将被发送的自定义请求头
headers: { 'X-Requested-With': 'XMLHttpRequest' },
// 定义对于给定的HTTP响应状态码是resolve或reject promise
validateStatus(status) {
return status === success
}
})
更多api参见
http://www.axios-js.com/zh-cn/docs/
请求拦截和响应拦截
1.请求拦截
service.interceptors.request.use(
config => {
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
2.响应拦截
service.interceptors.response.use((config) => {
return config
}, (error) => {
if (error.response) {
const errorMessage = error.response.data === null ? '系统内部异常,请联系网站管理员' : error.response.data.message
switch (error.response.status) {
case 401:
Notify({
message: '很抱歉,认证已失效,请重新登录',
type: 'warning',
duration: messageDuration
})
router.replace('/login')
store.commit('setUser', {})
store.commit('setLogin', {})
break
case 404:
Notify({
message: '很抱歉,资源未找到',
type: 'warning',
duration: messageDuration
})
break
case 403:
Notify({
message: '很抱歉,您暂无该操作权限',
type: 'warning',
duration: messageDuration
})
break
}
}
return Promise.reject(error)
})
请求配置
const request = {
post(url, params) {
return service.post(url, params, {
transformRequest: [(params) => {
return tansParams(params)
}],
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
postJson(url, params) {
return service.post(url, params, {
transformRequest: [(params) => {
return JSON.stringify(params)
}],
headers: {
'Content-Type': 'application/json'
}
})
},
put(url, params) {
return service.put(url, params, {
// 允许在向服务器发送前,修改请求数据,只能用在PUT POST PATCH这几个请求方法,后面数组中的函数必须返回一个字符串,或ArrayBuffer或Stream
transformRequest: [(params) => {
return tansParams(params)
}],
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
},
get(url, params) {
let _params
if (Object.is(params, undefined)) {
_params = ''
} else {
_params = '?'
for (const key in params) {
// eslint-disable-next-line no-prototype-builtins
if (params.hasOwnProperty(key) && params[key] !== null) {
_params += `${key}=${params[key]}&`
}
}
}
return service.get(`${url}${_params}`)
},
delete(url, params) {
let _params
if (Object.is(params, undefined)) {
_params = ''
} else {
_params = '?'
for (const key in params) {
// eslint-disable-next-line no-prototype-builtins
if (params.hasOwnProperty(key) && params[key] !== null) {
_params += `${key}=${params[key]}&`
}
}
}
return service.delete(`${url}${_params}`)
}
}
function tansParams(params) {
let result = ''
Object.keys(params).forEach((key) => {
if (!Object.is(params[key], undefined) && !Object.is(params[key], null)) {
result += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + '&'
}
})
return result
}
require.context
require.context是webpack的API,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化模块导入,在前端工程中,如果遇到一个文件夹引入很多模块的情况,就可以使用这个API,他会遍历文件夹中的指定文件,然后自动导入,使得不予要每次显示的调用import导入模块
require.context函数接收三个参数
1.directory{string} —文件读取的路径
2.useSU币direction{Boolean} —是否遍历文件的子目录
3.regExp{regExp} —匹配文件的正则
函数执行后返回一个参数,这个函数有三个属性
1.resolve{function} 接受一个参数request,request问文件夹下匹配文件的相对路径,返回这个匹配文件的相对路径对于整个工程的相对路径
2.keys{function} 返回匹配成功模块的名字组成的数组
3.id{string} 执行环境的id,返回的是一个字符串
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
export default store
在module文件中,声明了store的state等多个属性,如果分别使用import导入会很不方便,所以采用了require.context函数进行导入
module文件中
import local from '@/utils/localstorage'
const state = {
ISLOADING: true,
userInfo: local.get('USERINFO'),
isLogin: local.get('ISLOGIN')
}
const mutations = {
showLoading(state) {
state.ISLOADING = true
},
hideLoading(state) {
state.ISLOADING = false
},
setLogin(state, val) {
local.save('ISLOGIN', val)
state.isLogin = val
},
setUser(state, val) {
local.save('USERINFO', val)
state.userInfo = val
}
}
const actions = {}
export default {
state,
mutations,
actions
}