# kankandx **Repository Path**: totodo/kankandx ## Basic Information - **Project Name**: kankandx - **Description**: dadaxue app - **Primary Language**: JavaScript - **License**: OSL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-24 - **Last Updated**: 2024-06-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # kankandx #### 介绍 侃侃大学里的那些专业 APP #### 软件架构 1. VUE3 vue-router https://vuejs.org 2. Vite 5.0 https://cn.vuejs.org/guide/scaling-up/tooling.html#vite 3. DesignSystem tdesign-vue-next https://tdesign.tencent.com/ 4. Css tailwindcsss https://tailwindcss.com/ #### 安装教程 全局安装 ``` npm i ``` 安装Tdesginer组件 ``` npm install tdesign-vue-next ``` 安装tailwindcss ``` npm install tailwindcss postcss autoprefixer ``` #### 使用说明 ``` npm run dev ``` #### 开发教程 ##### 1开发配置 ###### 1.1. 配置t-designe ```javascript //main.js import TDesign from 'tdesign-vue-next'; import 'tdesign-vue-next/es/style/index.css'; const app = createApp(App) app.use(TDesign) ``` ###### 1.2. 配制tailwindcss 配置文件 tailwind.config.js ```javascript //tailwind.config.js /** @type {import('tailwindcss').Config} */ export default { content: ["./src/**/*.{vue,html,js}"], theme: { extend: {}, }, plugins: [], } ``` 配置文件 postcss.config.js ```javascript //postcss.config.js plugins: { tailwindcss: {}, autoprefixer: {}, }, ``` 配置css文件 src/assets/index.csss ```css @tailwind base; @tailwind components; @tailwind utilities; ``` 引入tailwindcsss mian.js中 ```javascript import './assets/index.css' ``` ###### 1.3. 配置Vite ```javascript //vite.config.JS import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import tailwindcss from 'tailwindcss' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } } }) ``` ##### 2. Vue开发使用指南 ###### 2.1 使用Vue-rotuer ```javascript //router/index.js //引入组件 import Home from './components/Home.vue' import AddAdvice from './components/AddAdvice.vue' // 引入路由 import { createRouter, createWebHashHistory } from 'vue-router' // 定义一些路由 // 每个路由都需要映射到一个组件。 // 我们后面再讨论嵌套路由。 const routes = [ { path: '/', component: Home }, { path: '/addadvice', component: AddAdvice }, { path: '/feedback', component: FeedBack }, ] // 创建路由实例 const router = createRouter({ routes, history: createWebHashHistory() }) // 使用路由 const app = createApp(App) app.use(router) ``` ###### 2.2 VUE 模板中跳转 ```html Add Home ``` ###### 2.3 script 方法中调用 * 方式一 使用全局属性 $router ```javascript this.$router.push('/') //跳转到 Home.vue this.$router.push('/addadvice') //跳转到AddAdvice.vue ``` * 方式二 使用 Composition API 的 useRouter 钩子 ```javascript // main.js文件中 app.provide('router', router); ``` ```javascript //UserRegister.vue文件 中 import { inject } from 'vue';//引入 const router = inject('router'); router.push("/") ``` VUE模板中使用展示 ```html ``` ###### 2.2 使用TDesigner下拉选择组件 选用t-input-selector 组件 * 参考文档 https://tdesign.tencent.com/vue-next/components/select?tab=demo 定义formdata,selectInput,以及下拉中的事件 ```javascript data(){ selectSchool: '', //学校下拉选择输入内容,可根据这个值进行后台过滤 popupVisibleSchool: false, //弹出下拉选择列表的展示控制 formdata:{ school:'', //v-model 绑定formdata.school 传递给后台 }, schools:[] //学校选择器的数组 } ``` 定义t-input-select 中绑定的事件 ```javascript methods:{ //学校下拉 输入下来 onInputChangeSchool(val, content) { //console.log(val, content) this.getCategroySelect(val,'学校') }, onOptionClickSchool(o) { //console.log(school) this.selectSchool = o.tagname; // 选中后立即关闭浮层 this.popupVisibleSchool = false; //选中后赋予值 this.formData.school = o.tagname; }, onPopupVisibleChangeSchool(val,content){ this.popupVisibleSchool = val; } } ``` 使用t-input-select组件 ``` html ``` #### 3 Form表单验证 ##### 给form 添加 规则 引用参考 https://tdesign.tencent.com/vue-next/components/form#%E4%B8%8D%E5%90%8C%E6%A0%A1%E9%AA%8C%E8%A7%84%E5%88%99%E7%9A%84%E8%A1%A8%E5%8D%95 ```vue

{{ title }}

``` 在 javascript 中添加 rules 对象 ```javascript const rules = { username: [ { required: true, message: '用户名必填', type: 'error' }, { min: 3, message: '至少需要两3个字符', type: 'error', trigger: 'blur', }, { max: 32, message: '最长不能超过32个字符', type: 'error', trigger: 'blur', }, ], password: [ { required: true, message: '密码必填', type: 'error' }, ], repassword: [ { required: true, message: '密码必填', type: 'error' }, { validator: rePassword, message: '两次密码不一致' } // rePassword 设置为可自定义的校验方法 ] }; const rePassword = (val) => new Promise((resolve) => { const timer = setTimeout(() => { resolve(formData.password === val); clearTimeout(timer); }, 500); // 假设验证延时为0.5秒 }); ``` 注:使用 validator 自定义校验函数,支持异步返回结果 Promise,返回结果可以设置不同的校验结果、校验结果类型、校验结果信息。 示例一 : validator: (val) => { result: !!val, message: '该项必填', type: 'error' }。 示例二:validator: (val) => new Promise((resolve) => resolve({ result: false, message: '校验未通过', type: 'warning' }))。如果是异步校验,必须返回所有情况的校验结果,不能只返回 resolve(false) 校验不通过的情况,还需要注意返回 resolve(true) 校验通过的情况。 #### 4 VUE 部署环境配置 ##### 创建环境变量文件: 在项目根目录下,创建或编辑以下两个文件: .env:全局环境变量,对所有环境生效。 .env.local:本地环境变量,会覆盖 .env 中的相同变量。 .env.development:开发环境特定的环境变量。 .env.production:生产环境特定的环境变量。 ###### 在代码中使用环境变量: 在Vite项目中,你可以通过import.meta.env来访问这些环境变量。例如: ```javascript const baseUrl = import.meta.env.VITE_APP_API_BASE_URL; ``` #### 5 VUE第三方组件使用 ###### ChartJs做普通图表 (EcCharts ChartJS) vue-chartjs 是Chart.js 的扩展. 可以方便的创建使用图表的扩展组件 目前最新支持 Chart.js v4. ##### 安装 ```bash npm i vue-chartjs chart.js ``` ##### 创建图表 饼状图摸版 ``` vue ``` 脚本 ``` javascript import { Bar } from 'vue-chartjs' import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js' ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale) export default { name: 'BarChart', components: { Bar }, data() { return { chartData: { labels: ['January', 'February', 'March','April','May'], datasets: [ { label: '同比增长', backgroundColor: '#f87979', data: [40, 45, 50, 60, 55] }, { label: '环比增长', backgroundColor: '#7989f8', data: [25, 35, 40, 45, 50] } ] }, chartOptions: { responsive: true, maintainAspectRatio: false } } }, ``` ##### 更新图表。动态获取数据 更新图表的数据,不能直接修改选项式申明中的data,他是只读。 所以需要用相应方式去绑定, 在export default 中使用coumpute: 在组合式API方法中,可以对相应的对象,直接修改复制。 ``` javascript import { ref } from 'vue' import { Bar } from 'vue-chartjs' import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js' import { useIntervalFn } from '@vueuse/core' ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale) const chartData =ref({ labels: ['January', 'February', 'March', 'April', 'May'], datasets: [ { label: '同比增长', backgroundColor: '#f87979', data: [40, 45, 50, 60, 55] }, { label: '环比增长', backgroundColor: '#7989f8', data: [25, 35, 40, 45, 50] } ]} ) const chartOptions = ref({ responsive: true, maintainAspectRatio: false }) //更新图表数据 const updateData = () => { chartData.value = { labels: ['January', 'February', 'March', 'April', 'May'], datasets: [ { label: '同比增长', backgroundColor: '#f87979', data: [Math.random()*100, Math.random()*100, Math.random()*100, Math.random()*100, Math.random()*100] }, { label: '环比增长', backgroundColor: '#7989f8', data: [Math.random()*100, Math.random()*100, Math.random()*100, Math.random()*100, Math.random()*100] } ] } } //采用usecore 动态调用函数定时器 useIntervalFn() 实现动态更新 useIntervalFn(() => { updateData() }, 1000) ``` ##### ApexChartjs 实现股票实时走势图 ##### 安装 vue3-ApexChartjs ``` bash npm install --save apexcharts npm install --save vue3-apexcharts ``` candlestick 图表魔板 ``` vue ``` ``` javascript import { ref } from 'vue' import ApexCharts from 'vue3-apexcharts' import { useIntervalFn } from '@vueuse/core' const chartRef = ref(null) const ohlcData = [{ x: new Date(1538778600000), y: [6629.81, 6650.5, 6623.04, 6633.33] }, { x: new Date(1538780400000), y: [6632.01, 6643.59, 6620, 6630.11] }, { x: new Date(1538782200000), y: [6630.71, 6648.95, 6623.34, 6635.65] }, { x: new Date(1538784000000), y: [6635.65, 6651, 6629.67, 6638.24] }, { x: new Date(1538785800000), y: [6638.24, 6640, 6620, 6624.47] }, { x: new Date(1538787600000), y: [6624.53, 6636.03, 6621.68, 6624.31] }, { x: new Date(1538789400000), y: [6624.61, 6632.2, 6617, 6626.02] }, { x: new Date(1538791200000), y: [6627, 6627.62, 6584.22, 6603.02] }, { x: new Date(1538793000000), y: [6605, 6608.03, 6598.95, 6604.01] }, { x: new Date(1538794800000), y: [6604.5, 6614.4, 6602.26, 6608.02] }, { x: new Date(1538796600000), y: [6608.02, 6610.68, 6601.99, 6608.91] }, { x: new Date(1538798400000), y: [6608.91, 6618.99, 6608.01, 6612] }, { x: new Date(1538800200000), y: [6612, 6615.13, 6605.09, 6612] }, { x: new Date(1538802000000), y: [6612, 6624.12, 6608.43, 6622.95] }, { x: new Date(1538803800000), y: [6623.91, 6623.91, 6615, 6615.67] }, { x: new Date(1538805600000), y: [6618.69, 6618.74, 6610, 6610.4] }, { x: new Date(1538807400000), y: [6611, 6622.78, 6610.4, 6614.9] }, { x: new Date(1538809200000), y: [6614.9, 6626.2, 6613.33, 6623.45] }, { x: new Date(1538811000000), y: [6623.48, 6627, 6618.38, 6620.35] }, { x: new Date(1538812800000), y: [6619.43, 6620.35, 6610.05, 6615.53] }, { x: new Date(1538814600000), y: [6615.53, 6617.93, 6610, 6615.19] }, { x: new Date(1538816400000), y: [6615.19, 6621.6, 6608.2, 6620] }, { x: new Date(1538818200000), y: [6619.54, 6625.17, 6614.15, 6620] }, { x: new Date(1538820000000), y: [6620.33, 6634.15, 6617.24, 6624.61] }, { x: new Date(1538821800000), y: [6625.95, 6626, 6611.66, 6617.58] }, { x: new Date(1538823600000), y: [6619, 6625.97, 6595.27, 6598.86] }, { x: new Date(1538825400000), y: [6598.86, 6598.88, 6570, 6587.16] }, { x: new Date(1538827200000), y: [6588.86, 6600, 6580, 6593.4] }, { x: new Date(1538829000000), y: [6593.99, 6598.89, 6585, 6587.81] }, { x: new Date(1538830800000), y: [6587.81, 6592.73, 6567.14, 6578] }, { x: new Date(1538832600000), y: [6578.35, 6581.72, 6567.39, 6579] }, { x: new Date(1538834400000), y: [6579.38, 6580.92, 6566.77, 6575.96] }, { x: new Date(1538836200000), y: [6575.96, 6589, 6571.77, 6588.92] }, { x: new Date(1538838000000), y: [6588.92, 6594, 6577.55, 6589.22] }, { x: new Date(1538839800000), y: [6589.3, 6598.89, 6589.1, 6596.08] }, { x: new Date(1538841600000), y: [6597.5, 6600, 6588.39, 6596.25] }, { x: new Date(1538843400000), y: [6598.03, 6600, 6588.73, 6595.97] }, { x: new Date(1538845200000), y: [6595.97, 6602.01, 6588.17, 6602] }, { x: new Date(1538847000000), y: [6602, 6607, 6596.51, 6599.95] }, { x: new Date(1538848800000), y: [6600.63, 6601.21, 6590.39, 6591.02] }, { x: new Date(1538850600000), y: [6591.02, 6603.08, 6591, 6591] }, { x: new Date(1538852400000), y: [6591, 6601.32, 6585, 6592] }, { x: new Date(1538854200000), y: [6593.13, 6596.01, 6590, 6593.34] }, { x: new Date(1538856000000), y: [6593.34, 6604.76, 6582.63, 6593.86] }, { x: new Date(1538857800000), y: [6593.86, 6604.28, 6586.57, 6600.01] }, { x: new Date(1538859600000), y: [6601.81, 6603.21, 6592.78, 6596.25] }, { x: new Date(1538861400000), y: [6596.25, 6604.2, 6590, 6602.99] }, { x: new Date(1538863200000), y: [6602.99, 6606, 6584.99, 6587.81] }, { x: new Date(1538865000000), y: [6587.81, 6595, 6583.27, 6591.96] }, { x: new Date(1538866800000), y: [6591.97, 6596.07, 6585, 6588.39] }, { x: new Date(1538868600000), y: [6587.6, 6598.21, 6587.6, 6594.27] }, { x: new Date(1538870400000), y: [6596.44, 6601, 6590, 6596.55] }, { x: new Date(1538872200000), y: [6598.91, 6605, 6596.61, 6600.02] }, { x: new Date(1538874000000), y: [6600.55, 6605, 6589.14, 6593.01] }, { x: new Date(1538875800000), y: [6593.15, 6605, 6592, 6603.06] }, { x: new Date(1538877600000), y: [6603.07, 6604.5, 6599.09, 6603.89] }, { x: new Date(1538879400000), y: [6604.44, 6604.44, 6600, 6603.5] }, { x: new Date(1538881200000), y: [6603.5, 6603.99, 6597.5, 6603.86] }, { x: new Date(1538883000000), y: [6603.85, 6605, 6600, 6604.07] }, { x: new Date(1538884800000), y: [6604.98, 6606, 6604.07, 6606] }, ] const series = ref([ { data: ohlcData } ]) const chartOptions = ref({ chart: { type: 'candlestick', height: 350 }, title: { text: '铜价期货跟踪图标', align: 'center' }, xaxis: { type: 'datetime', range: 60480000, tooltip: { enabled: true, } }, yaxis: { tooltip: { enabled: true } } }) //推送新数据更新图表的方法 const updateData = (n) => { const newData = { x: new Date()+1800000, y: [6600+Math.random()*20, 6600+Math.random()*20,6600-Math.random()*20, 6600-Math.random()*20] } series.value[0].data.push(newData) console.log(series.value[0].data.length) series.value[0].data.shift(); } useIntervalFn(() => { updateData(1800000) }, 3000) ```