Vue全家桶

本文详细介绍了Vue.js的基本语法、插值表达式、数据绑定、计算属性、过滤器、watch、事件处理、路由控制、组件通信、Vuex状态管理、Cookie使用以及axios网络请求。涵盖了组件生命周期、路由守卫、模块化开发和常见工具如Vue Router、Vue Cookies和Axios的实战应用。
摘要由CSDN通过智能技术生成

基础篇

插值表达式

mustache(胡子)语法

<p>{{ msg }}</p>

字符插值

<!-- data中 content='<h1>123<h1>' -->
<div v-text="content"></div>
<div v-html="content"></div>

属性绑定

<p v-bind:name="name"></p>

<!-- 语法糖 -->
<p :name="name"></p>

数据、方法 仓

data: () => ({
  ......
}),
methods: {
  ......
}

计算属性

computed: {
  name: function () {
    return this.firsterName+lastName
  }
},
  • 计算属性所涉及到的 任何 data 中的数据发生了变化,就会 立即重新计算 这个计算属性的值,
  • 计算属性也是响应式的。
  • 调用的时候不要加 () ,直接把它 当作属性 去使用;
  • 计算属性有缓存功能,缓存最后return 的东西,所以计算属性一定是要有 return语句的。

过滤器

 <h1>{{text|abc}}</h1>
filters: {
  abc(data) {
    data+="李哈哈"
    return data
  }
}

watch监听

监视哪个变量,函数名就是哪个变量名

  • 不需要 用到 检测值 的 变化状态,只是发现 b 改变了 就触发
watch: {
  name() {
    ......
  }
}
  • 需要 用到 检测值 的 变化状态,发现 b 改变了 就触发
watch: {
  name(newVal, oldVal) {
    ......
  }
}
  • 监视data中的 对象 man:{name:‘tom’,age:10}
  watch: {
    man: {
      handler() {
        console.log(this.man)
      },
      deep: true
    }
  }
/* 说明:
deep设为了true,意味着会检测 man对象每一个属性的变化,如果该对象结构嵌套过深时,性能开销是蛮大。
实际中,我们往往需要检测的是对象的某一个属性,可以如下操作:
*/
  watch: {
    'man.name'() {
      console.log(this.man)
      alert(1234)
    }
  }
  • 监视 非DOM元素 、非状态 一类 的改变:
watch: {
'$route.path': function (newVal, oldVal) {
    **** 
  }
}

注册事件

<p  @click="fn1"></p>
<p  @click="fn1( ) ; fn2( )"></p>
<p  @click="fn1(123, $event)"></p>
  • 绑定事件不需要传参时,可以不写括号
  • 给一个事件同时绑定多个处理函数时,必须都写括号,彼此之间用分号隔开;
  • 方法在定义时写一个形参,绑定事件调用方法时若没有写(),那么会默认将 事件处理参数对象event 作为实参传入。
  • $event是事件处理参数对象固有写法,强行记住。

事件修饰符(@click.prevent.once=)

  • .once: 只会触发一次
  • .prevent: 防止执行预设的行为
  • .capture: 与事件冒泡的方向相反,事件捕获由外到内
  • .stop: 防止事件冒泡
  • .self: 只会触发自己范围内的事件,不包含子元素
  • .native: 给组件绑定事件

按键修饰符(@keyup.enter=)

  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up .down .letf .right
  • @keyup.键码 =’处理函数’

条件判断

<p v-if="score >= 90">优秀</>
<div v-else-if="score >= 60">及格</>
<p v-else>劝其退学</>
  • 参与判断的标签之间不能有任何其他不相干的内容
  • v-if:隐藏后不占位,如同 display:none;v-show:隐藏后占位,如同visibility:hidde,该元素上的数据依旧可用。

循环遍历

<li v-for="i in 10" :key="i">{{i}}</li>
<li v-for="(item, index) in array" :key="item"></li>
<li v-for="(value, key, index) in object" :key="value"></li>

表单元素 的 双向绑定

<input type="text" v-model="text">
<h1>{{text}}</h1>

修饰符:

  • v-model.lazy=“text”
  • v-model.trim=“text”
  • v-model.number=“text” //转为数字类型

钩子

  • beforeCreate

实例初始化,this指向创建的实例,不能访问到data、computed、watch、methods 上的方法和数据。这个阶段主的工作是 初始化 非响应式变量 ,也就是 工作变量 和 工作函数。

  • created

实例创建完成,可以访问data、computed、watch、methods 上的方法和数据;因为未被挂在到DOM上,所以不能访问到$el,进而也不能访问通过ref标记的元素(这也就是为什么在created钩子函数中操作DOM相关的代码要放到 $nextTick函数中的原因)。
这个阶段常用于简单的ajax请求,因为未被挂在到DOM上,所以请求过于复杂的内容,页面显示空白的时间会很长。

  • beforeMount

挂在开始之前被调用,先找到template模板,然后编译成render函数,最后挂在到页面上。

  • mounted

实例挂载到DOM上,此时可以通过DOM API 对DOM进行相关的操作了。这个阶段常会 获取 或 操作 节点,ajax请求。页面的初次渲染到此就完成了

  • beforeUpdate

响应式数据更新时调用,发生在虚拟DOM打补丁之前。

  • updated

界面完二次渲染的完成了

  • beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用,this仍能获取到实例。

  • destroyed

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被
移除,所有的子实例也会被销毁。

父、子组件 钩子的响应顺序:

设 A为父组件, 先引入了 子组件B,再引入 子组件C。

  • 首次渲染:(似 洋葱模型)

A: created -> B: created -> C: created -> B:mounted -> C:mounted -> A:mounted

  • 更新渲染:
  • A 中数据的更新 不会引起 B和C的钩子变化: A:updated
  • B 中数据的更新 不会引起 A和C的钩子变化: B:updated
  • A 传给 B数据的更新:B:updated-> A:updated
  • B 传给 A数据的更新:B:updated-> A:updated

钩子中有 异步

如果钩子函数中有异步代码,以上钩子按照顺序依次被调用执行,但是下一个钩子的执行不会等到 上一个钩子 中的 异步代码的执行完毕后在执行,因为异步代码 不是在主线程 执行的,所以只要上一个钩子 的同步代码执行完毕后,其下一个钩子函数就可以行了。

vue运行过程

Vue模板–(解析)–>抽象语法树–(编译)–>render函数---->虚拟DOM---->真实DOM(页面)

mixin混入

  • 混入: 是一种分发 Vue 组件中可复用功能的非常灵活的方式。
  • 混入效果:组件文件引入混入文件的js代码,共同管理 组件文件 的html代码
  • 使用: 在 组件文件 中 通过mixins属性 把 混入文件 引入进来就可以了。
  • 不在推荐: 在vue3被歧视了,原因是过多使用,会造成来源不明

栗子:

  • 混入文件: m.js
let mixA = {
  data:() =>({...}), 
  methods:{...},
  mounted() {...}
}
export default mixA;
  • 引入混入文件 的 组件文件: m.vue
import mixA from './m.js';
export default {
  name: "App",
  mixins: [mixA], //如有多个混入文件,往后添加就是了。
  data:() =>({...}), 
  methods:{...},
  mounted() {...}
}

说明:

  • data 和methods合并:

混入文件 和 组件文件 的 变量名 或 方法名 重名时, 选用原则是 自家优先

  • 钩子函数合并:

同名钩子函数 将混合为一个数组,因此都将被调用,但是调用顺序是 喧宾夺主
注意:混入文件的钩子函数中如果有异步数据请求,组件文件获取数据的时机是不好把握的。

DOM获取

<div id="app">
  <p ref="aaa"></p> 
  <kid ref="bbb"></kid> 
</div>
methods: {
  getElement() {
    // ref把aaa从 字符串  变成  变量
    this.$refs.aaa.style.color = 'red';

    // 使用子组件的 方法
    this.$refs.bbb.show(); 
  }
}
  • 如果拿到组件最外层的标签,还想继续拿组件内部的标签,可以这样写:
    this.$refs.aaa.getElementsByTagName(‘p’)[0]
  • 循环生成的元素是不能通过 ref 是标记的。

下一帧

  • 在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。
  • 与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。
 this.$nextTick(function()  {
        DOM操作
  })

实例属性

组件树

  • $parent:用来访问组件实例的父实例
  • $root: 用来访问当前组件树的根实例
  • $children:用来访问当前组件实例的直接子组件实例
  • $refs:用来访问v-ref指令的子组件

DOM访问

  • $el:用来挂载当前组件实例的dom元素
  • $els:用来访问vue实例中el属性指定的DOM元素

数据访问

  • $data:用来访问组件实例观察的数据对象
  • $options:用来访问组件实例化时的初始化选项对象

DOM方法的使用

  • $appendTo(elementOrSelector, callback):将el所指的DOM元素插入目标元素
  • $before(elementOrSelector, callback):将el所指的DOM元素或片段插入目标元素之前
  • $after(elementOrSelector, callback):将el所指的DOM元素或片段插入目标元素之后
  • $remove(callback):将el所指的DOM元素或片段从DOM中删除
  • $nextTick(callback):用来在下一次DOM更新循环后执行指定的回调函数

组件化 开发

组件传值

父子传值

1、父—>子
  • 父组件
<div id="app">    
  <Kid :msg="data"></Kid>
</div>
  • 子组件
export default {
  props: ['msg'],       
}

// 限制类型
props: {
  msg:[String,Number]// 设置默认值
props: {
  msg:{type:[String, Number]default"默认数据"}
}
  • 说明:
  • 当默认值是数组or对象的时候,默认值必须是一个函数,并且将其return出去。
  • 在js中使用驼峰命名法,在html中对应转化为 - 语法:
    props:[‘iLoveYou’] --对应–> <Kid :i-love-you=“data”/>
  • 父组件 给 子组件 传de值,在子组件中修改了,父组件中不受影响,若是若父组件修改了,那么子组件是同步修改的。
  • 不建议 直接在子组件中 修改 props中的数据。
子—>父
  • 父组件
<Kid @i-love-you="show"></Kid>

methods: { show(arr1,arr2) {...} }
  • 子组件
mounted () {  this.$emit('i-love-you', 123456)  } //这里不建议用驼峰

2、依赖、注入

可以把依赖注入看作一部分“大范围有效的 prop”, 只不过 祖先组件不需要知道哪些后代组件使用它提供的属性,后代组件也不需要知道被注入的属性来自哪里。

  • 祖先组件
export default {
  provide: () => ({
    msg: 'msg',
    msg2: 'msg2',
  }),
}
  • 后代组件
export default {
  inject: ['msg', 'msg2']
}

3、事件总线

组件间的通信的一种手段。

  • 创建事件总线实例: eventBus.js
import Vue from 'vue' ; 
let  eventBus = new Vue()export default eventBus ;
  • 定义事件
import  eventBus from "./eventBus.js";
// wtt事件 定义在mounted钩子函数里 以减少出错的概率
mounted() {
    eventBus.$on("wtt", data => {
          console.log(data)
    });
}
  • 触发事件
import  eventBus from "./eventBus.js";
methods() {
  aaa() {
   	eventBus.$emit("wtt", '参数信息');
  } 
} 
  • 注销事件
import  eventBus from "./eventBus.js";
methods() {
  bbb() {
   	eventBus.$off("wtt");// 注销wtt事件
   	// eventBus.$off(); // 注销所有事件
  } 
}

插槽

普通插槽

<template>
  <div> 
    <p>子组件</p> 
    <slot><p>插槽的默认值</></slot> 
  </div>
</template>

具名插槽

  • 子组件
<template>
  <div> 
    <p>子组件</p> 
    <slot name="aaa"></slot> 
  </div>
</template>
  • 父组件
<div id=”app”>
  <kid>
    <h1 slot=“aaa”>使用具名插槽</h1>
  </kid>
</div>

作用域插槽

  • 子组件
<template>
  <div>
    <slot :msg="data" name="aaa"></slot>
    <!-- 
      自定义属性msg上携带的数据data,只有占有该坑位的元素才可以使用
    -->
  </div>
</template>
  • 父组件
<template>
  <kid>
    <!-- 使用 具名、作用域插槽时,使用 #号的语法糖 -->
    <template #aaa="{msg}">
      <h1>{{msg}}</h1>
    </template>
  </kid>
</template>

说明:
在 父组件中 使用 作用域插槽 时 必须 使用 template标签 包裹内容

组件样式标签de常用属性

  • <style lang=“scss”>

插件下载:
npm i node-sass@4.14.1 sass-loader@10.0.2

  • <style scoped>

使得父样式 可以影响 子样式,子样式 影响不了 父样式。若没有这个属性那么父样式 和 子样式 可以相互影响。

  • 模块化开发中,引用css样式文件,在style标签中写: @import “文件路径”

vue-router

概述

  • 前端路由

在单页面应用程序中,这种通过hash(锚点值 url # 之后的内容)改变来切换页面的方式,称作前端路由(区别于后端路由),hash改变不会向后端发起数据请求。

  • 实现

实现 前端路由 的前提:改变URL时不向服务端发起请求,页面不进行整体的刷新。

方式一: url的hash 模式 -----> localhost:8081/#/home
方式二:HTML5的history模式 -----> localhost:8081/home
(方式二只是省略#号,性质未变)
这种模式下常用的方法有
history.pushState; history.back;history.go; hietory.replace

  • 安装

npm i vue-router

搭建路由

  • 路由文件: router.js
import VueRouter from 'vue-router'
import Vue from 'vue'

Vue.use(VueRouter)

import Hi from '@/components/HelloWorld.vue'

// 路由表: 这里路由的核心!!!
let routeList= [
  {
    path: '/aaa',
    name: 'home', // 路由名称(非必须)
    component: Hi,//立加载
  },
  {
    path: '/vvv',
    component: () => import('@/views/layout/Layout.vue')//懒加载
  }{
    path: '/abc'
    component: Com,
    children: [ // 路由嵌套
      {path: 'def' , component: KidCom}
    ]
  }{ path: ' * ' , component: 404}, //404路由
  { path: '/', redirect: '/login' } //重定向 路由
]

const router = new VueRouter({
  routes: routeList,
  mode: 'history',
})

export default router
  • main.js 中注册一下
import Vue from 'vue'
import App from './App.vue'
import router from './router/router'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router, // 注册一下
}).$mount('#app')

路由标签

<!-- 路由跳转 标签 -->
<!-- <router-link>原本是a标签,
    所以跳转后导航栏默认是通过hash值的方式去改变 
-->
<router-link to="/register">注册</router-link>

<!-- 路由展示 标签 -->
<router-view></router-view>

<!-- 路由保活 标签 -->
<keep-alive exclude="aaa,bbb">
    <router-view></router-view>
</keep-alive>

说明:

  • 默认情况下一旦离开 当前路由,那么当前路由的 相关组件 就会被销毁,相关数据也就不能用了,keep-alive标签,可以打破这个默认规则。
  • exclude 指定不被保活的路由,其属性值的逗号之后一定不要有空格!!!
  • exclude 的属性值是 路由表中 的路由名称,即 路由的 name属性值。

路由控制下的组件 比 普通组件 多两个钩子函数:

  • activited(){激活状态下回调函数}
  • deactivited() {待激活未销毁状态下的回调函数}

js进行 路由跳转

 this.$router.push('/login') //可返回跳转
 this.$router.replace('/login')//不可返回跳转
 this.$router.back() //返回

路由传参

params 参数

  • 先在路由文件中定义好 要传的 参数
{
  path: '/aaa/:name',
  component: () => import('@/components/HelloWorld.vue')
},
  • 出发路由 传参
    标签的形式 and js代码的形式:
<router-link to="/aaa/tom123">jump</router-link>
this.$router.push("/aaa/tom123")
  • 目标路由 取参
console.log(this. $route.params.name)

query 参数

    • 出发路由 传参
      标签的形式 and js代码的形式:
<router-link :to="{path:'/aaa’, query: {name: 'WTT'}}">jump</router-link>
this.$router.push({ path:'/aaa',  query: {name:"tom"}})
  • 目标路由 取参
console.log(this. $route.query.name)

重点理解一下: this. r o u t e r 和 t h i s . router 和 this. routerthis.route

  • $router

路由实例 , 控制路由大系统的工作,比如 路由跳转。

  • $route

当前路由, 描述当前所在路由的一些状态信息。

路由守卫

全局 守卫

路由文件:

const router = new VueRouter({
  routes: routeList,
  mode: 'history',
})

// 全局守卫
router.beforeEach((to, from, next) => {
  // 进入==每个路由== 都要弹框 问一下 是否确定进入
  let res = window.confirm('Are you sure enter cart')
  if (res) {
    next() //放行
  } else {
    next(false) //拒绝
  }
})

export default router

守卫 回调函数 的 参数 说明:

  • to

即将要进入的 目标路由对象

  • from

即将要离开的 路由对象

  • next

路由跳转函数:
next() => 放行
next(false) => 拒绝
next(‘/login’) => 跳转到指定路由

扩展:
利用 全局守卫 实现 到哪一个路由, title标签 就显示哪一个 路由的名称:

router.beforeEach((to, from, next) => {
	if(to.meta.title) {
		document.title = to.meta.title
	}
	next();
})

单路由 守卫

//路由表
let routeList = [
  {
    path: '/aaa',
    component: Com,
    // 单路由 守卫
    beforeEnter(to, from ,next) {
      let res = window.confirm('Are you sure enter?')
      if(res) {
        next() //放行
      } else {
        next(false) //拒绝
      }
    }
  },
]

组件路由 守卫

放在组件中的 路由守卫,这个组件必须是 在 路由表中 指定的 组件
组件路由守卫 可以用在 单路由守卫下 的 嵌套 子路由中 比较敏感的页面中。

export default {
  data: () => ({......}),
  methods: {......},
  // 进入 该组件时,进行盘问的 路由守卫
  beforeRouteEnter(to, from, next) {
    let res = window.confirm("Are you sure enter?");
    if (res) {
      next(); //放行
    } else {
      next(false); //拒绝
    }
  },

  // 离开 该组件时,进行盘问的 路由守卫
  beforeRouteLeave(to, from, next) {
    let res = window.confirm("Are you sure leave?");
    if (res) {
      next(); //放行
    } else {
      next(false); //拒绝
    }
  },
};

说明:

beforeRouteEnter函数 先行于 在data()函数之前,因此在beforeRouterEnter函数中不能使用this来代表实例组件,因为组件还没有初始化。
那么就是要用this的话怎么办哪?可以用to.matched[1]。
因为 to对象中的matched[0]是路由组件B的父路由组件A;matched[1]是路由组件B自己。所以可以通过to.matched[1] 来代替实例。(路由关系:A/B---->matched[0]/matched[1])

路由文件中使用 vuex中的数据

不能 像在组件 中 :this.$store.state直接这样使用,
应该先引入 store文件: import store from “@/store/vuex.js”
然后: store.state

Vuex

概述

保存全局数据的仓库store,前面说到过 事件总线,只能 跨组件传值,跨路由是传值不了的,Vuex是可以做到跨路由的。
安装: npm i vuex

搭建store

  • store文件: vuex.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

let storeBox = {
  state: {},
  getters: {},
  mutations: {},
  actions: {}, 
  modules: {},
} 

let store = new Vuex.Store(storeBox)
export default store
  • main.js 中注册一下
import Vue from 'vue'
import App from './App.vue'
import router from '@/router/router.js'
import store from '@/store/vuex.js'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router, 
  store,// 注册一下
}).$mount('#app')

基本使用

state

//store 中
state: {
  aaa: 'tom'
}

// 组件中使用
this.$store.state.aaa

getters

//store 中
getters: {
  abc(state, getters) {
    console.log(getters)
    let s = "李哈哈"
    return state.aaa + s
  }
}

// 组件中使用
this.$store.getters.abc

mutations

  • 无参 控值
//store 中
mutations: {
  changeAaa(state) {
    state.aaa = "123456"
  }
},

// 组件中使用
this.$store.commit('changeAaa')
  • 有参 控值
//store 中
mutations: {
  changeAaa(state,payload) {
    state.aaa = payload.wtt.name
  }
},

// 组件中使用
let payload = {
  type: 'changeAaa',
  wtt: {
    name:'cat'
  }
}
this.$store.commit(payload)

actions

//store 中
actions: {
  handleAaa(content, payload) {
    console.log(content.state.aaa);
    console.log(payload); //--->{type: 'handleAaa',data: 'msg'}

    let name = payload.data
    content.commit({ type: 'changeAaa', data: { name, } })
  }
},

// 组件中使用
let payload = {
  type: 'handleAaa',
  data: 'msg'
}
this.$store.dispatch(payload).then(() => {
	console.log("It is ok")
})

module

modules: {
  AAA: {
    state: {
      name: 'cat'
    },
    getters: {
      comput() {
        
      }
    },
    mutations: {

    },
    actions: {

    }
  }, 
  BBB: {
    ......
  }
}
//store 中
modules: {
  module111: {
    
    state: {
      name1: 'jerry'
    },
    getters: {},
    mutations: {
      changeName(state, payload) {
          state.name1 = payload.data
      }      
    },
    actions: {
      handleName(content,payload) {
          // 总部的 state数据
          console.log(content.rootState.aaa)
          // 模块的 state数据
          console.log(content.state.name)

          content.commit({
              type: 'module111/changeName',
              data: payload.data
          })
      }
    },
  },
  module222: {

  }
},

// 组件中使用:
// state
this.$store.state.module111.name1

// mutations
let payload = {
  type: 'module111/changeName',
  data: 'cat123'
}
this.$store.commit(payload)

// actions
let payload = {
  type: 'module111/handleName',
  data: 'cat123'
}
this.$store.dispatch(payload)

命名空间namespaced 说明:

module中的 mutations和全局的mutation使用的方式是一样的,这个就不行了,若多个module中有相同的mutations 方法名,则一触发,全响应,那数据就乱了。
所以为了让mutations中的方法和state有一样的区别使用的效果,这里我们引入 命名空间。
做法很简单,在每个modules中加入 启动 命名空间的属性就可以了

vue-cookie

下载

npm i vue-cookies

安装

在main.js文件中加入:

import VueCookies from 'vue-cookies'

Vue.use(VueCookies)

使用

  • 设置全局配置项:
this.$cookies.config(expireTimes[,path])
  • 设置:
this.$cookies.set(key, value [, expireTimes [, path [, domain [, secure ]]]] )
  • 获取:
this.$cookies.get(key) 
  • 删除:
this.$cookies.remove(key [, path [, domain]]) 
  • 是否存在:
this.$cookies.isKey(key)
  • 获取所有 cookie name,以数组形式返回:
this.$cookies.isKey(key)

使用栗子

// set path
this.$cookies.set("name","tom","1d","/app");  
// set domain
this.$cookies.set("name","tom",null, null, "domain.com");  
// set secure
this.$cookies.set("name","tom","value",null, null, null,true);

//设置cookie过期时间
/*
  说明: y=>year;m=>month;d=>day;h=>hour;min=>minute;s=>second
*/
this.$cookies.set("name","tom") //==>不写过期时间,默认为1天过期
this.$cookies.set("name","tom","2d") // ==>2天后过期

this.$cookies.set("name","tom",60 * 60 * 2) // ==>2个小时后过期
this.$cookies.set("name","tom", new Date(2020, 02, 02)) //==>2020年2月2号那天过期
this.$cookies.set("name","tom","0") // ==> 浏览器会话结束时过期
this.$cookies.set("name","tom",-1)  // ==> 永远不过期!!!

axios

let’s go

Vue CLI

安装使用

npm install @vue/cli -g
vue create 项目名(项目名不要有中文)

配置文件:vue.config.js

Vue.js CLI工具 不知不觉发展到了4.0时代,CLI给人最直白的感受是没有了build文件夹跟config文件夹,所有的配置都在Vue.config.js完成。那么该文件的配置至关重要。
脚手架项目创建好后项目目录中是没有vue.config.js文件的,此时需要我们在项目的根目录下手动创建vue.config.js

module.exports = {
    // 公共路径, 此配置项是 控制 打包生成 index.html文件 引入资源公共路径的 
    // 默认为"/",建议使用"./"相对路径,
    // 使用相对路径的最大好处是,打包之后的文件可以==直接本地==打开查看效果
    // 当然 直接本地 前提是 项目中未使用 路由
    publicPath: "./", 

    // build打包输出目录
    outputDir:"dist", 

    // 输出html文件名
    indexPath: "index.html",  

    // 静态文件输出目录,src开发目录下的所有 静态资源文件 在打包后 全部都集中在dist下 assets文件夹 中了
    assetsDir:"src_assets", 

    productionSourceMap: false, // 取消.map文件的打包,加快打包速度

    lintOnSave: false,  // 取消lint语法检测,此处可不配置

    // Webpack 相关配置
    configureWebpack: (config) => {
      // process.env为环境变量,分别对应.env.development文件和.env.production文件 此处表示加快开发环境打包速度
      if (process.env.NODE_ENV !== 'production') return;
        config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true;	//生产环境去掉console.log
        return {  // 此处配置webpack.config.js的相关配置
            plugins: [],
            performance: {}
        };
    },

    // 由 Webpack 扩展 的 配置
    chainWebpack: (config) => {
        config.resolve.symlinks(true); // 修复热更新失效
        config.resolve.alias // 添加别名
            .set('@', resolve('src'))
            .set('@assets', resolve('src/assets'))
            .set('@components', resolve('src/components'))
            .set('@views', resolve('src/views'))
            .set('@store', resolve('src/store'));
    }// 本地服务器配置(npm run serve)
    devServer: {   
      port: 8080, // 端口
      host: "localhost", // 域名
      https: false, // 是否开启https
      open: true	// 是否在开启服务器后自动打开浏览器访问该服务器
      hotOnly: true, // 热更新


/*
注意:
    1、如果使用的 uniapp 自带的网络请求框架, 配置代理则需要在 manifest.json中的 h5 选项中配置,
       这里 使用的是 第三方网络请求框架 flyio , 配置代理 需要在 vite.config.js 中配置。
    2、代理 捕获的是 本地项目启动 同源的 请求,例如: npm run dev  启动监听的是 localhost:5612, 
       那么代理获取的请求的范围 就是 请求地址是 localhost:5612, 然后在通过路径进行 具体捕获。

    proxy: {
      '/h5_api': { // 匹配 本地 请求路径 localhost:5173/h5_api
          target: 'http://192.168.104.60:8668', // 代理的目标地址
          changeOrigin: true, // 开发模式, 默认的origin是 真实的 
          secure: false, //  是否https接口
          ws: false, // 是否带来websockets
  	
          // localhost:5173/h5_api/test   ==> http://192.168.104.60:8663/wtt/test
          rewrite: (path) => path.replace('/h5_api', '/wtt'),
      },
    },

*/
    proxy: {
      '/api_default': {
        target: 'http://121.4.225.175:8000', 
        changeOrigin: true,
        secure: false,
        rewrite: (path) => path.replace('/api_default', ''),
      },
    },
  },

      // 通过 代理 进行 多个数据源的 跨域 处理
      proxy: {
          // 加入 请求的后台多个,我们则需要 配置多个跨域
          '/api': {
                target: 'http://ffsdas:8036',  //后端服务器域名
                changeOrigin: true,  //是否跨域 
                pathRewrite: {
                    '^/api': '/' 
                    // '^/api': ' ' 
                }
            }
          '/api2': {
                target: 'http://asdf:8888',  //后端服务器域名
                changeOrigin: true,  //是否跨域 
                pathRewrite: {
                    '^/api2': '/' 
                }
            }
      }
    },
};

环境文件

文件名称

位置是和package.json 同目录

  • .env

全局默认配置文件,不论什么环境都会加载合并

  • .env.development

开发环境下的配置文件, npm run serve 时 会加载合并

  • .env.production

生产环境下的配置文件, npm run build 时 会加载合并

文件内容

自定义属性名必须以VUE_APP_开头,比如VUE_APP_WTT

  • .env
VUE_APP_WTT=abc
  • .env.development
VUE_APP_BASE_URL=http://localhost:8080/aaa
  • .env.production
VUE_APP_BASE_URL=https://baidu.com:8080/aaa

使用 环境文件 的内容

process 对象是一个 global (全局变量),提供有关信息,控制当前 Node.js 进程。

data: ()=> ({
	url: process.env.VUE_APP_BASE_URL,
})
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值