技术栈:v3 + webpack + element-plus + sass
fregment
teleport
Suspense
用于处理需要异步数据返回的异步组件(loading,过渡,骨架屏)
v-model变更
prop: value=> modelValue
event: input => update:modelValue
属性绑定
vue3绑定在app上
vue2绑定在vue上
比如:vue.component
- vue2没有app概念 new Vue()的根实例作为一个app,全局只有一个,容易被污染
- 全局配置也导致没办法在单页上做不同app实例
由于是全局的,所以不要引用就可以使用import {createApp} from 'vue'
import App from './App.vue'
createAPP(App).component('comp', {
render() {
return h('div', 'i anm comp')
}
}).mount('#app')
<comp></comp>
sass和sass-loader默认版本不兼容
Syntax Error: TypeError: this.getOptions is not a function
sass ^1.32.12
sass-loader 11.0.2
解决方案
yarn add sass-loader@10
element-plus按需导入的全局引用问题
配置按需导入后全局引用存在一定性问题,有可能导致找不到引用对象
需要使用use方法代替component的方式
初始化子组件默认配置在mounted周期失效
如图所示,下图将所有的分页器抽离成全局组件
子组件在mounted周期无法获取父组件的值
解决方案
解决方法,提前一个周期使用,直接在创建DOM后,即为created
vue3.0中的监听路由已经不能使用watch的方法
无明显优化效果
业务场景中需要路由变化时重新渲染的操作
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate(to => {
console.log(to, '新路由')
})
import { useRoute } from 'vue-router'
const route = useRoute()
watch(() => route.path, (val) => {
console.log('%c%s', 'color: #00a3cc', val)
})
/deep/深度选择器警告
// /deep/ .el-input__inner {
// border:0;
// }
::v-deep(.el-input__inner) {
border:0;
}
vue-router通配符路由重定向
vuex => hooks数据数据状态维护状态
vuex可以延用v2的风格,也可以通过compotion API的方式使用, 但当前大厂的最佳实践中,很多项目已经在vue3中弃用vuex的依赖,采用hooks方式
v2-vuex
v3-vuex
v3-hooks
/*
* @Date: 2021-06-30 09:34:45
* @LastEditTime: 2021-07-01 10:39:13
*/
import * as IpistrAction from "@/contract/ipistr";
import * as PriceAction from "@/contract/priceOracle";
import { useWallet } from "@/hooks/useWallet";
import { reactive } from "vue";
import { useContract } from "@/hooks/useContract";
const { account } = useWallet();
const { contractAddress } = useContract();
const balance = reactive({
price: 0,
amount: 0
});
export function useBalance() {
async function fetchBalance() {
if (!account.value) return;
try {
let result = await IpistrAction.getBalanceOf(account.value);
balance.amount = result;
} catch (error) {
console.log(error, "fetchBalance");
}
}
/**
* @description: 获取喂价机价格
* @param {*} tokenAddress
* @return {*}
*/
async function fetchPrice() {
if (!contractAddress.IPISTR) return;
try {
let result = await PriceAction.getFeedPrice(contractAddress.IPISTR);
balance.price = String(result / 10 ** 18);
} catch (error) {
console.log(error, "fetchPrice");
}
}
function updateBanance() {
fetchBalance();
fetchPrice();
}
return {
balance,
fetchPrice,
fetchBalance,
updateBanance
};
}
父子组件通信
setup
函数可接受两个参数:props
、context
;
props
表示父组件传递过来的属性,且值为响应式的,若修改其值页面将被更新。故,props
不能进行解构,但可以使用toRefs
进行解构,否则它将失去响应式。context
上下文,里面包含attrs
、slots
、emit
等。它不是响应式的,故可以进行解构
当 setup
被执行时,组件实例未被创建,只能访问到以下属性:props
、attrs
、slots
、emit
。不能访问到其他选项:computed
、methods
等。
主要是子组件变化比较大,父组件写法和v2一致
自定义指令的写法
<body>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
const autoFocus = (ctx) => {
ctx.el.focus()
}
createApp().directive('auto-focus', autoFocus).mount()
</script>
<div v-scope>
<input v-auto-focus />
</div>
</body>
组件封装中的上下文问题
论坛地址: https://www.yuque.com/webkubor/talking/fr89p8
配置web-components
// 任何以“ion-”开头的元素都将被识别为自定义元素
app.config.isCustomElement = tag => tag.startsWith('ion-')
指定一个方法,用来识别在 Vue 之外定义的自定义元素(例如,使用 Web Components API)。如果组件符合此条件,则不需要本地或全局注册,并且 Vue 不会抛出关于 Unknown custom element 的警告。
注意,所有原生 HTML 和 SVG 标记不需要在此函数中匹配——Vue 解析器自动执行此检查。
v-model与.sync功能重叠问题
vue3做了统一
//父组件
<componet v-model="data"></componet>
// 等效于
<componet :modelValue="data" @update:modelValue="data=$event"></componet>
// 子组件
props:['modelValue']
$emit('update:modelValue', newValue)