vue3.x配合Typescript配合element-ui-Plus 基础安装配置使用教程(vue3.x ref 响应式,钩子)
vue3.x(vue-cli@4.5) Typescript element-ui-Plus
vue3不适用2版本的element-ui,要使用https://element-plus.gitee.io/#/zh-CN/component/installation(element-ui-plus)
安装步骤:vue add element-plus
安装完: main.ts内会新增
import installElementPlus from './plugins/element'
const app = createApp(App)
installElementPlus(app)
把./plugins/element的element文件后缀改为ts
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import locale from 'element-plus/lib/locale/lang/zh-cn'
export default (app: any) => { // 加入any类型判断
app.use(ElementPlus, { locale })
}
成功引入element-ui-plus
vue3写法,新特性
1、setup 函数 setup() 函数是 vue3 中,专门为组件提供的新属性。它为我们使用 vue3 的 Composition API 新特性提供了统一的入口
1.1 执行时机 setup 函数会在 beforeCreate 之后、created 之前执行
ref
示例
<!--在 template 中访问响应式数据,会默认加.value-->
<template>
<div class="about">
<h2>欢迎来到红浪漫狗子服务中心</h2>
<el-button v-for="(item, index) in girls"
:key="index"
@click="selectGirlFn(index)">
{{index}}号技师:{{item}}
</el-button>
<p>你选择了【{{selectGirl}}】为你服务</p>
</div>
</template>
<script lang="ts">
import { Options, Vue } from 'vue-class-component'
import { defineComponent, ref, reactive } from 'vue'
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'about',
setup () {
const girls = ref(['大狗子', '二狗子', '三狗子'])
const selectGirl = ref('')
const selectGirlFn = (index: number) => {
// 只在setup函数内部访问ref函数需要加.value
selectGirl.value = girls.value[index]
}
return {
girls,
selectGirl,
selectGirlFn
}
}
})
</script>
在 reactive 对象中访问 ref 创建的响应式数据
// template 渲染
<p>{{state.selectGirl}}</p>
setup () {
const state = reactive({selectGirl})
console.log(state.selectGirl) // 1
return { state }
}
reactive toRefs
reactive可以声明变量,直接赋值,不要.value,但是它不是响应式的数据,需要使用toRefs,toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据
<p>{{ count }}</p>
<button @click="increment">+1</button>
import { toRefs, reactive } from 'vue'
setup() {
const state = reactive({
count: 0,
naem: 'zs'
})
const increment = () => {
state.count++
}
return {
// 将 state 上的每个属性,都转化为 ref 形式的响应式数据
...toRefs(state),
increment
}
}
生命周期,钩子函数
这些生命周期钩子注册函数只能在 setup() 期间同步使用, 因为它们依赖于内部的全局状态来定位当前组件实例(正在调用 setup() 的组件实例), 不在当前组件下调用这些函数会抛出一个错误。
写法
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
},
与2对应
Vue2.x 的生命周期 | Vue3.x 的生命周期
beforeCreate | 使用 setup()
created | 使用 setup()
beforeMount | onBeforeMount //组件挂载到节点上之前
mounted | onMounted //组件挂载完成后
beforeUpdate | onBeforeUpdate //组件更新之前
updated | onUpdated // 组件更新完成后
beforeDestroy | onBeforeUnmount //组件卸载之前
destroyed | onUnmounted //组件卸载完成后
errorCaptured | onErrorCaptured //捕获一个来自子孙组件异常
| onActivated //被包含在<keep-alive></keep-alive>中的组件会多出两个生命周期钩子函数,被激活时执行
| onDeactivated // 比如a组件切换到b组件,a组件消失时执行
新增的钩子函数
除了与 Vue2.x 等效的生命周期之外,composition-api 还新增了以下生命周期钩子用作调试:
onRenderTracked onRenderTriggered 两个钩子函数都接收一个 DebuggerEvent :
export default {
onRenderTriggered(e) {
debugger
// 检查哪个依赖性导致组件重新渲染
},
}
原2.x钩子函数也能写,写在setup下面,setup()在beforeCreate之前执行。 只要用一种就行,如果混用,同类型的钩子setup里的比2.x的先执行
props(组件传值),context(上下文对象),
&&
Suspense(异步组件),teleport(自由组件)
<template>
<teleport to="#modal">
<el-dialog
title="公告"
v-model="isShow"
width="30%"
center>
<Suspense>
<template #default>
<AsyncShow />
</template>
<template #fallback>
<h3>loading...</h3>
</template>
</Suspense>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="close">确 定</el-button>
</span>
</template>
</el-dialog>
</teleport>
</template>
<script lang="ts">
import { ref, watchEffect, onErrorCaptured } from 'vue'
import AsyncShow from '@/components/AsyncShow.vue'
export default {
name: 'Modal',
props: {
isDialog: {
type: Boolean,
default: false
}
},
components: {
AsyncShow
},
setup(props: any, context: any) {
const isShow = ref(false)
watchEffect(() => {
isShow.value = props.isDialog
})
const close = () => {
context.emit('close')
}
onErrorCaptured((err) => { // 用来捕获异步请求的异常
console.log(err)
return true
})
return {
isShow,
close
}
},
}
</script>
<style lang="scss" scoped>
</style>
teleport 自由组件,可自由展示在想要地方
如index.html,或者其他任意地方
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<div id="modal"></div>
<!-- built files will be auto injected -->
</body>
watch, computed
setup () {
const confirmVal = ref('粉红浪漫')
const data = reactive({
name: '秋梨膏',
userList: [{name: '老司机', age: 99}]
})
const userInfo = computed(() => {
return data.userList.find(item => item.name === '老司机')
})
//1.watch单个值
watch(confirmVal, (newVal, oldVal) => {
console.log(newVal, oldVal)
})
//2.watch多个值,对象某个属性,取值方法1
watch([confirmVal, () => data.name], (newVal, oldVal) => {
console.log(newVal[0], oldVal[0])
console.log(newVal[1], oldVal[1])
})
//3.watch多个值,对象某个属性,取值方法2
watch([confirmVal, () => data.name], [(newConVal, oldConVal), (newName, oldName)] => {
console.log(newConVal, oldConVal)
console.log(newName, oldName)
})
return {
confirmVal,
...toRefs(data),
}
}
Suspense异步组件
<Suspense>
<template #default>
<AsyncShow />
</template>
<template #fallback>
<h3>loading...</h3>
</template>
</Suspense>
AsyncShow组件,里是一个promise,如果我们要在等待组件获取数据并解析时显示“正在拼了命的加载…”之类的内容,则只需三个步骤即可实现Suspense。
将异步组件包装在<template #default>标记中 在我们的Async组件的旁边添加一个兄弟姐妹,标签为<template #fallback>。 将两个组件都包装在<suspense>组件中 使用插槽,Suspense将渲染后备内容,直到默认内容准备就绪。然后,它将自动切换以显示我们的异步组件。
==AsyncShow组件==
<template>
<div>
<h3>{{result}}</h3>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'AsyncShow',
setup() {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve({result: '最新迎新年活动:单次消费满888元打88折!!!'})
}, 1000);
})
}
})
</script>
router
import { useRouter } from 'vue-router'
const $router = useRouter()
$router.push('/home')
配合element-ui plus使用
一个登录功能如下:
<template>
<div class="login">
<el-form :model="form"
:rules="rules"
ref="formRef"
label-width="60px"
class="form">
<el-form-item label="账号" prop="loginName">
<el-input v-model="form.loginName" clearable placeholder="请输入账号">
<template #suffix>
<i class="el-input__icon el-icon-user"></i>
</template>
</el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password" clearable placeholder="请输入密码">
<template #suffix>
<i class="el-input__icon el-icon-key"></i>
</template>
</el-input>
</el-form-item>
<el-form-item label="">
<el-button class="login-btn" @click="login">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { onMounted, reactive, ref, toRefs, defineComponent } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { LoginApi } from '@/apis'
import md5 from 'blueimp-md5'
import _ from 'lodash'
import $to from '@/utils/to'
export default defineComponent({
name: 'Login',
setup () {
const $router = useRouter()
const formRef = ref(null)
const data = reactive({
form: {
loginName: '',
password: '',
logintype: 'local',
url: window.location.href
},
bgType: 'wave',
rules: {
loginName: [
{ required: true, message: '请输入账号', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
},
login: () => {
const params = {
loginName: data.form.loginName,
password: String(md5(data.form.password)).toUpperCase(),
logintype: 'local',
url: window.location.href
}
formRef.value.validate(async (valid) => {
if (valid) {
const [err, data] = await $to(LoginApi.login(params))
if (err) {
ElMessage.error(err.data && err.data.message || err.message)
} else {
$router.push('/home')
}
} else {
return false
}
})
}
})
return {
...toRefs(data),
formRef
}
},
})
</script>
因element的form表单需要绑定ref,来实现调用表单方法,所以在 <el-form :model="form" :rules="rules" ref="formRef" label-width="60px" class="form">上绑定ref, 在setup中定义 const formRef = ref(null),关联起来,formRef.value即为form实例对象,和2.x的this.$refs.formRef同样了.当然使用reactive来声明变量也是一样结果,只是要同名
VueX
通过import {useStore} from 'vuex'获取vuex对象。 https://www.cnblogs.com/guiyishanren/p/10657910.html vuex教程文档\
import {useStore} from 'vuex'
import {onMounted} from 'vue'
setup(props, context) {
const store = useStore()
onMounted(() => {
console.log(store.name)
store.commit('show', '传值')
})
}
更多推荐
所有评论(0)