基础篇
插值表达式
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', 123,456) } //这里不建议用驼峰
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. router和this.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
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,
})