构建 vue3+vite 开发环境
- npm init vite-app 项目名
- npm install
- npm install vue-router@next --save //配置router 创建router目录
- npm install vuex@next //配置vuex
element-plus
- element-plus
<el-dialog>
中:visible.sync=“isShow” 改为v-model - element-plus中日期选择器中
value-format="yyyy-MM-dd HH:mm:ss "
改为value-format="YYYY-MM-DD HH:mm:ss"
- element-plus
<el-row>
标签多了display: flex ;
属性 ::v-deep .child
修改为::v-deep(.child)
- element-plus 默认英文,切换为中文操作
//在main.js文件中
import ElementPlus from 'element-plus' // 引入element-ui-plus
import zhLocale from 'element-plus/lib/locale/lang/zh-cn' // element-plus配置中文
import 'element-plus/dist/index.css' // element-plus样式
app.use(ElementPlus,{ locale:zhLocale }).mount('#app')
vue3
- 当注册组件为驼峰命名法时,引用需要小写加-
import DatePacker from '@/components/global/DatePacker.vue'
components:{
DatePacker // 需要大写
},
//标签引用 <date-packer>
- 引入
router
时,如果name命名有重复会导致页面显示空白 - vue-cli3舍弃了
filters
过滤器,可以使用函数做数据回显处理,或者使用computed
属性处理
setup函数
- setup选项在组件创建之前执行,一旦props被解析,将作为组合式API的入口,为其提供使用的位置
- setup接收props和context两个函数:
setup(props,context){}
- 在setup中需避免使用
this
,因为会找不到组件实例,无法获取
在setup中获取this方法
// vue3
import { getCurrentInstance } from 'vue'
export function useCurrentInstance() {
const { appContext } = getCurrentInstance()
return appContext.config.globalProperties
}
import { getAppContext } from ../../../src/common/common';
const that = useCurrentInstance()
//---------------------------------------------------------------
// vue3+ts
import { getCurrentInstance, ComponentInternalInstance } from 'vue'
export function useCurrentInstance(): any {
const { appContext } = getCurrentInstance() as ComponentInternalInstance
const proxy: any = appContext.config.globalProperties
return { proxy }
}
引用
import { useCurrentInstance } from '@/common/js/common'
const { proxy: that } = useCurrentInstance()
console.log(that)
路由跳转
// 法1
import { useRouter } from 'vue-router';
export default {
setup() {
const router = useRouter();
function goto(){ router.push("/about"); }
// 一定要要放在return里才能在模板上使用
return{ goto }
}
}
// 法2
import router from "../../router/index.js";
router.push("/");
router-history
/hash
vue2
import VueRouter from 'vue-router'
Vue.use(VueRouter) // 全局使用Router
export default new VueRouter({
mode: "history", // mode:"hash"
routes:[]
})
vue3
import { createRouter, createWebHistory } from 'vue-router'
// history: –createWebHistory
// hash: –createWebHashHistory
import { createRouter, createWebHistory } from 'vue-router'
const routes = []
const router = createRouter({
history: createWebHistory(), // history: createWebHashHistory(),
routes
})
reactive和ref
-
reactive()
—将数据变成响应式数据,数据驱动UI,用于复杂数据类型——对象、数组 -
ref()
—由于reactive()
必须传递一个对象,如只想某个变量实现响应式比较麻烦,ref()
可实现简单值的监听 -
reactive
本质上是将传入的数据包装成一个Proxy对象 -
ref
底层本质还是reactive
,ref(xx)->reactive({value:xx})
,是对reactive
的第二次包装 -
ref
获取数据值时需要.value
import { defineComponent , reactive , toRefs , ref , onMounted } from 'vue'
export default defineComponent ({
setup(){
const allData = ref(1)
console.log(allData.value) // 1
const allData = reactive({ count: 'abc' })
console.log(allData.count)
onMounted(()=>{ })
return{ ...toRefs(allData) }
}
})
toRefs将 reactive()
创建出来的响应式对象, 转换为普通对象
toRaw
返回 reactive 或 readonly 代理的原始对象,跳过Proxy的过程。
这是一个“逃生舱”,可用于临时读取数据而无需承担代理访问/跟踪的开销,也可用于写入数据而避免触发更改
import { toRaw } from '@vue/reactivity'
setup(){
let Form = reactive({
ruleForm:{username:''}
})
let list = toRaw(Form)
console.log(list)
console.log(Form)
return { ...toRefs(Form)}
}
watch和watchEffect
watch
只有监听的值发生变化才执行,watchEffect
初始化时会先执行一次watch
需要具体监听参数,watchEffect
不需要传入监听参数watch
能获取到前后newValue
,oldValue
值,watchEffect
只能获取newValue
- 两者都无法监听到 未双向绑定的属性
<el-input class="width-220" v-model="ruleForm.count"></el-input>
import { defineComponent , reactive , toRefs , watch , watchEffect } from 'vue'
export default defineComponent({
setup(){
const allData = reactive({
ruleForm:{ count:1 }
})
watch(()=>allData.ruleForm.count,(newValue,oldValue)=>{
console.log(`原值${oldValue}`)
console.log(`新值${newValue}`)
})
watchEffect(()=>{
console.log('ruleForm',allData.ruleForm.count)
})
}
})
form表单
<template>
<el-container class="loginRegister">
<el-main>
<el-form class="login-form m-auto" :model="ruleForm" :rules="rules" ref="formRef" label-width="100px">
<el-form-item label="用户" prop="username">
<el-input v-model="ruleForm.username" class="width-220"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="ruleForm.password" class="width-220"></el-input>
</el-form-item>
<el-form-item>
<div style="margin-left: 120px!important;">
<el-button :loading="loading" class="but-p mr20" type="primary" @click="handleSave">
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
<el-button class="but-p mr20" type="primary" @click="handleReset"> 重 置 </el-button>
</div>
</el-form-item>
</el-form>
</el-main>
</el-container>
</template>
<script lang="ts">
import { reactive , toRefs , onMounted , ref , unref } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
export default {
setup(){
const router = useRouter()
onMounted(){
gethandler()
}
let allData = reactive({
ruleForm:{
username:'', // 用户名称
password:'', // 密码
},
rules:{
username: [{required: true, message: '请输入登陆名', trigger: 'blur'}],
password: [{required: true, message: '请输入密码', trigger: 'blur'}]
},
loading:false
})
const formRef = ref()
// 登录
let handleSave = async () =>{
const form = unref(formRef)
if(!form) return
try {
await form.validate()
allData.loading = true
let data = {}
axios_login(data).then(res=>{
if(true){
router.push('/template')
}else{
ElMessage.error('错误')
allData.loading = false
}
})
}catch (err) {
allData.loading = false
console.log(err)
}
}
// 重置
let handleReset = ()=>{
// 清空 表单数据
const form = unref(formRef)
form.resetFields();
}
return { ...toRefs(allData) , onMounted , formRef , handleSave , handleReset }
}
}
</script>
待续。。。