vue3+ts

  • 一、环境
  • 二、安装
  • 三、创建项目
    • 1、vue-cli创建项目
    • 2、图形化创建项目
    • 3、部分目录介绍
  • 四、安装sass
  • 五、ts集成和使用
    • 1、集成
    • 2、使用
  • 六、路由
    • 1、安装
    • 2、使用
  • 七、vuex
    • 1、安装
    • 2、引入注册
    • 3、mapState、mapGetters、mapMutations、mapActions
    • 4、使用
  • 八、vue.config.js配置
  • 九、vue3的一些写法
    • 1、mixin
    • 2、teleport
    • 3、composition-api
    • 4、生命周期函数
    • 5、props
    • 6、Provider Inject 父子传值
    • 7、Suspense 异步加载组件
  • 十、好用插件
    • 1、安装`style-resources-loader`自动化导入

vue3的优点
1、vue3采用渐进式开发,向下兼容
2、性能的提升:打包大小减少41%,初次渲染快55%,更新快133%,内存使用减少54%
3、Composition API集合,解决vue2组件开发问题
4、新得api加入:Teleprot瞬移组件,Suspense解决异步加载组件问题
5、更好TypeScript支持

一、环境

Vue CLI 3需要 nodeJs ≥ 8.9 (官方推荐 8.11.0+,你可以使用 nvm 或 nvm-windows在同一台电脑中管理多个 Node 版本)

1、下载安装node
下载地址:https://nodejs.org/en/
2、检查是否安装成功

二、安装

1、全局安装过旧版本的 vue-cli(1.x 或 2.x)要先卸载它,否则跳过此步:

npm uninstall vue-cli -g //或者 yarn global remove vue-cli

2、安装@vue/cli(Vue CLI 3的包名称由 vue-cli 改成了 @vue/cli)

1 cnpm install -g @vue/cli //yarn global add @vue/cli

3、vue -V 检查vue版本号

三、创建项目

1、vue-cli创建项目

1、安装vue-cli

npm install -g @vue/cli
或者
yarn global add @vue/cli查看版本
vue --version

2、npm创建项目

vue create 项目名如:
//我这里设置了以下淘宝源
vue create vue-next-libs --registry=https://registry.npm.taobao.org

选择最后一个

勾选如下
选择3.x

下面的选择根据自己的需求来

2、图形化创建项目

vue ui

会默认开启一个服务

3、部分目录介绍

  • shims-vue.d.ts 类文件/定义文件,让ts认识vue
  • .browserslistrc 在不同工具间共有浏览器和node版本进行配置兼容
  • .eslintrc.js .eslintrc配置文件
  • .gitignore 不需要上传到库的文件的配置文件
  • tsconfig.json ts的配置文件

四、安装sass

删除之前安装失败的包(第一次安装请跳过此步)

npm uninstall node-sass

安装

npm install -D sass-loader node-sass

安装style-resources-loader样式自动引入(公用样式里面的变量不用没页引入,就可以直接用了)

vue add style-resources-loader

在vue.config.js中使用

const path = require('path');
module.exports = {pluginOptions: {'style-resources-loader': {preProcessor: 'less',patterns: [// 这个是加上自己的路径,不能使用(如下:alias)中配置的别名路径path.resolve(__dirname, './src/style/params.less')]}},......
}

五、ts集成和使用

1、集成

进入到项目,执行下面的命令

vue add typescript

这里选择n,生成的组件就会和文档给的一样;y则组件是class类型

上面的程序运行完,typescript也就集成好啦!

2、使用

<template><div class="red">{{ name }}<home /></div>
</template><script lang="ts">
import { defineComponent, reactive, toRefs } from "vue";
import home from "./components/home.vue";
// data数据的接口
interface User {name: string;age: number;get(): string;
}export default defineComponent({name: "App",components: {home,},setup() {// ref只能用第二种写法// 实现接口的第一种方法 属性可增不可减// let data: User = reactive({//   name: "张三",//   age: 12,//   get() {//     return this.name;//   },// set(){}// });// 实现接口的第二种方法 属性不可增减// let data = reactive<User>({//   name: "张三",//   age: 12,//   get() {//     return this.name;//   },// });// 实现接口的第三种方法  属性可增不可减let data = reactive({name: "张三",age: 12,get() {return this.name;},set() {},}) as User;return {...toRefs(data),};},
});
</script><style lang="scss">
</style>

六、路由

1、安装

npm install vue-router@next --save

2、使用

在src目录下面建一个路由文件routes.ts

import { createRouter, createWebHistory } from 'vue-router'
// 引入组件
import Home from "./components/home.vue"
import Location from "./components/location.vue"const routes = [{path: '', redirect: '/home' //路由重定向
}, {//alias路由别名,user访问的也是home页面,也可以配置多个 // 如:alias:["/c","/n"]path: '/home', alias: "/user", component: Home
}, {path: '/location', component: Location
}]
// 配置路由
const router = createRouter({// history: createWebHashHistory(),//哈希模式history: createWebHistory(),//h5 History 模式   这种方式上线需要服务器配置伪静态routes
})
// 暴露路由实例对象
export default router

在main.ts中挂载路由

import { createApp } from 'vue'
import App from './App.vue'
import routes from "./routes"
const app = createApp(App)
// 挂载路由
app.use(routes)
app.mount('#app')

在App.vue中通过router-view渲染组件

<template>
哎呀<router-link to="/">首页</router-link><router-link to="/location">本地</router-link><router-view></router-view>
</template><script lang="ts">
import { defineComponent } from "vue";export default defineComponent({name: "App",setup() {},
});
</script><style lang="scss">
</style>

七、vuex

更多详情请查看https://vuex.vuejs.org/zh/installation.html

1、安装

npm install vuex@next --save

2、引入注册

store.ts

import { createStore } from 'vuex'
const store = createStore({state: { num: 0 }...
})
export default store

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import routes from "./routes"
import store from "./store"
const app = createApp(App)
// 挂载路由
app.use(routes)
app.use(store)
app.mount('#app')

3、mapState、mapGetters、mapMutations、mapActions

先引入

import { mapState,mapGetters,mapMutations,mapActions} from 'vuex'
  • mapState
nickname(){return this.$store.state.nickname}
age(){return this.$store.state.age}
gender(){return this.$store.state.gender}//一句代替上面三句computed: mapState(['nickname','age','gender'])//映射哪些字段就填入哪些字段

当还有自定义计算属性时

computed: {   //computed是不能传参数的value(){return this.val/7
},...mapState(['nickname','age','gender'])
}
  • mapGetters
computed: {  //computed是不能传参数的valued(){return this.value/7},...mapGetters(['realname','money_us'])
}
  • mapMutations
methods:{...mapMutations(['addAge'])//就相当于addAge(payLoad){this.$store.commit('addAge',payLoad)
}
}
  • mapActions
methods:{ ...mapActions([‘getUserInfo’])}

总结一下:

① 依赖state得到新的数据,用getters(跟computed一样,只读)

② 修改state的属性值,就用mutations(同步操作)

③异步就用actions

4、使用

store.ts

import { createStore, Store } from 'vuex'
import { ComponentCustomProperties } from 'vue';
declare module '@vue/runtime-core' {interface State {num: number,str: string,arr: string[]}interface ComponentCustomProperties {$store: Store<State>}
}const store = createStore({state() {return {num: 12,str: 'tom',arr: [1, 2, 4],}},mutations: {numMutation(state: any, data: number) {state.num = data;},strMutation(state: any, data: string) {state.str = data;},arrMutation(state: any, data: string[]) {state.arr = data;},},actions: {numAction({ commit }, args) {commit('numMutation', args)}},modules: {}
})
export default store

home.vue

<template><div class="home">我是子组件home</div>-------------{{ num }}<button @click="numAction(10)">change</button>
</template><script  lang="ts" >
import { toRef, toRefs, defineComponent } from "vue";
import { useStore } from "vuex";
export default defineComponent({name: "home",setup() {const store: any = useStore();//mapStateconst { str, arr, obj } = toRefs(store.state);const num = toRef(store.state, "num");//mapGettersconst { getNum } = toRefs(store.getters);//mapMutationsconst {strMutation: [strMutation],} = store._mutations;//mapActionsconst {numAction: [numAction],} = store._actions;return {str,num,arr,obj,getNum,strMutation,numAction,};},methods: {},
});
</script><style scoped>
</style>

八、vue.config.js配置

vue-cli升级到3之后,减少了很多的配置文件,将所有的配置项都浓缩到了vue.config.js这个文件中。

在根目录 新建一个 vue.config.js 同名文件

① 基本路径

baseUrl从 Vue CLI 3.3 起已弃用使用publicPath来替代。

在开发环境下,如果想把开发服务器架设在根路径,可以使用一个条件式的值

module.exports = {publicPath: process.env.NODE_ENV === 'production' ? '/production-sub-path/' : '/'
}

② 构建输出目录(打包位置)outputDir

module.exports = {outputDir: 'dist',
}

③ 静态资源目录 assetsDir
放置生成的静态资源 (js、css、img、fonts) 的目录

module.exports = {assetsDir: 'assets',
}

④ eslint代码检测 有效值:ture | false | ‘error’

设置为 true 时, eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败

希望让 lint 错误在开发时直接显示在浏览器中,可以使用 lintOnSave: ‘error’ 。这会强制 eslint-loader 将 lint 错误输出为编译错误

module.exports = {lintOnSave:false,//这里禁止使用eslint-loader}

⑤ webpack-dev-server 相关配置

devServer: {open: true,//设置自动打开port: 1880,//设置端口proxy: {//设置代理'/axios': {target: 'http://101.15.22.98',changeOrigin: true,secure: false, //如果是http接口,需要配置该参数pathRewrite: {'^/axios': ''}}}}}
module.exports = {// 部署应用时的基本 URLpublicPath: process.env.NODE_ENV === 'production' ? '192.168.60.110:8080' : '192.168.60.110:8080',// build时构建文件的目录 构建时传入 --no-clean 可关闭该行为outputDir: 'dist',// build时放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录assetsDir: '',// 指定生成的 index.html 的输出路径 (相对于 outputDir)。也可以是一个绝对路径。indexPath: 'index.html',// 默认在生成的静态资源文件名中包含hash以控制缓存filenameHashing: true,// 构建多页面应用,页面的配置pages: {index: {// page 的入口entry: 'src/index/main.js',// 模板来源template: 'public/index.html',// 在 dist/index.html 的输出filename: 'index.html',// 当使用 title 选项时,// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>title: 'Index Page',// 在这个页面中包含的块,默认情况下会包含// 提取出来的通用 chunk 和 vendor chunk。chunks: ['chunk-vendors', 'chunk-common', 'index']},// 当使用只有入口的字符串格式时,// 模板会被推导为 `public/subpage.html`// 并且如果找不到的话,就回退到 `public/index.html`。// 输出文件名会被推导为 `subpage.html`。subpage: 'src/subpage/main.js'},// 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码 (在生产构建时禁用 eslint-loader)lintOnSave: process.env.NODE_ENV !== 'production',// 是否使用包含运行时编译器的 Vue 构建版本runtimeCompiler: false,// Babel 显式转译列表transpileDependencies: [],// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建productionSourceMap: true,// 设置生成的 HTML 中 <link rel="stylesheet"> 和 <script> 标签的 crossorigin 属性(注:仅影响构建时注入的标签)crossorigin: '',// 在生成的 HTML 中的 <link rel="stylesheet"> 和 <script> 标签上启用 Subresource Integrity (SRI)integrity: false,// 如果这个值是一个对象,则会通过 webpack-merge 合并到最终的配置中// 如果你需要基于环境有条件地配置行为,或者想要直接修改配置,那就换成一个函数 (该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。在函数内,你可以直接修改配置,或者返回一个将会被合并的对象configureWebpack: {},// 对内部的 webpack 配置(比如修改、增加Loader选项)(链式操作)chainWebpack: () =>{},// css的处理css: {// 当为true时,css文件名可省略 module 默认为 falsemodules: true,// 是否将组件中的 CSS 提取至一个独立的 CSS 文件中,当作为一个库构建时,你也可以将其设置为 false 免得用户自己导入 CSS// 默认生产环境下是 true,开发环境下是 falseextract: false,// 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能sourceMap: false,//向 CSS 相关的 loader 传递选项(支持 css-loader postcss-loader sass-loader less-loader stylus-loader)loaderOptions: {css: {},less: {}}},// 所有 webpack-dev-server 的选项都支持devServer: {},// 是否为 Babel 或 TypeScript 使用 thread-loaderparallel: require('os').cpus().length > 1,// 向 PWA 插件传递选项pwa: {},// 可以用来传递任何第三方插件选项pluginOptions: {}
}

目前小颖公司用的 vue.config.js配置内容如下:

module.exports = {devServer: {proxy: {'/api': {target: 'http://xxxx',ws: true,changeOrigin: true,pathRewrite: {'^/api': ''}}}}
}

九、vue3的一些写法

1、mixin

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

// 定义一个混入对象
var myMixin = {created: function () {this.hello();},methods: {hello: function () {console.log("hello from mixin!");},},
};
export default {name: "HelloWorld",mixins: [myMixin],data() {return {};},
};//最后会打印  hello from mixin!

2、teleport

Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术。

to="xxx" 可以是标签,也可以是id,即将teleport内的内容放到"xxx"的DOM里面。简单理解,在组件里面写入teleport ,to=“body”,那么teleport 内容就变成body的子节点了

<template><teleport to="body" class="modal" v-if="show"><div class="modal-mask" >关闭</div><slot></slot></teleport>
</template><script>
import "./style.scss";
export default {props: {show: Boolean,},
};
</script>

3、composition-api

Composition API字面意思是组合API,它是为了实现基于函数的逻辑复用机制而产生的。

提供了以下函数:

  • setup
    composition-api所有代码都写在里面
  • ref
    定义响应式数据,即数据试图可以双向绑定,主要应用于:字符串、布尔值、数字、数组。
  • reactive
    定义响应式数据,主要应用于:对象。
  • toRefs
    解构响应式对象数据。
<template><div class="hello"><h1>{{ msg.text }}</h1><button @click="getMsg">获取msg</button><h1>{{ title }}</h1><button @click="getTitle">获取title</button><h1>{{ name }}</h1></div>
</template><script  >
import { reactive, ref, toRefs } from "vue";
export default {name: "HelloWorld",setup() {// 使用需要先引入var title = ref("我是一个标签");var msg = reactive({text: "张三",});var user = reactive({name: "张张",});// 获取reactive定义的数据var getMsg = () => {console.log(msg.text); //张三msg.text = "里斯";console.log(msg.text); //里斯};// 获取ref定义的数据var getTitle = () => {console.log(title.value); //我是一个标签title.value = "改变了";console.log(title.value); //改变了};return {title,msg,getMsg,getTitle,// ...user,   这样写,数据就不能双向绑定了...toRefs(user), //toRefs结构,数据就可以进行双向绑定};},
};
</script><style scoped>
</style>
  • watchEffect
    在相应式的跟踪其依赖项时立即运行一个函数,并在更改以后重新运行,不管是否改变都会执行一次
<template><div class="hello"><h1>{{ name }}</h1></div>
</template><script  >
import { reactive, toRefs, watchEffect } from "vue";
export default {name: "HelloWorld",setup() {// 非响应式数据let data = reactive({num: 12,});// 改变num就会执行一次,另外不管num改不改变都会执行一次watchEffect(() => {console.log(data.num);});setInterval(() => {data.num++;}, 1000);return {...toRefs(data),};},
};
</script><style scoped>
</style>
  • watch
    对比watchEffect,watch 允许我们:
    - 懒执行,也就是说仅在侦听的源变更时才执行回调
    - 更明确哪些状态的改变会触发侦听器重新运行
    - 访问侦听状态变化前后的值
<template><div class="hello"><h1>{{ name }}</h1></div>
</template><script  >
import { reactive, toRefs, watch, ref } from "vue";
export default {name: "HelloWorld",setup() {// 非响应式数据let data = reactive({num: 12,});let age = ref(1);watch(age, (v, old) => {console.log(v, old);});watch(() => data.num,(v, old) => {console.log(v, old);});//监听多个值watch([age,data.num], (v, old) => {console.log(v, old);//v, old都是数组});setInterval(() => {data.num++;age.value++;}, 1000);return {...toRefs(data),age,};},
};
</script><style scoped>
</style>
  • computed
<template><div class="hello"><h1>{{ title }}</h1><p>{{ newTitle }}</p></div>
</template><script  >
import { ref, computed } from "vue";
export default {name: "HelloWorld",setup() {// 使用需要先引入let title = ref("我是一个标签");let newTitle = computed(() => {return "哈哈哈," + title.value;});return {title,newTitle,};},
};
</script><style scoped>
</style>
  • readonly "深层"的只读代理
    传入一个对象(可双向绑定或普通)或ref,返回一个原始对象的只读代理,不可双向绑定。
<template><div class="hello"><h1>{{ name }}</h1><input type="text" v-model="name" /></div>
</template><script  >
import { reactive, readonly, toRefs } from "vue";
export default {name: "HelloWorld",setup() {// 非响应式数据let obj = reactive({name: "张三",age: 12,});// readonly 将响应式数据改成只读数据obj = readonly(obj);return {...toRefs(obj),};},
};
</script><style scoped>
</style>
  • 生命周期的hooks

4、生命周期函数

因为 setup是围绕 beforeCreatecreated 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。

  • onBeforeMount —挂载前
  • onMounted —挂载后
  • onBeforeUpdate —组件更新之前
  • onUpdated —组件更新之后
  • onBeforeUnmount —组件卸载之前
  • onUnmounted —组件卸载之后
  • onActivated —keep-alive包裹的组件激活时
  • onDeactivated —keep-alive包裹的组件停止使用时
  • onErrorCaptured —当捕获一个来自子孙组件的异常时
  • onRenderTracked —状态跟踪,它会跟踪页面上所有响应式变量和方法的状态,也就是我们用return返回去的值,它都会跟踪。只要页面有update的情况,它就会跟踪,然后生成一个event对象,我们通过event对象来查找程序的问题所在
  • onRenderTriggered —状态触发,它不会跟踪每一个值,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来
<template><div class="hello"></div>
</template><script  >
import { reactive, toRefs, ref, onMounted } from "vue";
export default {name: "HelloWorld",setup() {// 非响应式数据let data = reactive({num: 12,});let age = ref(1);onMounted(() => {console.log("onMounted");});return {...toRefs(data),age,};},
};
</script><style scoped>
</style>

5、props

父组件传参和vue2是一样的,只是子组件有点不一样,下面是子组件

<template><div class="hello"></div>
</template><script  >
export default {name: "HelloWorld",props: ["msg"],setup(props) {console.log(props);return {};},
};
</script><style scoped>
</style>

6、Provider Inject 父子传值

对父组件可以作为多有子组件的依赖提供程序,而不管组件层次结构有多深,这个特性有两部分:父组件有一个provider选项来提供数据,子组件有一个inject选项来开始使用数据。

  • 非组合式api中的写法
    父组件
<template><div class="red"><home /></div>
</template><script >
import home from "./components/home.vue";
export default {name: "App",components: {home,},// 写法一provide: {title: "父组件的标题",},// 写法二provide() {return {title: "父组件的标题",that: this,};},data() {return {data: "data数据",};},
};
</script><style  >
</style>

子孙组件

<template><div class="location">我是孙组件<br>拿到home组件的title:{{ title }}<pre>{{that}}</pre></div>
</template><script  >
export default {name: "location",inject: ["title","that"],setup() {return {};},
};
</script><style scoped>
</style>
  • 组合式api中的写法

父子组件的数据都是可以双向绑定的,即:子组件可以直接改变父组件的变量,父组件改变变量时,子组件也会同时改变
Provider
在setup()中使用provider时,我们首先从vue显示导入provider方法。这使我们能够调用provider时来定义每一个property。
provider函数允许通过两个参数定义:
1、name(string类型)
2、value
Inject

父组件

<template><div class="red"><button @click="setTitle">改变</button><input type="text" v-model="title" /><br /><br /><home /></div>
</template><script >
import home from "./components/home.vue";
import { ref, provide } from "vue";
export default {name: "App",components: {home,},setup() {let title = ref("父组件的标题");let setTitle = () => {title.value = "改变标题";};provide("title", title);return {setTitle,title,};},
};
</script><style  >
</style>

子孙组件

<template><div class="location">我是孙组件<br>拿到home组件的title:{{ title }}<input type="text" v-model="title"></div>
</template><script  >
import { inject} from "vue";
export default {name: "location",setup() {let title =inject('title')return {title,};},
};
</script><style scoped>
</style>

7、Suspense 异步加载组件

Async组件

export default defineComponent({async setup() {const result = ref("");await setTimeout(() => {result.value = "HI~Async";}, 3000);return {result};}
});

使用

<template><div id="app"><Suspense><template #default> //插槽包裹异步组件<Async></Async></template><template #fallback>//插槽包裹渲染异步组件之前的内容<h1>Loading...</h1></template></Suspense></div>
</template>

十、好用插件

1、安装style-resources-loader自动化导入

1、安装

vue add style-resources-loader

如果已经有配置文件了就选n,以防更改你有的文件


2、配置
vue.config.js文件配置

const path = require('path');
module.exports = {pluginOptions: {'style-resources-loader': {preProcessor: 'less',patterns: [// 这个是加上自己的路径,不能使用(如下:alias)中配置的别名路径path.resolve(__dirname, './src/style/params.less')]}},......其他配置
}

或者(variable变量文件,如此配置就不用每个需要用到变量的页面都引入variable,可以直接使用啦)

module.exports = {pluginOptions: {'style-resources-loader': {preProcessor: 'scss',patterns: ['./src/assets/styles/variable.scss']}}
}

搭建vue3项目+ts相关推荐

  1. 搭建vue3项目时出现Cannot read property ‘nextSibling‘ of null报错

    记录自己学习中,出现的错误 在搭建vue3项目,配置router,vuex,element-ui后,运行项目页面白屏,控制台出现了Cannot read property 'nextSibling' ...

  2. vue = 什么意思_记录使用@vue/cli搭建Vue3项目完整流程

    最近发现vue两大UI框架Element UI和Ant Design Vue都已经支持Vue3了,如果再不学习Vue3就落伍了,此文章记录下使用@vue/cli搭建Vue3项目完整流程. 1 安装vu ...

  3. cli vue 卸载_记录使用@vue/cli搭建Vue3项目完整流程

    最近发现vue两大UI框架Element UI和Ant Design Vue都已经支持Vue3了,如果再不学习Vue3就落伍了,此文章记录下使用@vue/cli搭建Vue3项目完整流程. 1 安装vu ...

  4. 【Vue3】搭建vue3项目以及环境

    前言 本来是打算结合vue3和spring boot出一期登录项目实战的,但是由于vue3没有我想象的简单,最后阉割了下,后面我们通过uniapp小程序出一期 一.安装环境创建vue3项目 确保你安装 ...

  5. vue3项目ts文件引入LodopFuncs.js打印控件

    //==本JS是加载Lodop插件或Web打印服务CLodop/Lodop7的综合示例,可直接使用,建议理解后融入自己程序==var CreatedOKLodopObject, CLodopIsLoc ...

  6. 使用vite搭建Vue3项目

    全局安装create-vite-app # yarn yarn global add create-vite-app@1.18.0 # npm npm i -g create-vite-app@1.1 ...

  7. vue3.0+ts+element-plus多页签应用模板:项目搭建

    目录 系列文章 一.安装vue-cli@4.5.x 二.创建项目 三.项目配置 四.IDE配置 五.vue.config.js配置 六.重置浏览器默认样式 系列文章 vue3.0+ts+element ...

  8. 【Parcel 2 + Vue 3】从0到1搭建一款极快,零配置的Vue3项目构建工具

    前言 一周时间,没见了,大家有没有想我啊!哈哈!我知道肯定会有的.言归正传,我们切入正题.上一篇文章中我主要介绍了使用Vite2+Vue3+Ts如何更快的入手项目.那么,今天我将会带领大家认识一个新的 ...

  9. vue3.0+ts+element-plus多页签应用模板:element-plus按需引入与动态换肤

    目录 系列链接 一.安装element-plus 二.按需引入 1. 为什么要按需引入? 2. 如何按需引入? 3. 验证是否引入成功 三.动态换肤 1. 制作自定义主题 2. 引入自定义主题 3. ...

最新文章

  1. 【调试基础】Part 3 Window操作系统
  2. 产品经理经验谈50篇(四):数据分析常用方法及应用案例解析
  3. LeetCode 784. 字母大小写全排列(位运算回溯)
  4. nginx中的location指令
  5. Graphene-SGX 总结
  6. RDP VS VNC 速度测试
  7. setSingleChoiceItems和setPositiveButton两者触发时期
  8. 格式化移动硬盘或者U盘,并设置为NTFS格式
  9. 读书笔记 - javascript设计模式和开发实践
  10. python爬取墨迹天气的8月份的温度情况并发送到邮箱
  11. 前端更新需要清空浏览器缓存_js清除浏览器缓存的几种方法
  12. C语言绕过杀毒软件,易语言插件规避杀毒软件方法
  13. 用username.github.io在github创建一个个人空间
  14. 如何下载河北区卫星地图高清版大图
  15. uva 12627 Erratic Expansion
  16. vue项目中,关于echarts报错:To install them, you can run: npm install --save echarts/lib/chart/bar…………
  17. nslookup命令使用技巧(一)
  18. python 连通域面积_python 三维连通域分析
  19. 皇后大道东 皇后大道西
  20. 今日学习——卷积神经网络(CNN)

热门文章

  1. 普元 AppServer 6.5 支持哪些日志级别?
  2. matlab散点图加图例,将图例添加到图 - MATLAB Simulink - MathWorks 中国
  3. 两个PDF比较标出差异_如何快速比较两个PPT文档的差异,早学早知道!
  4. DiDi Food中的智能补贴实战漫谈
  5. android mediaplayer 实现歌曲边播放边下载
  6. java论坛私信_巡云轻论坛系统 - JAVA轻论坛
  7. Linux书签(05)用linux more命令查看日志文件
  8. 七夕情人节该送女朋友什么礼物,推荐五款让女朋友超惊喜的礼物
  9. 如何识别骗子广告联盟,骗子广告联盟常用手段
  10. Java判断手机号格式