笔记

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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值