欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你完全掌握Vue自定義指令

 更新時(shí)間:2023年03月03日 11:12:26   作者:yyds2026  
作為使用Vue的開發(fā)者,我們對(duì)Vue指令一定不陌生,諸如v-model、v-on、等,同時(shí)Vue也為開發(fā)者提供了自定義指令的api,熟練的使用自定義指令可以極大的提高了我們編寫代碼的效率,讓我們可以節(jié)省時(shí)間開心的摸魚

準(zhǔn)備:自定義指令介紹

除了核心功能默認(rèn)內(nèi)置的指令 (v-model 和 v-show等),Vue 也允許注冊(cè)自定義指令。注意,在 Vue2.0 中,代碼復(fù)用和抽象的主要形式是組件。然而,有的情況下,你仍然需要對(duì)普通 DOM 元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令。

作為使用Vue的開發(fā)者,我們對(duì)Vue指令一定不陌生,諸如v-model、v-on、v-for、v-if等,同時(shí)Vue也為開發(fā)者提供了自定義指令的api,熟練的使用自定義指令可以極大的提高了我們編寫代碼的效率,讓我們可以節(jié)省時(shí)間開心的摸魚~

對(duì)于Vue的自定義指令相信很多同學(xué)已經(jīng)有所了解,自定義指令的具體寫法這里就不細(xì)講了,官方文檔很詳細(xì)。 但是不知道各位同學(xué)有沒有這種感覺,就是這個(gè)技術(shù)感覺很方便,也不難,我也感覺學(xué)會(huì)了,就是不知道如何去應(yīng)用。這篇文檔就是為了解決一些同學(xué)的這些問題才寫出來的。
PS:這次要講的自定義指令我們主要使用的是vue2.x的寫法,不過vue3.x不過是幾個(gè)鉤子函數(shù)有所改變,只要理解每個(gè)鉤子函數(shù)的含義,兩者的用法差別并不大。

試煉:實(shí)現(xiàn)v-mymodel

我的上篇文章說到要自己實(shí)現(xiàn)一個(gè)v-model指令,這里使用v-myodel模擬一個(gè)簡(jiǎn)易版的,順便再領(lǐng)不熟悉的同學(xué)熟悉一下自定義指令的步驟和注意事項(xiàng)。

定義指令

首先梳理思路:原生input控件與組件的實(shí)現(xiàn)方式需要區(qū)分,input的實(shí)現(xiàn)較為簡(jiǎn)單,我們先實(shí)現(xiàn)一下input的處理。

首先我們先定義一個(gè)不做任何操作的指令

Vue.directive('mymodel', {
        //只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。
        bind(el, binding, vnode, oldVnode) {
        },
        //被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用 (僅保證父節(jié)點(diǎn)存在,但不一定已被 插入文檔中),需要父節(jié)點(diǎn)dom時(shí)使用這個(gè)鉤子
        inserted(el, binding, vnode, oldVnode) {
        },
        //所在組件的 VNode 更新時(shí)調(diào)用,**但是可能發(fā)生在其子 VNode 更新之前**。指令的值可能發(fā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見下)。
        update(el, binding, vnode, oldVnode) {
        },
        //指令所在組件的 VNode **及其子 VNode** 全部更新后調(diào)用。
        componentUpdated(el, binding, vnode, oldVnode) {
        },
        只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。
        unbind(el, binding, vnode, oldVnode) {
        },
})

上面的注釋中詳細(xì)的說明了各個(gè)鉤子函數(shù)的調(diào)用時(shí)機(jī),因?yàn)槲覀兪墙o組件上添加input事件和value綁定,因此我們?cè)赽ind這個(gè)鉤子函數(shù)中定義即可。所以我們把其他的先去掉,代碼變成這樣。

Vue.directive('mymodel', {
        //只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。
        bind(el, binding, vnode, oldVnode) { 
        }
})

簡(jiǎn)單說一下bind函數(shù)的幾個(gè)回調(diào)參數(shù),el是指令綁定組件對(duì)應(yīng)的dom,binding是我們的指令本身,包含name、value、expression、arg等,vnode就是當(dāng)前綁定組件對(duì)應(yīng)的vnode結(jié)點(diǎn),oldVnode就是vnode更新前的狀態(tài)。

接下來我們要做兩件事:

  • 綁定input事件,同步input的value值到外部
  • value值綁定,監(jiān)聽value的變化,更新到input的value

這對(duì)于input原生組件比較容易實(shí)現(xiàn):

//第一步,添加inout事件監(jiān)聽
el.addEventListener('input', (e) => {
   //context是input所在的父組件,這一步是同步數(shù)據(jù)
   vnode.context[binding.expression] = e.target.value;
})
//監(jiān)聽綁定的變量
vnode.context.$watch(binding.expression, (v) => {
     el.value = v;
})

這里解釋一下上面的代碼,vnode.context是什么呢,他就是我們指令所在組件的上下文環(huán)境,可以理解就是指令綁定的值所在的組件實(shí)例。不熟悉vnode結(jié)構(gòu)的同學(xué)建議先看一下官方的文檔,不過文檔描述的比較簡(jiǎn)單,不是很全面,所以最好在控制臺(tái)log一下vnode的對(duì)象看一下它具體的結(jié)構(gòu),這很有助于我們封裝自定義指令,對(duì)理解Vue原理也很有幫助。

我們可以通過context[binding.expression]獲取v-model上到綁定的值,同樣可以修改它。上面的代碼中我們首先通過在添加的input事件中操作vnode.context[binding.expression] = e.target.value同步input的value值到外部(context),與使用@input添加事件監(jiān)聽效果是一樣的;然后我們需要做第二件事,做value值的綁定,監(jiān)聽value的變化,同步值的變更到input的value上,我們想到我們可以使用Vue實(shí)例上的額$watch方法監(jiān)聽值的變化,而context就是那個(gè)Vue實(shí)例,binding.expression就是我們想要監(jiān)聽的屬性,如果我們這樣寫

<input v-mymodel='message'/>

那么binding.expression就是字符串'message'。所以我們想下面的代碼這樣監(jiān)聽綁定的響應(yīng)式數(shù)據(jù)。

//監(jiān)聽綁定的變量
vnode.context.$watch(binding.expression, (v) => {
     el.value = v;
})

至此,input的v-mymodel的處理就完成了(當(dāng)然input組件還有type為checkbox,radio,select等類型都需要去特別處理,這里就不再一一處理了,感興趣的同學(xué)可以自己嘗試去完善一下),但是對(duì)于非原生控件的組件,我們要特殊處理。

因此我們完善代碼如下:

Vue.directive('mymodel', {
        //只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。
        bind(el, binding, vnode, oldVnode) {
           //原生input組件的處理
           if(vnode.tag==='input'){
                //第一步,添加inout事件監(jiān)聽
                el.addEventListener('input', (e) => {
                   //context是input所在的父組件,這一步是同步數(shù)據(jù)
                   vnode.context[binding.expression] = e.target.value;
                })
                //監(jiān)聽綁定的變量
                vnode.context.$watch(binding.expression, (v) => {
                     el.value = v;
                })
           }else{//組件

???????           }
        }
})

接下來我們要處理的是自定義組件的邏輯,

//vnode的結(jié)構(gòu)可以參見文檔。不過我覺得最直觀的方法就是直接在控制臺(tái)打印處理
let {
    componentInstance,
    componentOptions,
    context
} = vnode;
const {
   _props
} = componentInstance;
//處理model選項(xiàng)
if (!componentOptions.Ctor.extendOptions.model) {
  componentOptions.Ctor.extendOptions.model = {
        value: 'value',
        event: 'input'
  }
}
let modelValue = componentOptions.Ctor.extendOptions.model.value;
let modelEvent = componentOptions.Ctor.extendOptions.model.event;
//屬性綁定,這里直接修改了屬性,沒有想到更好的辦法,友好的意見希望可以提出
_props[modelValue] = binding.value;
context.$watch(binding.expression, (v) => {
     _props[modelValue] = v;
})
//添加事件處理函數(shù),做數(shù)據(jù)同步
componentInstance.$on(modelEvent, (v) => {
     context[binding.expression] = v;
})

聲明一下,上面的實(shí)現(xiàn)不是vue源碼的實(shí)現(xiàn)方式,vue源碼中實(shí)現(xiàn)v-model更加復(fù)雜一點(diǎn),是結(jié)合自定義指令、模板編譯等去實(shí)現(xiàn)的,因?yàn)槲覀兪菓?yīng)用級(jí)別的封裝,所以采用了上述的方式實(shí)現(xiàn)。

實(shí)現(xiàn)此v-mymodel需要同學(xué)去多了解一下Vnode和Component的API,就像之前說的,最簡(jiǎn)單的方法就是直接在控制臺(tái)中直接打印出vnode對(duì)象,組件的vnode上有Component的實(shí)例componentInstance。

接下來簡(jiǎn)單說一下上面的代碼,首先我們可以在componentOptions.Ctor.extendOptions上找到model的定義,如果沒有的話需要設(shè)置默認(rèn)值value和input,然后分別對(duì)想原生input的處理一樣,分別監(jiān)聽binding.expression的變化和modelEvent事件即可。

需要注意的是,我們上面的代碼直接給_prop做了賦值操作,這實(shí)際上是不符合規(guī)范的,但是我目前沒有找到更好的方法去實(shí)現(xiàn),有好思路的同學(xué)可以在評(píng)論區(qū)留言指教。

應(yīng)用實(shí)踐:4個(gè)實(shí)用的自定義指令

上文我們通過封裝v-mymodel為各位同學(xué)展示了如何封裝和使用自定義指令,接下來我把自己在生產(chǎn)實(shí)踐中使用自定義指令的一些經(jīng)驗(yàn)分享給大家,通過實(shí)例,我相信各位同學(xué)能夠更深刻的理解如何在在應(yīng)用中封裝自己的指令,提高效率。

權(quán)限控制

下面我們定義一個(gè)v-permission指令用于全平臺(tái)的權(quán)限控制

  • role:角色控制;
  • currentUser:當(dāng)前登錄人判斷;當(dāng)前用戶是否是業(yè)務(wù)數(shù)據(jù)中的創(chuàng)建人或者負(fù)責(zé)人
  • bussinessStatus:業(yè)務(wù)狀態(tài)判斷;
  • every:與操作;
  • some:或操作;

示例代碼

//定義權(quán)限類型
const permissionType = {
    ROLE: 'role',
    CURRENTUSER:'currentUser',
    BUSSINESSSTATUS: 'bussinessStatus',
    MIX_EVERY: 'every',
    MIX_SOME: 'some'
}
export default {
    //只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用
    bind: function () {
    },
    //當(dāng)前vdom插入到真實(shí)dom時(shí),因?yàn)槭菍?duì)dom的樣式操作,在這里操作
    inserted: function (el, binding) {
        let show = false;
        show=processingType(binding.arg,binding.value); 
        el.style.display = `${show ? 'inline-block' : 'none'}`
    },
    //所在組件的VNode更新時(shí)調(diào)用,狀態(tài)更新后需要更新顯示狀態(tài)
    update: function (el, binding) {
        //避免無效的模板更新
        if(binding.value===binding.oldValue) return;
        let show = false;
        show=processingType(binding.arg,binding.value); 
        el.style.display = `${show ? 'inline-block' : 'none'}`
    },
    //指令所在組件的 VNode 及其子 VNode 全部更新后
    componentUpdated: function (el, binding) {
    },
    unbind: function () {
    },
}
//處理不同類型的權(quán)限控制
function processingType(type,value){
    let values=[];
    switch (type) {
        case permissionType.ROLE:
            return permissionByRole(value);
        case permissionType.CURRENTUSER:
            return permissionCreater(value);
        case permissionType.BUSSINESSSTATUS:
            return permissionBusinessStatus(value);
        case permissionType.MIX_EVERY:
            for(let type in value){
                values.push(processingType(type,value[type]))
            }
            return values.every(v=>{
                return v;
            })
        case permissionType.MIX_SOME:
            for(let type in value){
                values.push(processingType(type,value[type]))
            }
            return values.some(v=>{
                return v;
            })
        default:
            return false;
    }
}
//業(yè)務(wù)狀態(tài)判斷
function permissionBusinessStatus(bindingValue){
   return bindingValue.status==bindingValue.value;
}
//當(dāng)前用戶?
function permissionCreater(bindingValue){
    const userInfo = JSON.parse(sessionStorage.CDTPcookie);
    // console.log(userInfo.userInfo.id,bindingValue)
    if(bindingValue instanceof Array){
        return bindingValue.some(v=>{
            return userInfo.userInfo.id==v;
        })
    }
    return userInfo.userInfo.id==bindingValue;
}
//角色控制
export function permissionByRole(bindingValue) {
    //這里也可以是store里的用戶信息
    const userInfo = JSON.parse(sessionStorage.userInfo);  
    let roles = []
    if (userInfo) {
        roles = userInfo.roleList
    }
    let show = false;
    if (bindingValue instanceof Array) {
        return roles.some(role => {//多角色處理
            return bindingValue.some(item => {
                return role.roleCode === item
            })
        })
    } else if (typeof bindingValue == 'string') {
        show = roles.some(role => {
            return role.roleCode === bindingValue;
        })
    }
    return show;
}

簡(jiǎn)單說一下上面??指令的定義思路和使用方法。整體思路就是通過processingType處理權(quán)限邏輯,使用el.style.display控制組件顯示或隱藏。我在這里從日常應(yīng)用中提取了一些通用的processingType中的權(quán)限處理方式,方便大家理解也供大家參考。

下面逐一說一下權(quán)限指令各個(gè)類型的使用方法:

//角色權(quán)限
<component v-permission:role='leader'></component>
//判斷當(dāng)前登錄人
<component v-permission:currentUser='orderInfo.createUser'></component>
//判斷業(yè)務(wù)狀態(tài)
<component v-permission:bussinessStatus='{status:orderStatus.RUNNING,value:orderInfo.status}'></component>
//角色是leader或者是當(dāng)前訂單的創(chuàng)建者,有權(quán)限
<component v-permission:some="{role:'leader',currentUser:'orderInfo.createUser'}"></component>
//角色是leader并且是當(dāng)前訂單的創(chuàng)建者,有權(quán)限
<component v-permission:every="{role:'leader',currentUser:'orderInfo.createUser'}"></component>

輸入限制

v-input 輸入框限制,限制數(shù)字、保留n位小數(shù)點(diǎn)等。

export default {
    inserted: function (el, binding, vnode) {
        el.addEventListener('input', function (e) {
            if (binding.arg == 'toFixed') {
                //限制輸入n位小數(shù)點(diǎn)
                toFiexd(e.target, vnode, binding.value)
            } else {
                //限制數(shù)字輸入
                Integer(e.target, vnode)
            }
        })
    },
}
function toFiexd(target, vnode, v) {
    console.log(v);
    let ln = 2;
    if (v) {
        ln = v;
    }
    var regStrs = [
        ['^0(\\d+)$', '$1'], //禁止錄入整數(shù)部分兩位以上,但首位為0
        ['[^\\d\\.]+$', ''], //禁止錄入任何非數(shù)字和點(diǎn)
        ['\\.(\\d?)\\.+', '.$1'], //禁止錄入兩個(gè)以上的點(diǎn)
        ['^(\\d+\\.\\d{' + ln + '}).+', '$1'] //禁止錄入小數(shù)點(diǎn)后兩位以上
    ];
    for (var i = 0; i < regStrs.length; i++) {
        var reg = new RegExp(regStrs[i][0]);
        target.value = target.value.replace(reg, regStrs[i][1]);
    }
    //對(duì)于封裝的像el-input組件,因?yàn)槠湫枰ㄟ^input事件同步狀態(tài)
    if(vnode.componentInstance){
      vnode.componentInstance.$listeners.input(target.value)
    }
}
function Integer(target, vnode) {
    let valueStr = target.value
    if (valueStr.length == 1) {
        //第一個(gè)數(shù)字不為0
        valueStr = valueStr.replace(/[^0-9]/g, "");
    } else {
        //只能輸入正整數(shù)
        valueStr = valueStr.replace(/\D/g, "");
    }
    target.value = valueStr;
    if(vnode.componentInstance){
      vnode.componentInstance.$listeners.input(target.value)
    }
}

這里需要特別注意的是下面這行代碼

vnode.componentInstance.$listeners.input(target.value)

我們?yōu)槭裁葱枰砑舆@一句呢,我們明明已經(jīng)為target.value做了賦值。

實(shí)際上這一句代碼相當(dāng)于指令作用組件內(nèi)部的$emit('input',target.value),這是因?yàn)槿绻覀兪窃赼ntd或者elementui中的輸入框組件上添加我們定義的v-input指令,直接為target.value賦值是不能生效的,修改的只是原生input控件value值,并沒有修改自定義組件的value,還需要通過觸發(fā)input事件去同步組件狀態(tài),修改value值。(這里不了解為什么需要觸發(fā)input事件區(qū)同步狀態(tài)的同學(xué)了解一下v-model的語法糖原理即可理解,

使用方法:

<!-- 限制輸入兩位小數(shù)數(shù)字 -->
<input v-input:toFixed="2"/>
<!-- 限制輸入正整數(shù) -->
<el-input v-input:integer/>

內(nèi)容處理

我們也可以通過自定義指令做對(duì)內(nèi)容到處理,比如

  • 空值處理
  • 數(shù)字千分?jǐn)?shù)逗號(hào)分割
export default {
    bind:function(){
    },
    inserted:function(el,binding){
        dealContent(el,binding)
    },
    update:function(el,binding){
        dealContent(el,binding)
    },
    componentUpdated:function(){
    },
    unbind:function(){
    },
}
function dealContent(el,binding){
   const {arg}=binding;
   if(arg=='empty'){
       if(!el.textContent){//空值顯示
            el.textContent=binding.value||'暫無數(shù)據(jù)';
        }
   }else if(arg=='money'){//金額千分位逗號(hào)分割,如10000000顯示為100,000,00
        if (binding.value) {
            el.textContent = dealMoney(binding.value);
        }else {
            el.textContent = dealMoney(el.textContent);
        }
   }
}

千分位分割代碼:

//金額處理
export function dealMoney(money, places = 2) {
    const zero = `0.00`;
    if (isNaN(money) || money === '') return zero;
    if (money && money != null) {
        money = `${money}`;
        let left = money.split('.')[0]; // 小數(shù)點(diǎn)左邊部分
        let right = money.split('.')[1]; // 小數(shù)點(diǎn)右邊
        // 保留places位小數(shù)點(diǎn),當(dāng)長(zhǎng)度沒有到places時(shí),用0補(bǔ)足。
        right = right ? (right.length >= places ? '.' + right.substr(0, places) : '.' + right + '0'.repeat(places - right.length)) : ('.' + '0'.repeat(places));
        var temp = left.split('').reverse().join('').match(/(\d{1,3})/g); // 分割反向轉(zhuǎn)為字符串然后最多3個(gè),最少1個(gè),將匹配的值放進(jìn)數(shù)組返回
        return (Number(money) < 0 ? '-' : '') + temp.join(',').split('').reverse().join('') + right; // 補(bǔ)齊正負(fù)號(hào)和貨幣符號(hào),數(shù)組轉(zhuǎn)為字符串,通過逗號(hào)分隔,再分割(包含逗號(hào)也分割)反向轉(zhuǎn)為字符串變回原來的順序
    } else if (money === 0) {
        return zero;
    } else {
        return zero;
    }
}

使用方法:

<span v-content:empty="'無'">{{message}}</span>
<!-- 金額千分位逗號(hào)分割 -->
<span v-content:money>100000</span>

文件預(yù)覽

v-preview方便的實(shí)現(xiàn)文件預(yù)覽功能

  • 預(yù)覽圖片;
  • 預(yù)覽文件;
  • 其他預(yù)覽類業(yè)務(wù)功能
import {isOffic,isPdf,isImage} from '@/utils/base'
import {previewWithOffice} from '@/utils/fileUtils.js'
export default {
    inserted:function(el,binding){
        el.onclick=function(e){
            let params = binding.value
            if(isOffic(params.name)){
                e.preventDefault()
                e.stopPropagation()
                previewWithOffice(params.url)//使用office在線預(yù)覽打開
            }else if(isPdf(params.name) || isImage(params.name)){
                e.preventDefault()
                e.stopPropagation()
                if(params.url){//直接打開url
                    previewFile(params)
                }
            }
        }
    },
    //指令所在組件的 VNode 及其子 VNode 全部更新后
    componentUpdated: function (el, binding) {
        el.onclick=function(e){
            let params = binding.value
            if(isOffic(params.name)){
                //使用插件預(yù)覽Office文件
                e.preventDefault()
                e.stopPropagation()
                previewWithOffice(params.url)
            }else if(isPdf(params.name) || isImage(params.name)){
               //預(yù)覽圖片和pdf等能直接打開的文件
                e.preventDefault()
                e.stopPropagation()
                previewFile(params)
            }
        }
    },
    unbind(el){
       el.onclick=null;
    }
}
//預(yù)覽圖片和pdf等能直接打開的文件
function previewFile(params) {
    let a = document.createElement("a");
    a.download = params.name
    a.href = params.url;
    a.target = "_blank";
    a.click();
    a = null;
}

使用方法:

<!-- 預(yù)覽圖片 -->
<image :src='url' v-preview="{name:file.name,url:file.url}"></image>
<!-- 預(yù)覽文件 -->
<span v-preview="{name:file.name,url:file.url}">{{file.name}}</span>

試著自己實(shí)現(xiàn)

各位同學(xué)可以試著自己實(shí)現(xiàn)一個(gè)v-loading的加載中的指令,通過設(shè)置一個(gè)bool值來設(shè)置容器的加載狀態(tài)。

如有疑問可以在評(píng)論區(qū)留言。

總結(jié)

本文主要講了如下幾件事:

  • vue自定義指令介紹
  • 實(shí)現(xiàn)一個(gè)v-model
  • 通用的自定義指令使用技巧

以上就是一文帶你完全掌握Vue自定義指令的詳細(xì)內(nèi)容,更多關(guān)于Vue自定義指令的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue使用$set和$delete操作對(duì)象屬性

    Vue使用$set和$delete操作對(duì)象屬性

    這篇文章介紹了Vue使用$set和$delete操作對(duì)象屬性的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • vue3項(xiàng)目打包與上線詳細(xì)圖文教程

    vue3項(xiàng)目打包與上線詳細(xì)圖文教程

    這篇文章主要給大家介紹了關(guān)于vue3項(xiàng)目打包與上線的相關(guān)資料,在項(xiàng)目完成得差不多得時(shí)候,就可以開始打包部署了,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 解決vue的 v-for 循環(huán)中圖片加載路徑問題

    解決vue的 v-for 循環(huán)中圖片加載路徑問題

    今天小編就為大家分享一篇解決vue的 v-for 循環(huán)中圖片加載路徑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 解決vue項(xiàng)目中出現(xiàn)Invalid Host header的問題

    解決vue項(xiàng)目中出現(xiàn)Invalid Host header的問題

    這篇文章主要介紹了解決vue項(xiàng)目中出現(xiàn)"Invalid Host header"的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • vite打包出現(xiàn)?"default"?is?not?exported?by?"node_modules/...問題解決辦法

    vite打包出現(xiàn)?"default"?is?not?exported?by?"

    這篇文章主要給大家介紹了關(guān)于vite打包出現(xiàn)?"default"?is?not?exported?by?"node_modules/...問題的解決辦法,文中通過代碼將解決的辦法介紹的非常詳細(xì),對(duì)同樣遇到這個(gè)問題的朋友具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-06-06
  • 詳解Vue3中響應(yīng)式的特殊處理

    詳解Vue3中響應(yīng)式的特殊處理

    這篇文章主要為大家詳細(xì)介紹了Vue3中響應(yīng)式的一些特殊處理,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Vue3有一定的幫助,需要的可以參考一下
    2023-04-04
  • 基于vue+uniapp直播項(xiàng)目實(shí)現(xiàn)uni-app仿抖音/陌陌直播室功能

    基于vue+uniapp直播項(xiàng)目實(shí)現(xiàn)uni-app仿抖音/陌陌直播室功能

    uni-liveShow是一個(gè)基于vue+uni-app技術(shù)開發(fā)的集小視頻/IM聊天/直播等功能于一體的微直播項(xiàng)目。本文通過實(shí)例圖文的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2019-11-11
  • vue實(shí)現(xiàn)實(shí)時(shí)搜索顯示功能

    vue實(shí)現(xiàn)實(shí)時(shí)搜索顯示功能

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)實(shí)時(shí)搜索顯示功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue3獲取元素并且修改元素樣式的實(shí)戰(zhàn)操作

    vue3獲取元素并且修改元素樣式的實(shí)戰(zhàn)操作

    ref作為在vue里面我們獲取元素最常用的一個(gè)api,在vue3迎來改造,下面這篇文章主要給大家介紹了關(guān)于vue3獲取元素并且修改元素樣式的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • 為Vue3?組件標(biāo)注?TS?類型實(shí)例詳解

    為Vue3?組件標(biāo)注?TS?類型實(shí)例詳解

    這篇文章主要為大家介紹了為Vue3?組件標(biāo)注?TS?類型實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論