node_modules文件夹:项目依赖文件夹。
public文件夹:一般放置一些静态资源(如:图片),webpack打包时会原封不动的打包到dist文件夹中。
src文件夹(源代码文件夹):
babel.config.js:配置文件(babel相关)。
package.json文件:记录项目的详细信息,如项目中有哪些依赖、如何运行、名称等。
package-lock.json:缓存性文件,记录了当前项目所依赖的模块版本。
//package.json中
"scripts": {
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build"
}
//在根目录下,创建一个 vue.config.js 文件
module.exports = {
lintOnSave:false
}
//在根目录下,创建jsconfig.json 配置别名@,用@/ 替代src/ ,在文件数量多,嵌套层次多的时候尤为方便
//exclude表示的是不可使用该别名的文件
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*":["src/*"]
}
},
"exclude": ["node_module","dist"]
}
{
path: '/home',
component: Home,
meta: {
show: true
}
},
{
path: '/login',
component: Login,
meta: {
show: false
}
}
//必须有to,可以把router-link理解为一个a标签,它 也可以加class修饰
<router-link to="/"></router-link>
//编程式导航除了路由跳转,在跳转之前还可以处理一些业务逻辑
this.$router.push('/')
this.$router.push({name:'search',params:{},query:{} })
//在占位符后加 ?即可
path('/search/:keyWord?')
this.$router.push({name:'search',params:{keyWord:''||undefined})
//在router的index.js文件中添加如下代码
import Vue from 'vue'
import VueRouter from 'vue-router'
//解决重复push相同路由报错问题
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
//配置请求拦截器、响应拦截器,可以在发送请求之前处理一些业务、响应拦截器可以在数据返回之后处理一些事情
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
//可以使用自定义配置新建一个实例
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
import requests from "@/api/request";
//首页三级分类接口
export const reqCateGoryList = () => {
return requests({
url: '/product/getBaseCategoryList',
method: 'GET'
})
}
import {reqCateGoryList} from './api'
//发起请求
reqCateGoryList();
//在vue.config.js中配置
module.exports = {
//关闭eslint
lintOnSave: false,
devServer: {
// true 则热更新,false 则手动刷新,默认值为 true
inline: false,
// development server port 8000
port: 8001,
//代理服务器解决跨域
proxy: {
//会把请求路径中的/api换为后面的代理服务器
'/api': {
//提供数据的服务器地址
target: 'http://39.98.123.211',
}
},
}
}
//安装并引入vuex,根目录创建store文件夹,创建index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//创建store仓库并暴露出去
export default new Vuex.Store({
//state包含组件的状态,是数据源
//注意:vuex中的数据不是永久的,页面刷新后,数据会被重置
state:{
count: 0
},
//更改store中状态的唯一方法是提交mutation,在组件中通过method提交mutation
mutations:{
increment(state) {
return state.count++
}
},
})
//在main.js中引入上述文件,并在vue实例中注册store
import store from './store'
new Vue({
render: h => h(App),
//注册路由,此时组件中都会拥有$router $route属性
router,
//注册store,此时组件中都会拥有$store
store
}).$mount('#app')
//方法一 ,在组件中通过computed返回state中数据
computed: {
count() {
//state数据是响应式的,通过计算属性将获取的数据返回即可
return this.$store.state.count;
},
},
//方法二 ,使用mapState辅助函数,当一个组件需要多个状态都声明为计算属性会比较冗余,可以使用辅助函数生成计算属性
computed: mapState(['count']),
//在mutations中定义更改数据的方法
mutations:{
//除了传入state数据源还可以传入额外的参数
increment(state) {
return state.count++
}
}
//在组件中提交变更
//方法一 , this.$store.commit
methods: {
addCount() {
//在方法中通过提交一个mutation的方式提交变更
this.$store.commit('increment');
},
}
//方法二 , 使用mapMutations辅助函数将methods映射为 store.commit 调用,在组件中直接使用increment作为事件处理函数即可
methods: {
...mapMutations(['increment']),
}
actions: {
//action不能直接修改state,需要通过提交mutation变更state
incrementAsync(context) {
setTimeout(() => {
context.commit('increment')
},1000)
}
}
//方法一 , this.$store.dispatch
methods: {
addCountAsync() {
//在组件中触发异步函数
this.$store.dispatch('incrementAsync');
},
},
//方法二 ,使用mapActions
methods: {
...mapActions(['incrementAsync']),
},
//在store中创建小仓库
import { getBaseCategoryList } from '@/api/index.js'
export default {
state: {
categoryList: []
},
mutations: {
getCateList(state, categoryList) {
state.categoryList = categoryList
console.log(state.categoryList);
}
},
actions: {
async getCateList(context) {
const { data: res } = await getBaseCategoryList()
console.log(res);
if (res.code !== 200) {
return
}
context.commit('getCateList', res.data)
}
}
}
//在大仓库中导入小仓库
import home from '@/store/home/index.js'
import search from './search';
export default new Vuex.Store({
modules: {
home,
search
},
});
//在组件中获取状态
this.$store.state.home.categoryList;
//安装
npm i -S lodash
//引入
import _ from 'lodash'
//防抖,前面所有的触发都会被取消,只会执行最后一次触发,到达规定延迟时间后,调用回调函数,返回新的 debounced(防抖动)函数
let debounced = _.debounce(function(){},1000)
//表示在1秒内只触发一次回调
_.throttle(function(){},1000)
import Mock from 'mockjs';
import banners from './banners.json';
import floors from './floors.json';
//mock方法第一个参数是路径,第二个参数是假数据
Mock.mock('/mock/banners', banners);
Mock.mock('/mock/floors', floors);
//父->子 (props)
//子组件
export default {
name: 'Floor',
props: ['floorList']
};
//父组件 绑定floorList属性并传值
<Floor :floorList="item"></Floor>
//子->父 ($emit)
//子组件
methods: {
sendTrademark(trademark) {
this.$emit('trademarkInfo', trademark);
},
}
//父组件 绑定自定义事件
<SearchSelector @trademarkInfo="trademark"></SearchSelector>
methods: {
trademark(trademark) {
this.searchParams.trademark = `${trademark.tmId}:${trademark.tmName}`;
this.dispatchSearch();
}
}
//非父子组件之间 (evenBus)
//先在main.js中创建bus
new Vue({
router,
store,
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this
}
}).$mount('#app')
//A组件
removeKeyword() {
this.$bus.$emit('clear');
}
//B组件
mounted() {
this.$bus.$on('clear', () => {
this.iptValue = '';
});
}
const count = arr.push('2','3')
,返回 count=3,此时arr=['1','2','3']
const remove = arr.pop()
,返回remove=3,此时arr=['1','2']
const newArr = arr.concat('4')
返回新数组['1', '2', '4']
,原数组并未被修改arr=['1', '2']
const a = arr.filter((item)=>return item>1)
,返回a=['2']
,此时arr=['1', '2']
。router.beforeEach((to,from,next)=>{
//to:可以获取你要跳转到的路由信息
//from:可以获取你从哪个路由而来的信息
//next:next()放行 next('/')放行到具体的路由 next(false)驳回
})