vue3.0正式版-语法
一.vue3.0版本中elementui-plus的安装和使用
1.安装:
npm i element-plus
扩展:
vue3.0和antdesign一起使用,ant-design-vue需要v2的版本,否则当行这样的样式就会出现问题。
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
const app = createApp(App);
app
.use(Antd)
.mount("#app");
2.main.js里面
import App from './App.vue'
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
const app = createApp(App)
app.use(ElementPlus).mount('#app')
3.页面的使用
在新版的vue3.x版本中还保留了原有的生命周期函数
created(){
this.$message("message")
},
4.但在vue3.0 setup中使用
import { setup } from 'vue-class-component'
import { getCurrentInstance } from 'vue'
export default {
name: 'App',
components: {
},
setup(e){
const {ctx} = getCurrentInstance()
ctx.$message("mesage")
}
}
更新:ctx 打包之后无法调用$message,可以使用proxy
import { getCurrentInstance } from 'vue'
export default {
name: 'App',
components: {
},
setup(){
const {proxy} = getCurrentInstance()
proxy.$message("mesage")
}
}
二.中英文切换
网址:https://vue-i18n-next.intlify.dev/
下面网上有这个网址,但不支持vue3.0
http://kazupon.github.io/vue-i18n/zh/introduction.html
三.vue.config.js
const path = require("path");
// vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '' : './',
// 构建项目生成的目录
outputDir: process.env.NODE_ENV === 'production' ? 'dist' : 'devDist',
// 关闭语法的自动检测
lintOnSave: false,
chainWebpack: config => {
config.module.rules.delete('svg'); //重点:删除默认配置中处理svg,
config.module
.rule('svg-sprite-loader')
.test(/\.svg$/)
.include.add(path.resolve('src/assets/svg')) //处理svg目录
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
});
},
css: {
loaderOptions: {
scss: {
prependData: `@import "./src/styles/main.scss";`
}
}
},
devServer: {
open: false, // 运行项目后是否自动打开
host: "0.0.0.0", // 可以让外部访问
port: 8000,
proxy: {
[process.env.VUE_APP_FLAG]: {
target: process.env.VUE_APP_APIURL,
ws: false, // webstock
changeOrigin: true, // 是否开启跨域
pathRewrite: {
[`^${process.env.VUE_APP_FLAG}`]: '' // 查找开头为/api的字符替换成“空字符串” /api/getCode
}
}
}
}
}
四.侧边栏引入svg
1,安装svg-sprite-loader
npm install svg-sprite-loader -D
2.vue.config.js里面添加chainWebpack的配置
vue.config.js具体哪些配置可以直接百度搜索vue(vue -> 开发-> webpck相关)
chainWebpack: config => {
config.module.rules.delete('svg'); //重点:删除默认配置中处理svg,
config.module
.rule('svg-sprite-loader')
.test(/\.svg$/)
.include.add(path.resolve('src/assets/svg')) //处理svg目录
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
});
},
3)单独的svg组件,引入以后,传入svg文件按的名字即可显示
<template>
<svg class="svg-class" :class="className">
<use :href="'#icon-' + iconName"></use>
</svg>
</template>
<script>
export default {
name: "SvgIcon",
props: {
iconName: {
type: String,
default: ""
},
className: {
type: String,
default: ""
}
}
}
</script>
4)svg从局部组件改为全局组件
main.js:
import { createApp } from "vue";
import App from "./App.vue";
// svg全局组件
import SvgIcon from "@/components/Svgicon";
// svg文件解析
import "./js/svg";
const app = createApp(App);
app
.component("svg-icon", SvgIcon)
.mount("#app");
5)组件内直接使用:
<svg-icon iconName="collapsed" class="collapsed-svg" />
五.vue3.0的router的使用
官方文档:百度搜索vue-router-next,如果每日有官方文档,找github也可以,官网在右边about里面的next.router.vue.js.org/。
1)获取路由
<template v-for="item in rotuers"></template>
import { useRoute, useRouter } from "vue-router";
setup(){
const { options } = useRouter();
// 路由
const rotuers = options.routes;
return {
data,
rotuers,
selectMenu,
openMenu,
hasOnlyChildren
}
}
六.子级传值给父级
import {getCurrentInstance } from "vue";
setup(props){
const { ctx } = getCurrentInstance();
ctx.$axios.post("getSms")
更新:ctx 打包之后无法调用$message,可以使用proxy
import { getCurrentInstance } from 'vue'
export default {
name: 'App',
components: {
},
setup(){
const {proxy} = getCurrentInstance()
proxy.$message("mesage")
}
}
1)父组件传值给子组件(使用vue-property-decorator装饰器 @Prop)
2)子组件传值给父组件(使用vue-property-decorator装饰器 @Emit)
注:@Emit其他写法
3)侦听器watch(使用vue-property-decorator装饰器 @Watch)
注:handler,immediate和deep
- 如下写的函数其实就是在写这个handler方法里面的;
watch: {
firstName (val) {
this.fullName = val + ' ' + this.lastName
}
}
- 当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性为true。
- 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
七.vue 中使用 TS 的 class-style代码风格
1.前言:vue-property-decorator 与 vue-class-component 的关系
vue class component 是vue 官方出的,vue property decorator 是社区出的
- vue class component 提供了 vue component 等等
- vue property decorator 深度依赖了 vue class component 拓展出了很多操作符 @Prop @Emit @Inject 等等 可以说是 vue class component 的一个超集
正常开发的时候 你只需要使用 vue property decorator 中提供的操作符即可 不用再从vue class componen 引入vue component
2. 如何使用导入npm 包
npm i -S vue-property-decorator
3.主要有以下一些装饰器和一个方法
@Prop
@PropSync
@Model
@ModelSync
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
@VModel
@Component (provided by vue-class-component)
Mixins (the helper function named mixins provided by vue-class-component)
@Component
注: 该属性完全继承于vue-class-component
属性参数:@Component(options: ComponentOptions = {})
参数说明:@Component 装饰器可以接收一个对象作为参数,可以在对象中声明 components ,filters,directives, beforeRouteLeave等未提供装饰器的选项,也可以声明computed,watch等
js写法:
<script>
import Home from './Home.vue'
import About from './About.vue'
export default {
data() {
return {
title: '父组件中的值'
}
},
components: {
Home,
About
}
}
</script>
ts写法:
<script lang='ts'>
import Home from './Home.vue'
import About from './About.vue'
import { Component, Vue } from 'vue-property-decorator';
@Component({
components: {
Home,
About
}
})
export default class extends Vue {
private title: string = '父组件中的值'
}
</script>
@Emit
属性参数:@Emit(event?: string)
参数说明:
@Emit 装饰器接收一个可选参数,充当事件名。如果没有提供这个参数,@Emit会将回调函数名的camelCase转为kebab-case,并将其作为事件名;
@Emit的回调函数的参数,会在回调函数没有返回值的情况下,被 e m i t 当 做 第 二 个 参 数 使 用 。 @ E m i t 会 将 回 调 函 数 的 返 回 值 作 为 第 二 个 参 数 , 如 果 返 回 值 是 一 个 P r o m i s e 对 象 , emit当做第二个参数使用。 @Emit会将回调函数的返回值作为第二个参数,如果返回值是一个Promise对象, emit当做第二个参数使用。@Emit会将回调函数的返回值作为第二个参数,如果返回值是一个Promise对象,emit会在Promise对象被标记为resolved之后触发;
js写法:
export default {
data() {
return {}
},
mounted() {
this.$on('trigger-emit', data => {
alert(data)
})
},
methods: {
triggerEmit(val) {
this.$emit('trigger-emit', val)
}
}
}
ts写法:
<script lang="ts">
import { Component, Vue, Emit } from 'vue-property-decorator';
@Component({})
export default class Home extends Vue {
private mounted() {
this.$on('trigger-emit', (data: any): void => {
alert(data)
})
}
@Emit()
triggerEmit(n: any) {
console.log('hhh')
}
}
</script>
@Prop
属性参数:@Prop(options: (PropOptions | Constructor[] | Constructor) = {})
参数说明:@Prop装饰器接收一个参数,这个参数可以有三种写法:
PropOptions,可以使用以下选项:type,default,required,validator;
Constructor[],指定 prop 的可选类型;
Constructor,例如String,Number,Boolean等,指定 prop 的类型;
js写法:
export default {
props: {
propA: {
type: Number
},
propB: {
default: 'default value'
},
propC: {
type: [String, Boolean]
},
}
}
ts写法:
<script lang="ts">
import {Vue, Component, Prop} from 'vue-property-decorator';
@Component
export default class "组件名" extends Vue{
@Prop(Number) propA!: number;
@Prop({default: 'default value'}) propB!: string;
@prop([String, Boolean]) propC: string | boolean;
}
</script>
七.变量挂载在全局
(vue3.0官网 -> api参考 -> 应用配置 -> globalProperties)
import Axios from "axios";
const app = createApp(App);
app.config.globalProperties.$axios = Axios;
app
.mount("#app");
在页面通过getCurrentInstance()获取
import {getCurrentInstance } from "vue";
setup(props){
const { ctx } = getCurrentInstance();
ctx.$axios.post("getSms")
}
但一般建议使用proxy作为上下文的引用。
八.跨域
官网的配置参考-> devServe.proxy
baseUrl设为"/api"->axios就会自动八baseUrl和后面的其他请求路径凭借起来->请求的路径就是:本地的ip+baseUrl+请求接口。
设置跨域以后,’/api’的target指向另外一个地址,你们请求的地址的ip就不是本地的了,就是这个新地址+/api+请求的接口。然后通过正则匹配/api,把/api转为空字符串.
但这一段代码只有开发环境才会运行,线上环境是不会运行的。
九.环境变量
百度搜索:vue cli
一个vue脚手架有三种模式:
development:开发模式
test:测试模式
production:生产模式
1.定义三个环境变量的文件
开发环境 .env.development 运行npm run dev
生产环境 .env.production 运行npm run build
测试环境 .env.test 没有对应的命令,但可以在package.json里面自定义
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-test": "vue-cli-service build --mode test",
"lint": "vue-cli-service lint"
},
2.三个环境变量分别定义内容
.env.development:
# 本地环境联调接口的标记匹配
VUE_APP_FLAG = '/devApi'
#跨域地址
VUE_APP_APIURL = 'http://www.web-jshtml.cn/api/vue3'
#帐户体系
VUE_APP_ACCOUNT_APIURL = ''
#用户体系
VUE_APP_USER_APIURL = ''
.env.production:
VUE_APP_FLAG = ''
#帐户体系
VUE_APP_ACCOUNT_APIURL = 'http://account.web-jshtml.cn'
#用户体系
VUE_APP_USER_APIURL = 'http://user.web-jshtml.cn'
.env.test
VUE_APP_FLAG = ''
#帐户体系
VUE_APP_ACCOUNT_APIURL = 'http://account-test.web-jshtml.cn'
#用户体系
VUE_APP_USER_APIURL = 'http://user-test.web-jshtml.cn'
3.在request.js里面封装axios的baseUrl里面只需要是process.env.变量名称
import axios from "axios";
import { message } from "ant-design-vue";
const service = axios.create({
baseURL: process.env.VUE_APP_FLAG,
timeout: 5000
});
4.在vue.config.js里面
const path = require("path");
// vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '' : './',
// 构建项目生成的目录
outputDir: process.env.NODE_ENV === 'production' ? 'dist' : 'devDist',
// 关闭语法的自动检测
lintOnSave: false,
devServer: {
open: false, // 运行项目后是否自动打开
host: "0.0.0.0", // 可以让外部访问
port: 8000,
proxy: {
[process.env.VUE_APP_FLAG]: {
target: process.env.VUE_APP_APIURL,
ws: false, // webstock
changeOrigin: true, // 是否开启跨域
pathRewrite: {
[`^${process.env.VUE_APP_FLAG}`]: '' // 查找开头为/api的字符替换成“空字符串” /api/getCode
}
}
}
}
}
4.接口的调用
import service from "@/utils/request.js";
export function GetCode(data){
return service.request({
url: '/error/',
method: 'post',
data,
})
}
/**
* 帐户体系 - 登录
*/
export function AccountLogin(data){
return service.request({
url: process.env.VUE_APP_ACCOUNT_APIURL + 'http://account-test.web-jshtml.cn/login/',
method: 'post',
data,
})
}
/**
* 用户体系 - 登录
*/
export function UserList(data){
return service.request({
url: process.env.VUE_APP_USER_APIURL + '/list/',
method: 'post',
data,
})
}