(vite + vue3 )
基础
1.基础 语法和传值问题
// 传值 defineProps defineEmits
// 父组件
<template>
<div> <Child :msg = "userInfo.info" @change="change"/></Child> </div>
</template>
<script setup>
// hooks: reactive ref defineProps defineEmits
import { reactive } from "vue";
// 子组件触发父组件函数 达到传值目的
const change = (e) => {
console.log(e)
}
// 定义响应式数据
const userInfo = reactive({
info:[
{text:"欢迎新同学"},
{text:"你们能来我非常高兴"}
]
})
</script>
// 子组件
<template>
<div>
<p v-for="(item,index) in info.msg" :key = "index"> {{ item }}</p>
<button onClick="trants"> 点击传递参数 </button>
</div>
</template>
<script setup>
import {reactive, ref,defineProps,toRefs,defineEmits} from "vue";
const emit = defineEmits()
// 父传子
const props = defineProps({
msg:[],
})
const info = reactive({
text:[...props.msg],
userInfo:{name:"xiaoming"}
})
// 子传父
const trants = () => {
emit(["change", info.userInfo])
}
</script>
// 插槽 solt 就是子组件给父组件的一个位置空间 让父组件写内容
// 父组件
<template>
<Child>
这里面是默认插槽
<template #header>具名插槽</template>
</Child>
</template>
// 子组件
<template>
<solt>默认插槽</solt>
<solt name="header">具名插槽</solt>
</template>
// 钩子 useAttrs() 接收父组件未被定义的数据 及defineProps没定义的数据
// 在需要接收的组件种定义 const attrs = useAttrs() <GrandChild v-bind="attrs"/> 此组件接收 <div> {{attrs}}</div>
// 接收 GrandChild 组件定义props 接收
// provide inject 传值
// 祖先组件
import { ref, provide, readonly} from 'vue';
const users = reactive({
info:[{name:"4848"},{name:"10025"}]
});
provide('obj',readonly(users)); // provide("key",value) value 可以是带有形参的函数从而达到子传祖
// 子组件
import { inject } from 'vue';
let obj = inject('obj') // inject("key") 子组件无发!!直接!!修改祖先组件的值
2.路由相关
// 文件 src --> router
// 基础知识 vue-router
// npm install [email protected]
import { createRouter,createWebHashHistory} from "vue-router";
// routes 路由表
const routes = [
{
path: "/index1",
name: "index1",
component: () => import('/src/views/index1.vue')
},
{
path: "/index2",
name: "index2",
component: () => import('/src/views/index2.vue')
}
]
//createWebHistory createWebHashHistory 两种模式 区别就是 Hash模式根路径带/#/
export default createRouter({
history:createWebHashHistory(),
routes:routes
})
// 路由信息获取 script setup -->
import { useRouter } from 'vue-router';
const router = useRouter()
console.log(router.currentRoute.value.params.caseId)
// 路由跳转
const ChangeRouter = () => {
router.push("/") //or router.replace() 这种跳转不能后退 一般都用push 具体看场景
}
// 路由传递参数
const setRouterData = () => {
router.push({
name:"Home",
params:{ // 这里可以用 query
name:"JNTMGG",
age:18
}
})
}
// 接收参数
import { useRoute,onMounted } from "vue";
const route = useRoute();
onMounted(() => {
console.log(route.params) // query 传参就 params --> query
})
// 路由守卫 全局拦截:
router.beforeEach((to, from, next) => {
if (to.meta.isKerwinRequired) {
// 判断 本地存储中是否token
if (localStorage.getItem('token')) {
// next():不拦截,放行
next()
} else {
next('/login')//跳转到登录页面
}
} else {
next()
}
})
// 局部拦截 ---> 在路由表添加 -->
beforeEnter: (to, from, next) => {
if (localStorage.getItem('token')) {
// next():不拦截,放行
next()
} else {
next('/login')
}
}
// 本项目是动态路由 需要前端根据后端路由表配置路由
// 原理:获取后端路由表---> 由 vuex 整合表 后端路由表 根据 前端表 进行过滤 ---> 把相同的路由保留 ---> 生成动态路由
3.vuex相关
// 文件 src --> store
// vuex --> state、moutations、actions、 modules 一切的一切 都是为了 获取--修改 state中的 数据
// state 全局状态数据
// dispatch commit()
// 单页面状态管理: View–>Actions—>State 视图层(view)触发操作(action)更改状态(state)响应回视图层(view)
// 获取state
import { useStore } from 'vuex'
const store = useStore()
console.log(store)
// mutions 修改数据 和 传入参数 第一个参数是state 第二个则需要外部传递参数去计算
mutations: {
// 传入 state
increment (state,num) {
state.count += num
}
}
// 触发方式
store.commit("模块/方法名") // 例如 user.js 模块 store.commit("user/increment",3)
const add = () => {
// 第一种风格
store.commit("user/increment",3)
// 第二种风格
store.commit({
type:"user/increment",
3
})
}
// actions 若state 数据需要异步操作 则 先actions异步操作 再传递到 mutations
mutations: {
sum (state, num) {
state.count += num
}
},
actions: {
// context 上下文对象,可以理解为store 可以直接解构 --> sum_actions ({ commit }, num)
sum_actions (context, num) {
setTimeout(() => {
context.commit('sum', num) // 通过context去触发mutions中的sum
}, 1000)
}
// 页面通过 dispatch 调用 acitons
// store.dispatch('sum_actions', num)
const addAction = (num) => {
store.dispatch('sum_actions', {
num
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
}
// getters 类似 computent(防止代码冗余)
state: {
students: [{ name: 'mjy', age: '18'}, { name: 'cjy', age: '22'}, { name: 'ajy', age: '21'}]
},
getters: {
more20stu (state) { return state.students.filter(item => item.age >= 20)}
}
// 获取getters 数据
store.getters.more20stu // 展示小于20 的学生
// modules 复杂项目中 全局数据很多而且得分类 要不难以维护
// 在modules 中创建单一得模块 一个模块一个功能
// user.js
export default {
namespaced: true, // 为每个模块添加一个前缀名,保证模块命明不冲突
state: () => {},
mutations: {},
actions: {}
}
modules: {
user,
pay,
cat
}
store.dispatch('user/sum_actions', sum)
4.计算和监听
// script - setup 现在的v3不需要引入 { watch ,computed } 但是还是引入好一点
// computed!
import { ref, computed } from 'vue';
let count = ref(1);
// 防止定义多个数据 造成代码的冗余
let com = computed(()=>{
if(count.value < 1000) return "你只有"+count.value + "块钱";
if(count.value >= 1000) return "哇,你有"+count.value +"哎!";
})
// 写法 2
let com1 = computed({
get:() => {
return count.value;
},
set:val => {
if(count.value < 1000){
count.value = "你只有"+count.value + "块钱";
}
if(count.value >= 1000){
count.value = "哇,你有"+count.value +"哎!";
}
}
})
// watch!
import { ref, watch } from 'vue';
// 监视一个ref属性,newVal、oldVal与监视的值保持一直
let price = ref<number | string>(1);
watch(price, (newVal, oldVal) => {
console.log(newVal);
console.log(oldVal);
});
// 监视多个ref属性,newVal、oldVal是一个数组
let price = ref<number | string>(1);
let price1 = ref<number | string>(1);
watch([price, price1], (newVal, oldVal) => {
console.log(newVal);
console.log(oldVal);
});
// 打印的值只要变化 就会重新打印
//监视一个ref对象 watch("name",function())
let message = ref({
nav: {
bar: {
name: 'zhangsan',
},
},
});
watch(
message,
(newVal, oldVal) => {
console.log(newVal, oldVal);
},
{
immediate: true,// 初始化就开启监视
deep: true,// 开启深度监视
}
);
import { reactive, watch } from 'vue';
// 监视一个reactive对象,监视reactive对象默认就会开启深度监视!
let message = reactive({
nav: {
bar: {
name: 'zhangsan',
},
},
});
watch(message, (newVal, oldVal) => {
console.log(newVal, oldVal);
});
// 监视reactive对象中的某个属性 watch("函数rerutn返回值",function())
watch(
() => message.nav.bar.name,
(newVal, oldVal) => {
console.log(newVal, oldVal);
}
);
5.跨域
// 跨域 vite.config.js
export default defineConfig({
plugins:[vue()],
server:{
port:3000,
open:true,
base:"./",
proxy:{
"/api":{
target:'https://cavan.cc',/ 跨域地址 url 写什么 那边就替换什么
changeOrigin:true,
}
}
}
})
// axios baseURL ---> config--->net.config.js
axios.defaults.baseURL = "/api"
// 请求的实际地址是 https://cavan.cc/api 显示的请求地址是 http://localhost:端口号/api 跨域完成
6.生命周期
<script setup>
// setup ---> beforeCreate 和 created 之前 创建数据和函数
// 类似格式 fun(()=>{})
// onBeforeMount ---> 节点挂载前
// onMounted ---> 节点挂载完成
// onBeforeUpdate ---> 组件更新前
// onUpdate ---> 组件更新完成
// onUpdated ---> 组件更新完成之后执行的函数
// onBeforeUnmount ---> 组件卸载之前执行的函数
// onUnmounted ---> 组件卸载完成后执行的函数
// onActivated ---> 被包含在 <keep-alive> 中的组件,会多出两个生命周期钩子函数,被激活时执行
// onDeactivated ---> 比如从 A 组件,切换到 B 组件,A 组件消失时执行
// one rrorCaptured ---> 当捕获一个来自子孙组件的异常时激活钩子函数
</scrpt>
1表格导出
<script setup>
// npm install js-table2excel
import table2excel from 'js-table2excel';
// 模拟表格数据 tableData 类型 ---> 数组 [ {},{},{} ]
const tableData = {
value:[
{
id:111,
sciencename:"郑州好风景",
time:"51515-000"
},
{
id:222,
sciencename:"洛阳好风景",
time:"51515-112"
},
{
id:333,
sciencename:"新乡好风景",
time:"51515-7663"
},
{
id:444,
sciencename:"南阳好风景",
time:"51515-1123"
},
{
id:555,
sciencename:"开封好风景",
time:"51515-55"
},
{
id:666,
sciencename:"商丘",
time:"51515-123"
}
]
}
// 处理后端数据 创建表头信息 如果不创建 下面要想实现功能 可能会写多个if类型的代码屎
const judge = {
id:"二维码id",
sciencename:"景区风景",
time:"创建时间"
}
// 整理表头字段名称 对象的 key 此处可用:
// let arr = Object.values(tableData.value[0]);
const arr = ['id','sciencename','time']
// 处理数据
const data = arr.reduce((pre,val)=>{
let obj = {title:judge[val],key:val,text:"text"}
pre.push(obj)
return pre
},[])
// 导出按钮 添加的方法
// 表格列的设定 title:表格列名称 key:根据表格对应字段进行导出 type 表示类型 (text文本 ,img:图片)
// 表格列数比较多 建议通过遍历计算 进行导出
// column 中的信息 是写死的表头 上面的data 数据是自己通过后端数据处理的 这里根据个人习惯
// 可以参考 项目中 src --> element --> demo 中的导出
const column = [
{
title: '二维码id',
key: 'id',
type: 'text',
},
{
title: '景区名称',
key: 'sciencename',
type: 'text',
},
{
title: '创建时间',
key: 'time',
type: 'text',
},
];
const onBatchExport = () =>{
const tableDatas = JSON.parse(JSON.stringify(tableData.value));
const datas = tableDatas;
table2excel(column, datas, '二维码');
}
</script>
<template>
<div>
<button @click="onBatchExport"> 点击导出 </button>
</div>
</template>
// 常见的计算 对象转换数组 :
let arr = Object.values(obj) //value
let arr=Object.keys(obj).map(function(i){return obj[i]}); // 根据key 找value
let keyArr = Object.keys(obj) //key
// 对象键值对反转
for (let k in datas) {
let value = datas[k];
datas[value] = k;
delete datas[k]; // 删除原来的属性
}
// const chars = text.split(''); 字符转成数组
// 必须掌握 字符串 数组 对象 的相互计算 !importent! js基础不再多说
//
标签:总结,const,入门,value,---,state,let,vue3,组件
From: https://www.cnblogs.com/cavans/p/17235945.html