首页
新闻资讯
产品中心
技术相关
VUE
Typecho
前端技术
留言
友链
统计
关于
Search
1
vue3+vite+ts使用@通过import导入ts文件和vue文件报错问题的解决
785 阅读
2
光伏发电工程设计概算软件
784 阅读
3
vue3安装配置eslint及遇到的坑
324 阅读
4
Typecho插件开发(一)
294 阅读
5
Vite初始化项目报错:Install for [ ‘create-vite-app@latest‘ ] failed with code 1
274 阅读
登录
/
注册
Search
标签搜索
vue
Typecho
Typecho插件开发
风电概算
光伏概算
经济评价
Typecho主题Joe
付费阅读
vue3
lnsoft
累计撰写
19
篇文章
累计收到
3
条评论
首页
栏目
新闻资讯
产品中心
技术相关
VUE
Typecho
前端技术
页面
留言
友链
统计
关于
2022-08-02
vue3-Mock-pinia-组件通信-导出excel
1、Mock方法post传参 2、响应式变量ref、reactive、toRef、 toRefs 3、状态管理工具pinia的使用 4、状态管理工具pinia的订阅 5、插槽slot及作用域 6、父传子通过provide、inject 7、父传子非props属性集合 useAttrs 8、父传子props 9、父传子事件defineEmits 10、父调用子的变量或方法defineExpose 11、事件总线mitt 12、导出excel文件 13、源码下载 vue3学习做的Demo 1、Mock方法post传参get方法之前文档已有记录,这里主要是post传过去的参数,如何在Mock方法中取得,看代码QueryParam是查询是参数对像,有属性OrderNum和Status。 // 调用 axios.post("/api/queryshops", QueryParam).then((res) => { DataObj.Shops = res.data.Shops; }); ...... // 在mock方法文件中 { url: '/api/queryshops', method: 'post', response: ({ body }) => { const OrderNum = body['OrderNum'] const Status = body['Status'] ...... return { Shops, } }, }2、响应式变量ref、reactive、toRef、 toRefs创建响应式变量reactive主要用于数组和对象,ref用于简单变量字符串、数字等;toRef响应式对象上的某个属性新创建一个ref。并保持对源属性的响应式连接。 toRefs将响应式对象的每个属性都创建一个ref。 特别注意ref类型的变量在模板中直接使用,在script中需要加.value访问let person = reactive({ name: '张三', age: 28, sex: '男', job: { name: 'UI开发', salary: '20K' } }) const name = toRef(person, 'name') const { sex, job } = toRefs(person) const TestClick = () => { name.value = '张三四' job.value.salary = '30k' job.value.name = '后端开发' }3、状态管理工具pinia的使用// cmd命令行模式下 安装包 npm install pinia // main.ts引入 import { createPinia } from 'pinia' ...... const pinia = createPinia() app.use(pinia) // 建文件src/store/index.ts import { defineStore } from 'pinia' /* state:数据仓库,用来存数据的。 getters:获取数据的。 actions: 同步异步都支持 */ export const mainstore = defineStore('mainstore', { state: () => { return { subTitle: '订单', author: '', name: '王二', age: 13, sex: '男', socre: [87, 98, 100, 100, 86], book: <Book>{} } }, // 取数据 getters: { // 普通函数可以用this getSubTitle(): string { return this.subTitle + '!' }, // 箭头函数 不能用this,直接用state getName: (state): string => { return state.name }, // 带参数,返回一个新函数 getAge(state) { return (num: number) => state.age + num }, getSex(state) { return state.sex }, getScoreSum(state) { return state.socre.reduce(function (prev, curr) { return prev + curr }) }, }, // 同步异步都可 actions: { changeSubTitle(data: string) { this.subTitle = data }, changeScore(data: number) { this.socre.push(data) }, changeAge(data: number) { this.age = this.age + data }, setAuthor(msg: string) { // 模拟ajax请求 setTimeout(() => { this.author = msg }, 1000) }, } }) // 页面中使用 import { mainstore } from '@/store/index' // pinia的使用 const store = mainstore() // 直接调用action store.changeSubTitle('订单查询') store.setAuthor('作者:Sun') // 和toRefs类似 得到的都是响应式的变量 const { getSubTitle } = storeToRefs(store)4、状态管理工具pinia的订阅修改state、调用action都会给你回调的机会import { mainstore } from '../store/index' const store = mainstore() store.$subscribe((mutation, state) => { /* * mutation主要包含三个属性值: * events:state改变的具体数据,包括改变前的值和改变后的值 * storeId:是当前store的id * type:用于记录这次数据变化是通过什么途径,主要有三个分别是 * “direct” :通过 action 变化的 ”patch object“ :通过 $patch 传递对象的方式改变的 “patch function” :通过 $patch 传递函数的方式改变的 * * */ console.log(mutation) console.log(state) }) store.$onAction( ({ name, //action 函数的名称 store, //store 实例,这里是 mainStore args, //action 函数参数数组 after, //钩子函数,在action函数执行完成返回或者resolves后执行 onError, // 钩子函数,在action函数报错或者rejects后执行 }) => { console.log('name===>', name) console.log('args===>', args) console.log('store===>', store) // result是action最后return的内容 after((result) => { console.log('after result===>', result) }) onError((error) => { console.log('onError error===>', error) }) }, false, // 默认是false,设置为true的时候,组件卸载时,订阅依然有效 )5、插槽slot及作用域<!--这是在子组件中 btn是插槽名称listquery是要传的参数 --> <slot name="btn" :listquery="listQuery"></slot> <!--这是在父组件中 btn是插槽名称,通过slots.listquery可以访问传过来的参数 --> <child> <template #btn="slots"> <el-form-item label=""> <el-button @click="exportExcel(slots.listquery)" icon="Check" type="primary">导出</el-button> </el-form-item> </template> </child>6、父传子通过provide、inject父传子,可跨代包括子的子的子......// 父组件中 他可以直达任意子组件 包括子的子 ... provide('subTitle', getSubTitle) // 子组件中 完成标题内容 // 接收父组件传过来的值 包括 父组件 父的父 ... const subTitle = ref(inject('subTitle') as string)7、父传子非props属性集合 useAttrs<!-- 父组件中 --> <child ref="datatable" @initlistquery="initquery" :options="options" title="Demo" sytle="width:100%" class="item" id="1:"></child> // 子组件中 // useAttrs: 非props属性集合 包含父作用的class、style id 等等 模板中可以直接用$attrs绑定 const attr = useAttrs() const title = ref(attr.title)8、父传子props// 在父组件中 <child ref="datatable" :options="options"></child> // 子组件中 取props 父组件传过来的 interface option { value: number, label: string } // 接收父组件传过来的值 defineProps({ options: { type: Array<option>, default: () => [] }, })9、父传子事件defineEmits子组件接收父传过来的事件,在子组件中调用。<!--父组件中--> <child ref="datatable" @initlistquery="initquery"></child> // 子组件中 // 接收父组件传过来的事件。方便子组件调用父组件定义的事件 const emits = defineEmits(['initlistquery']) // 生命周期的钩子函数。挂载完毕调用 onMounted(() => { emits('initlistquery', listQuery) QueryData(listQuery); });10、父调用子的变量或方法defineExpose在子组件中通过defineExpose暴露变量或方法以供父组件调用// 子组件中 // defineExpose直接使用 用它来暴露变量和方法 defineExpose({ Statusfilter, CalMoney, DataObj, QueryData }); <!--父组件中--> <child ref="datatable"></child> // 注意子组件上 ref='datatable' 取到子组件,调用他暴露出来的变量和方法 const datatable = ref() // 调用子组件暴露出来的变量和方法 子组件中defineExpose暴露 const modify = () => { var Shops = datatable.value.DataObj.Shops ...... }11、事件总线mitt// 安装 npm install mitt // src/utils/eventBus.ts import mitt from 'mitt' const emitter = mitt() export default emitter // 在vue页面中 import mitter from '@/utils/eventBus' const TestStore = () => { mitter.emit('nameChange', { name: 'sun', age: 26 }) } // 在vue另一页面中 mitter.on('nameChange', (data) => { console.log(data) }) onBeforeUnmount(() => { mitter.off('nameChange') })12、导出excel文件// cmd命令行安装这两个包 npm install xlsx npm install -S file-saver // vue文件中代码 const formatJson = ( filterVal: string[], jsonData: { ShopName: string; OrderNum: string; Status: string }[], ) => { return jsonData.map((v) => filterVal.map((j) => { if (j === 'OrderMoney') { return datatable.value.CalMoney(v) } else if (j === 'Status') { return datatable.value.Statusfilter(v[j]) } else { return v[j] } }), ) } // 导出excel const exportExcel = (param: { OrderNum: string }) => { if (param.OrderNum) { console.log(param.OrderNum) } import('../vendor/useExportExcel').then((excel) => { const table = datatable.value.DataObj.Shops const tHeader = ['商店名称', '订单编号', '金额', '状态'] //自定义列名 const filterVal = ['ShopName', 'OrderNum', 'OrderMoney', 'Status'] //对应自段 const data = formatJson(filterVal, table) console.log(data) excel.exportJsonToExcel({ multiHeader: [], merges: [], header: tHeader, data, filename: 'test', autoWidth: true, bookType: 'xlsx', }) }) }13、源码下载隐藏内容,请前往内页查看详情
2022年08月02日
122 阅读
0 评论
0 点赞
2022-08-01
vue3+vite+ts使用@通过import导入ts文件和vue文件报错问题的解决
import { mainstore } from '@/store/index' 导入ts文件报错:找不到模块“@/xxxxxx”或其相应的类型声明在tsconfig.json文件compilerOptions项下加配置 "baseUrl": "./" , "paths":{ "@/*": ["src/*"] },动态加载组件或者在vue文件中导入组件报错:Failed to resolve import"@/views/Home.vue” from "src\routerindex.ts". Does the file exist?在vite.config.ts文件中加配置 resolve: { alias: { '@/': new URL('./src/', import.meta.url).pathname } },
2022年08月01日
785 阅读
0 评论
0 点赞
2022-07-28
vue ts报错:绑定元素“body”隐式具有“any”类型及常用的Ts配置
1. MockMethod的方法post参数的取值,之后报错:绑定元素“body”隐式具有“any”类型。 { url: '/api/queryshops', method: 'post', response: ({ body }) => { const OrderNum = body['OrderNum'] ...... return { Shops } } },在tsconfig.json文件中 compilerOptions下增加一个配置"noImplicitAny": false2. 常用的ts配置如下:{ "compilerOptions": { "target": "es6", //用来指定ts被编译为js的版本 "module": "es6", //指定要使用模块化的规范 "moduleResolution": "node", "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "strict": true, //检查严格模式总开关 "strictNullChecks": false, //严格检查空值 "noImplicitAny": true, //不允许隐式的any类型 "noImplicitThis": false, //不允许明确类型的this "alwaysStrict": false, //编译后是否使用严格模式 "allowJs": false, //是否对js文件进行编译 默认是false "checkJs": false, //检查js代码是否符合语法规范 默认是false "declaration": true, "removeComments": false, //编译成js后是否移除注释 "noImplicitReturns": true, "noEmit": false, //不生成编译后的文件 "noEmitOnError": false, //有错误时不生成编译文件 "importHelpers": true, "lib": ["es6", "dom"], //指定项目中所用到的库 "typeRoots": ["node_modules/@types"], "outDir": "./js", //用来指定编译后文件所在路径 "rootDir": "./src", // "outFile": "./js/main.js" //将代码合并成一个文件,模块化规范需要为amd或者system }, "include": ["./src/**/*"], //被编译的文件目录 "exclude": ["node_modules", "dist", "**/*.test.ts"] //不希望被编译的文件 }
2022年07月28日
91 阅读
0 评论
0 点赞
2022-07-28
vue3安装配置eslint及遇到的坑
1. eslint的安装及配置向导2. 启用eslint后碰到的问题1、eslint的安装及配置向导进入项目目录在命令行执行 npm i eslint --save-dev 安装完成后,执行配置命令。按照向导依次选择你需要的配置。npm init @eslint/config2、启用eslint后碰到的问题vscode打开项目后报错Parsing error: '>' expected.在.eslintrc.json文件中增加如下配置 "parser": "vue-eslint-parser"。组件文件名称是Home.vue又报错Component name "Home" should always be multi-word.在.eslintrc.json文件中增加如下配置 "vue/multi-word-component-names":"off"
2022年07月28日
324 阅读
0 评论
1 点赞
2022-07-22
通过vite vue3 vue-router elementplus mock构建helloword项目 并部署到二级目录
1. 构建helloword项目2. 增加和展示路由3. 使用elementplus,按需引入4. 开发和生产环境中使用mock5. 打包部署至二级目录1. 构建helloword项目打开命令行工具,进入自已的开发目录执行npm init vite 依次输入项目名称 HelloWord 包名helloword 框架选择vue Select a variant:vue-ts也可以选择vue进入helloword目录:cd HelloWord执行安装命令npm install执行开发令npm run dev浏览器中已经可以打开了。2. 增加和展示路由添加路由npm install vue-router@4{callout color="#f0ad4e"}添加完路由后在src目录下创建router文件夹,在router文件夹内新建文件index.ts,下面是index.ts文件内容{/callout}// index.ts import { createRouter, createWebHistory } from "vue-router"; const routes = [ { path: '/', name: 'Home', component: () => import('@/views/Home.vue') } ] const router = createRouter({ history: createWebHistory(), routes }) export default router;{callout color="#f0ad4e"}新建views目录,在目录下新建Home.vue文件{/callout}<template> <div> <h1>HelloWord</h1> </div> </template> <script> export default { data(){ return{} } } </script>{callout color="#f0ad4e"}在vite.config.ts中配置别名{/callout}export default defineConfig({ plugins: [vue()], resolve: { alias: { '@/': new URL('./src/', import.meta.url).pathname } } }){callout color="#f0ad4e"}在App.vue文件中加入 <router-view/>展示路由{/callout}...... <template> <router-view/> ...... </template> ......{callout color="#f0ad4e"}在main.ts中添加路由{/callout}import { createApp } from 'vue' import './style.css' import App from './App.vue' import Router from './router/index.js' const app = createApp(App) app.use(Router).mount('#app')此时查看浏览器已经可以看到HelloWord3. 使用elementplus,按需引入前端最流行的UI elementplus已支持vue3,安装npm install element-plus --save同时再安装两个插件自动按需加载组件自动按需加载 API npm install unplugin-vue-components unplugin-auto-import -D导入样式插件,安装它前需要添加sass和sass-loader依赖npm install sass sass-loader unplugin-element-plus{callout color="#f0ad4e"}vite.config.js配置文件中添加配置{/callout}import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' import ElementPlus from 'unplugin-element-plus/vite' export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ElementPlus({ useSource: true }) ] ...... }){callout color="#f0ad4e"}修改Home.vue进行测试:{/callout}<template> <div> <h1>{Msg}</h1> <el-button @click="buttonclick" type="primary">ElementUI-Plus</el-button> </div> </template> <script> import {ElMessage} from 'element-plus' export default { data(){ return{ Msg: 'HelloWord' } }, methods: { buttonclick() { ElMessage({type: 'success',message:'HelloWord'}) } } } </script>运行效果安装图标插件npm install @element-plus/icons-vue{callout color="#f0ad4e"}在main.ts进行注册{/callout}import * as ElementPlusIconsVue from '@element-plus/icons-vue' for (let iconName in ElementPlusIconsVue) { app.component(iconName, ElementPlusIconsVue[iconName]) }{callout color="#f0ad4e"}修改Home.vue进行测试:{/callout}<el-button @click="buttonclick" icon="Check" type="primary">ElementUI-Plus</el-button>运行效果4. 开发和生产环境中使用mock在vite中使用mock模拟数据,需要借助vite-plugin-mock安装插件npm i mockjs -Dnpm i vite-plugin-mock -D安装路径解析插件 告诉 Rollup 如何查找外部模块 解决resolve is not defined的问题npm install @rollup/plugin-node-resolve --save-dev安装axios插件npm install axios --save{callout color="#f0ad4e"}在src/mock下新建index.ts{/callout}// mockProdServer.ts import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer' import testModule from './source/test' export function setupProdMockServer() { createProdMockServer([...testModule]) }{callout color="#f0ad4e"}在src/mock/source文件夹下新建test.ts{/callout}import { MockMethod } from 'vite-plugin-mock' export default [ { url: '/api/getUserInfo', // 注意,这里只能是string格式 method: 'get', response: () => { return 'hello world, I am mockdata' } },{ type:'get', url:'/user/menu', response: () => { return {menusList:[{ id:'/sysManagent', title:'系统管理', subMenuList:[ { id:'/userList', title:'用户管理', path:'/user/manage' }, { id:'/roleList', title:'角色管理', path:'/user/role' }, { id:'/permissionList', title:'权限管理', path:'/user/permission' } ] },{ id:'businessManagent', title:'业务管理', subMenuList:[ { id:'/businessList', title:'业务逻辑' } ] }],statusCode:200} } } ] as MockMethod[]{callout color="#f0ad4e"}vite.config.ts配置{/callout}import resolve from '@rollup/plugin-node-resolve' import { viteMockServe } from 'vite-plugin-mock' export default defineConfig({ plugins: [ ...... viteMockServe({ localEnabled: true, // 开发打包开关 prodEnabled: true, // 生产打包开关 supportTs: false, // 打开后,可以读取 ts 文件模块。 请注意,打开后将无法监视.js 文件。 watchFiles: true, // 监视文件更改 mockPath: "./src/mock/source", injectCode: ` import { setupProdMockServer } from './src/mock'; setupProdMockServer(); `, injectFile: resolve("src/main.ts") // 在main.ts注册后需要在此处注入,否则Could not resolve './src/mock' from src/main.ts错误 }) ] ...... }){callout color="#f0ad4e"}在main.ts里进行注册{/callout}import { setupProdMockServer } from '@/mock'; if (process.env.NODE_ENV === 'production') { setupProdMockServer(); }{callout color="#f0ad4e"}在Home.vue修改 测试{/callout}<template> <div> ...... <div>{{str.msg}}</div> ...... </div> </template> <script lang="ts" setup> import axios from 'axios'; import { onMounted, reactive } from 'vue' let str = reactive({}) onMounted(() => { axios.get("/api/getUserInfo").then(res => { console.log(res); str.msg = res.data; console.log(str) }); }) </script>运行效果5. 打包部署至二级目录{callout color="#f0ad4e"}打包部署至二级目录hfnm下。修改配置文件package.json{/callout} ...... "scripts": { ...... "build": "vite build --base=/hfnm/", ...... }, ......{callout color="#f0ad4e"}router目录index.ts 修改{/callout}const router = createRouter({ history: createWebHistory('hfnm'), routes })执行打包命令npm run build如图输出的文件夹是dist,把dist下的文件和目录全部放到你的网站根目录hfnm目录下运行效果源码下载隐藏内容,请前往内页查看详情
2022年07月22日
78 阅读
0 评论
0 点赞
1
2
...
4