踩坑记11 vue3 组件化 | watchEffect component组件 | @element-plus/icons el-icon | npm和yarn更新包

2021.8.5
封装组件,使用el-icon(SVG Icon)。
坑34(封装、组件化、生命周期钩子、路由守卫 :本坑记录的是未使用watch/watchEffect时的原始封装方法,仅作为记录。ps:下一坑35采用watchEffect方法(超好用!!!)。
与上一篇 踩坑记10 vue3、vuex4、组件化_Alloom的博客-CSDN博客 坑33中的封装方式(父组件获取路由数据,通过props传值给子组件,子组件通过computed设置响应性,数据更新时间是在父组件setup中调用onMounted和router.afterEach时)有相似也有不同。
考虑到之前的方法需要在组件之间通信传输一定量的数据。本坑的方法则将获取路由数据的方法封装到了组件内部,但获取或者说更新时间依然依赖父组件。
具体方法是设置一个updateCount值,其在父组件触发调用onMounted和router.afterEach时值更变+1;该值作为props传递给子组件,但子组件无需获取其具体值,只是相当于接收了一个更新信号;最后在子组件的onUpdated中进行数据的获取及更新。这样就将原先集合在父组件中的数据获取及更新的方法函数分别分装到了对应的各组件中。
//子组件script
import { onUpdated,reactive,toRefs } from 'vue'
import { useRouter } from 'vue-router'
export default {
    name:'Breadcrumb',
    setup(){
        const router=useRouter()
        const state=reactive({
            matchedRoutes:[],
        })
        onUpdated(()=>{
            state.matchedRoutes=router.currentRoute.value.matched.filter(r=>{
                return r.path!=='/index'
            })
        })
        return {
            ...toRefs(state),
        }
    }
}

//父组件template
<Breadcrumb :updateCount='updateCount'/>

//父组件script
import { onMounted,reactive,toRefs } from 'vue'
import { useRouter } from 'vue-router'
import Breadcrumb from './widgets/Breadcrumb.vue'

export default {
    components: { Breadcrumb },
    name: 'Header',
    setup() {
        const router=useRouter()
        const state=reactive({
            updateCount:0
        })
        router.afterEach((to,from) => {
            state.updateCount+=1
        });
            
        onMounted(()=>{
            state.updateCount+=1
        })

        return {
            ...toRefs(state),
        }
    },
}

坑35(vue3、watchEffect :目标是用watchEffect监听路由变化获取相关数据用于组件更新。
前情提要:继坑33和34后继续改进组件封装,涉及到的重要问题是获取初始和变更的路由数据的时机。之前主要依赖父组件中的onMounted和router.afterEach来确认进行更新的时间。
正题:为使子组件摆脱对父组件的依赖,在本此改进中使用watchEffect(好用!!!就显得之前一直生命周期钩子+路由守卫的我很傻)。
以下是相关代码,可与坑34对比查看(基本只是将onUpdated换成了watchEffect,简简单单):
//子组件script
import { reactive,toRefs,watchEffect } from 'vue'
import { useRouter } from 'vue-router'
export default {
    name:'Breadcrumb',
    setup(){
        const router=useRouter()
        const state=reactive({
            matchedRoutes:[],
        })
        watchEffect(()=>{
            state.matchedRoutes=router.currentRoute.value.matched.filter(r=>{
                return r.path!=='/index'
            })
        })
        return {
            ...toRefs(state),
        }
    }
}

//父组件template
<Breadcrumb />
坑36(npm、更新包 :背景是element-plus需要更新,但直接npm install和npm update element-plus都是没有效果的。了解一下原理机制,参考: npm的package.json和package-lock.json更新策略_Hello博客-CSDN博客
删除package-lock.json和yarn.lock后,npm install,依然没有改变版本。
用npm info element-plus查看了一下信息,最新版本已经到1.0.2-beta.69了。
于是通过npm install element-plus@1.0.2-beta.69进行了指定安装。
另外,安装了更新插件npm install -g npm-check-updates,通过ncu指令即可快速查看可更新的包。
之后用yarn upgrade --latest更新了所有包到最新版本,用npm list可以看到包已经更新了。
但package.json和package-lock.json中的版本依然没变,ncu查看到的也是之前版本,需更新。
所以又用了一下ncu -u来更新package.json,再用npm install更新了包。
2021.8.12更新:
发现ncu -u更新package.json、npm install更新包后,package-lock.json和yarn.lock都会同步更改。所以简化版的更新方式是:
ncu查看可更新包,如果 全部更新 ,则 ncu -u、npm install,安装全部最新版本的包;如果 部分更新 ,则 npm install 包名@版本号,进行指定版本的安装。
2021.8.30更新:
注意!上文使用的 ncu更新包的方法,不适用于vue3的更新,因为vue3是vue的next版本。
更新vue3到最新版本的方法:直接 npm install vue@next 或者根据github中发布的版本号(可选择最新版本/之前版本), 手动更改package.json中vue对应的版本号
坑37( @element-plus/icons、 el-icon :Element Plus 团队表示正在将原有组件内的 Font Icon 向 SVG Icon 迁移,于是目标是对代码进行对应的更新,Font Icon换成SVG Icon。
更新了 element-plus版本,指定安装 npm install element-plus@1.0.2-beta.69(2021.8.5时的最新版本)。之后直接使用<el-svg-icon><fold /></el-svg-icon>,报错:
[Vue warn]: Failed to resolve component: fold
[Vue warn]: Failed to resolve component: el-svg-icon
查文档,安装图标,npm install @element-plus/icons。依然报错。
文档表示:需要全局注册组件或者在要用到的组件中单独注册。看了一下源码,发现无统一导出,只能一个个注册。因此暂时选择在要用到的组件中注册,试一下效果,可行则改为全局注册。
组件中注册:
//组件script
import { Fold } from '@element-plus/icons'
import { Edit } from '@element-plus/icons'

export default {
    components: {
        Fold,
        Edit
    }
}
全局注册:
//main.js
import { Expand } from '@element-plus/icons'

const app=createApp(App)
app.component('expand',Expand)
app.mount('#app')
使用,第一种el-svg-icon会报错,后两者可用:
<!-- 组件template -->
<!-- 来自文档中点击SVG图标自动复制的内容,会报错 -->
<el-svg-icon><fold /></el-svg-icon>
<!-- 来自文档中代码段,可用 -->
<el-icon :size='20'><edit /></el-icon>
<expand />
错误:Failed to resolve component: el-svg-icon,于是去代码中查找,未找到以el-svg-icon命名或内含此字段的相关文件。暂不理会。
      
坑38( component组件、 el-icon、el-menu :目标是动态地向子菜单添加图标,供折叠时显示。
首先是走的弯路:参考此篇 vue 3.0 使用ref获取dom元素_好巧的博客-CSDN博客_vue3 获取dom 动态循环添加ref获取el-icon元素,在onMounted中向其用innerHTML添加相应的SVG Icon,但可能因为是之后添加的,例如添加<management />,其并没有被解析成svg组件,在网页查看其元素是看到的是<management ><management/>。不会显示相应图标。
于是寻找其他方法,找到了component组件。
vue3中的component组件,通过绑定is属性可以动态地渲染采用的组件。使用:
<el-icon :size='26' >
    <component :is="route.meta.icon"></component>
</el-icon>
完美显示图标。
by 莫得感情踩坑机(限定)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值