vue3笔记
笔记
全局挂载
//main.js
const apps = createApp(App);
// 全局挂载
apps.config.globalProperties.$_lodash = lodash;
// 组件中
import { getCurrentInstance } from 'vue';
let { proxy } = getCurrentInstance();
//取值
let res = proxy.$_lodash.cloneDeep(res0);
获取原始对象 用 toRaw
在ajax请求放入参数的时候可能会用到
setup() {
let obj={name:'lj',age:18}
let state=reactive(obj)
let obj2=toRaw(state)
console.log(obj===obj2); //true
function myFn(){
obj2.name='zs'
console.log(state); //Proxy {name: "zs", age: 18}
console.log(obj2); //{name: "zs", age: 18}
}
return {
myFn,state
}
},
process.cwd()
process.cwd() 方法返回 Node.js 进程的当前工作目录。
import { cwd } from 'process';
console.log(`Current directory: ${cwd()}`);
Env变量和模式
Vite在特殊的 import.meta 中公开环境变量。env对象。一些内置变量在所有情况下都是可用的。
import.meta.env.MODE: {string}应用程序运行的模式。
import.meta.env.BASE_URL:{string}应用程序提供服务的基础url。这由基本配置选项决定。
import.meta.env.PROD: {boolean}是否在生产环境中运行
import.meta.env.DEV: {boolean}应用是否在开发中运行(总是与import.meta.env.PROD相反)
Production Replacement
在生产过程中,这些env变量被静态地替换。因此,必须始终使用完整的静态字符串引用它们。例如,像import.meta这样的动态密钥访问。env[key]不起作用。
它还将替换JavaScript字符串和Vue模板中出现的这些字符串。这应该是一个罕见的情况,但它可能是无意的。有一些方法可以解决这个问题:
对于JavaScript字符串,你可以用一个unicode零宽度的空格来分隔字符串,例如。“import.meta \ u200b.env.MODE”。
对于被编译成JavaScript字符串的Vue模板或其他HTML,你可以使用标签,例如import.meta.env.MODE。
.env Files
Vite使用dotenv从你的项目根目录下的以下文件中加载额外的环境变量:
.env
__dirname
__dirname 是node的一个全局变量,获得当前文件所在目录的完整目录名
当你在 /d1/d2/myscript.js 文件中写了 __dirname, 它的值就是 /d1/d2 。
例如在vite中配置别名
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
},
},
vite共享配置 mode
类型: string
默认: ‘development’(开发模式),‘production’(生产模式)
在配置中指明将会把 serve 和 build 时的模式 都 覆盖掉。也可以通过命令行 --mode 选项来重写。
export default(({mode})=>{
return defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
},
},
base: "/",
build: {
brotliSize: false,
chunkSizeWarningLimit: 1024,
},
server: {
// host: "localhost",
port: 3030,
// 是否自动在浏览器打开
open: false,
// 是否开启 https
https: false,
proxy: {
'/api': {
target: loadEnv(mode,process.cwd()).VITE_ADMIN_BASE_API,
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
},
'/psi': {
target: loadEnv(mode,process.cwd()).VITE_PDS_BASE_API,
changeOrigin: true,
rewrite: path => path.replace(/^\/psi/, '')
},
'/Cti': {
target: loadEnv(mode,process.cwd()).VITE_BASE_API,
changeOrigin: true,
rewrite: path => path.replace(/^\/Cti/, '')
}
},
},
});
})
关于v3 ref 和 reactive 的坑
reactive 有个比较大的缺点 不能整体重新赋值 重置数据麻烦。想要整体赋值的话需要在对象中创建一个属性 对这个属性进行整体值的切换。最后还是避免不了内部引用。
例如使用element的多选框组 使用 reactive 直接创建一个数组的话是不起作用的
const info = reactive(data:{xxx:'ooo'})
更新时:
info.data = {xxx:'aaa'}
使用ref
const info = ref({xxx:'ooo'})
更新
info.value = {xxx:'aaa'}
总结: 除 对象/json/复杂的嵌套数组外。其他全用 ref :如基本类型、一维数组
关于资源、组件 引入时的后缀
v3的项目中引入组件和api接口的时候,最好把后缀也带上。否则有可能出现找不到模块的问题
v3组件传值
script setup 中的传值方式
- defineProps
- defineEmits
- Provide / Inject
defineProps父传子
和props的用法几乎一样
//子组件中
const props = defineProps({
foo: String
})
//取值
props.foo
defineEmits子传父
和Emit用法几乎一样
//子组件
let emit = defineEmits(['submission']);
emit('submission',{a:1,b:2});
//父组件
<myCustomTimeSection @submission="customTimeFn" />
let customTimeFn = (val)=>{
console.log(val) // {a:1,b:2}
}
Provide / Inject
依赖注入
可以将依赖注入看作是“长距离的 prop”除了
- 父组件不需要知道哪些子组件使用了它 provide 的 property
- 子组件不需要知道 inject 的 property 来自哪里
Provide
中允许定义两个参数
1、name (String 类型)
2、value
Provide 能够正确传递 ref reactive 的响应式数据,但要尽可能将对响应式property的所有修改限制在provide的组件内部
如果需要Inject接收注入的组件内部更新数据的话。这种情况下最好用Provide传入一个方法来负责在子组件中改变父组件的数据
//父组件
let addClose = ()=> {
addSwitch.value = false
}
provide('addCloseFn',addClose)
//子组件
<span @click="addCloseFn" >x</span>
const addCloseFn = inject('addCloseFn');
如果要确保通过 provide 传递的数据不会被 inject 的组件更改建议使用 readonly
<script setup >
import { provide, reactive, readonly, ref } from 'vue';
const location = ref('North Pole')
const geolocation = reactive({
longitude: 90,
latitude: 135
})
provide('location', readonly(location))
provide('geolocation', readonly(geolocation))
</script>
Inject
1、要 inject 的 property 的 name
2、默认值 (可选)
//子组件中
<script setup >
import { inject } from 'vue'
const userLocation = inject('location', 'The Universe')
const userGeolocation = inject('geolocation')
</script>
v3动态组件
如果是在 script setup 单文件组件中使用的话
这时候 组件被引用为变量而不是作为字符串键来注册
所以书写方式要有一定改变
<component :is="currentElementComponent[componentPoint]"></component>
// script setup 中
import { ref } from "vue";
import demonstrationOne from './conView/demonstrationOne.vue'
import demonstrationTwo from './conView/demonstrationTwo.vue'
let currentElementComponent = {
'demonstrationOne':demonstrationOne,
'demonstrationTwo':demonstrationTwo
}
let componentPoint = ref('demonstrationOne')
git删除远程仓库链接地址
常用于本地不想影响到远程的时候
//查看当前远程仓库链接
git remote -v
//根据第一步查询出来的链接删除别名即可
git remote rm origin
//git remote -v 没有查询出东西来表示删除成功了
动态组建可以像普通组建一样传值
插槽传值
<slot :属性=“要传的值”>
Map.vue 组件中
使用Map.vue组件
Map.vue 组件
使用Map.vue 组件
props
在设置默认值的时候对象或数组的默认值必须从一个工厂函数返回
props: {
// 基础的类型检查 (`null` 和 `undefined` 值会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组的默认值必须从一个工厂函数返回
default() {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator(value) {
// 这个值必须与下列字符串中的其中一个相匹配
return ['success', 'warning', 'danger'].includes(value)
}
},
// 具有默认值的函数
propG: {
type: Function,
// 与对象或数组的默认值不同,这不是一个工厂函数——这是一个用作默认值的函数
default() {
return 'Default function'
}
}
}
slot
无论是使用jsx还是模板,最终都会编译成render函数,并且render函数在执行之后会输出 Virtual Dom
- 所有的模板会被编译成创建vnode的函数。
- 父组件中传递给子组件的插槽(每个插槽都是一个函数,即名字不同的插槽为不同的函数)内容模板也会被编译成函数并且传递给子组件,模板中如果使用了父组件的变量,那么会通过闭包的形式在插槽函数中被使用。
- 子组件在接收到父组件传递的插槽内容函数,会以在slot暴露的变量(只有作用域插槽有这些变量)为参数执行这个函数,返回vnode,这个vnode会作为子组件vnode的一部分。
watch
watch时有一个特点,就是当值第一次绑定时,不会执行监听函数,只有值发生改变时才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,此时就需要deep属性对对象进行深度监听。
vuex 的使用
在setup语法糖中使用vuex
import { useStore } from 'vuex';
const store = useStore();
配合modules使用
import { createStore } from 'vuex'
import monitor from "./modules/monitor.js";
export default createStore({
// 外部模块
modules:{
monitor
},
})
monitor 下的 mutations 中的 m_createdDotidentification
store.commit('monitor/m_createdDotidentification');
monitor 下的 state 中的 exhibitionDot
store.state.monitor.exhibitionDot
v3使用全局变量
setup
//main.js
import lodash from 'lodash';
const apps = createApp(App);
apps.config.globalProperties.$_lodash = lodash;
//组件中
import { getCurrentInstance } from 'vue';
let { proxy } = getCurrentInstance();
proxy.$_lodash.cloneDeep()
选项卡
// main.js
import mitt from "mitt";
const apps = createApp(App);
apps.config.globalProperties.$mybus = new mitt();
//组件中
this.$mybus.on();
this.$mybus.emit();
打开新窗口
let DataUrl = this.$router.resolve({
path: "/aaa",
query:{
ruleChat: row.id
},
});
window.open(DataUrl.href, "_blanks");
history模式下上线刷新页面404
nginx
location / {
try_files $uri $uri/ /index.html;
}
这种情况的成因是这样的
history模式是通过js才改变浏览器地址栏的路径,并没有发起http请求。刷新浏览器等于重新发起http请求请求不到对应的参数直接就404了
vite解决跨域问题
实际上跨域方案就这么几个
- vue中的proxy跨域(原理是Node中间件代理)
- Jsonp跨域
- cors (跨域资源共享)
- nginx反向代理
这里说一下proxy跨域
vite.config.ts文件中
proxy: {
"/api": {
target: 'http://crmeb.cimns.com/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
更多推荐
所有评论(0)