日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue中waiting for update signal from wds_10个vue快捷开发技巧助你成为中级前端工程师!(二)...

發(fā)布時間:2023/12/10 vue 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue中waiting for update signal from wds_10个vue快捷开发技巧助你成为中级前端工程师!(二)... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

先贊再看,養(yǎng)成習(xí)慣~

優(yōu)雅更新props


更新 prop 在業(yè)務(wù)中是很常見的需求,但在子組件中不允許直接修改 prop,因為這種做法不符合單向數(shù)據(jù)流的原則,在開發(fā)模式下還會報出警告。因此大多數(shù)人會通過 $emit 觸發(fā)自定義事件,在父組件中接收該事件的傳值來更新 prop。


child.vue:

export defalut {props: {title: String },methods: {changeTitle(){this.$emit('change-title', 'hello')}} }

parent.vue:

<child :title="title" @change-title="changeTitle"></child> export default {data(){return {title: 'title'} },methods: {changeTitle(title){this.title = title}} }

這種做法沒有問題,我也常用這種手段來更新 prop。但如果你只是想單純的更新 prop,沒有其他的操作。那么 sync 修飾符能夠讓這一切都變得特別簡單。

parent.vue:

<child :title.sync="title"></child>

child.vue:

export defalut {props: {title: String },methods: {changeTitle(){this.$emit('update:title', 'hello')}} }

只需要在綁定屬性上添加 .sync,在子組件內(nèi)部就可以觸發(fā) update:屬性名 來更新 prop。可以看到這種手段確實簡潔且優(yōu)雅,這讓父組件的代碼中減少一個“沒必要的函數(shù)”。
參考文檔

在學(xué)習(xí)web前端的過程中,往往因為沒有資料或者沒人指導(dǎo)從而導(dǎo)致自己不想學(xué),因此我特意準(zhǔn)備了個qun,整理了一份最全面前端學(xué)習(xí)資料,從最基礎(chǔ)的HTML+CSS+JS 到移動端HTML5的項目實戰(zhàn)的學(xué)習(xí)資料都有整理,想學(xué)習(xí)的都可以申請加入

前端開發(fā)?jq.qq.com

送給每一位前端小伙伴, 有想學(xué)習(xí)web前端的,或是轉(zhuǎn)行,或是大學(xué)生,還有工作中想提升自己能力的,正在學(xué)習(xí)的小伙伴歡迎加入學(xué)習(xí)。


provide/inject


這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在其上下游關(guān)系成立的時間里始終生效。
簡單來說,一個組件將自己的屬性通過 provide 暴露出去,其下面的子孫組件 inject 即可接收到暴露的屬性。


App.vue:

export default {provide() {return {app: this}} }

這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在其上下游關(guān)系成立的時間里始終生效。
簡單來說,一個組件將自己的屬性通過 provide 暴露出去,其下面的子孫組件 inject 即可接收到暴露的屬性。


App.vue:

export default {provide() {return {app: this}} }

在 2.5.0+ 版本可以通過設(shè)置默認(rèn)值使其變成可選項:

export default {inject: {app: {default: () => ({})}},created() {console.log(this.app) } }

如果你想為inject的屬性變更名稱,可以使用from來表示其來源:.

export default {inject: {myApp: {// from的值和provide的屬性名保持一致from: 'app',default: () => ({})}},created() {console.log(this.myApp) } }

需要注意的是 provide 和 inject 主要在開發(fā)高階插件/組件庫時使用。并不推薦用于普通應(yīng)用程序代碼中。但是某些時候,或許它能幫助到我們。
參考文檔


小型狀態(tài)管理器


大型項目中的數(shù)據(jù)狀態(tài)會比較復(fù)雜,一般都會使用 vuex 來管理。但在一些小型項目或狀態(tài)簡單的項目中,為了管理幾個狀態(tài)而引入一個庫,顯得有些笨重。


在 2.6.0+ 版本中,新增的 Vue.observable 可以幫助我們解決這個尷尬的問題,它能讓一個對象變成響應(yīng)式數(shù)據(jù):

// store.js import Vue from 'vue'export const state = Vue.observable({ count: 0 })

使用:

<div @click="setCount">{{ count }}</div> import {state} from '../store.js'export default {computed: {count() {return state.count}},methods: {setCount() {state.count++}} }

當(dāng)然你也可以自定義mutation來復(fù)用更改狀態(tài)的方法:

import Vue from 'vue'export const state = Vue.observable({ count: 0 })export const mutations = {SET_COUNT(payload) {if (payload > 0) {state.count = payload} } }

使用:

import {state, mutations} from '../store.js'export default {computed: {count() {return state.count}},methods: {setCount() {mutations.SET_COUNT(100)}} }

參考文檔

卸載watch觀察

通常定義數(shù)據(jù)觀察,會使用選項的方式在 watch 中配置:

export default {data() {return {count: 1 }},watch: {count(newVal) {console.log('count 新值:'+newVal)}} }

除此之外,數(shù)據(jù)觀察還有另一種函數(shù)式定義的方式:

export default {data() {return {count: 1 }},created() {this.$watch('count', function(){console.log('count 新值:'+newVal)})} }

它和前者的作用一樣,但這種方式使定義數(shù)據(jù)觀察更靈活,而且$watch會返回一個取消觀察函數(shù),用來停止觸發(fā)回調(diào):

let unwatchFn = this.$watch('count', function(){console.log('count 新值:'+newVal) }) this.count = 2 // log: count 新值:2 unwatchFn() this.count = 3 // 什么都沒有發(fā)生...

$watch第三個參數(shù)接收一個配置選項:

this.$watch('count', function(){console.log('count 新值:'+newVal) }, {immediate: true // 立即執(zhí)行watch })

參考文檔

巧用template

相信 v-if 在開發(fā)中是用得最多的指令,那么你一定遇到過這樣的場景,多個元素需要切換,而且切換條件都一樣,一般都會使用一個元素包裹起來,在這個元素上做切換。

<div v-if="status==='ok'"><h1>Title</h1><p>Paragraph 1</p><p>Paragraph 2</p> </div>

如果像上面的 div 只是為了切換條件而存在,還導(dǎo)致元素層級嵌套多一層,那么它沒有“存在的意義”。


我們都知道在聲明頁面模板時,所有元素需要放在 <template> 元素內(nèi)。除此之外,它還能在模板內(nèi)使用,<template> 元素作為不可見的包裹元素,只是在運行時做處理,最終的渲染結(jié)果并不包含它。

<template><div><template v-if="status==='ok'"><h1>Title</h1><p>Paragraph 1</p><p>Paragraph 2</p></template></div> </template>

同樣的,我們也可以在<template>上使用v-for指令,這種方式還能解決v-for和v-if同時使用報出的警告問題。

<template v-for="item in 10"><div v-if="item % 2 == 0" :key="item">{{item}}</div> </template>

template使用v-if, template使用v-for

過濾器復(fù)用

過濾器被用于一些常見的文本格式化,被添加在表達(dá)式的尾部,由“管道”符號指示。

<div>{{ text | capitalize }}</div> export default {data() {return {text: 'hello'} },filters: {capitalize: function (value) {if (!value) return ''value = value.toString()return value.charAt(0).toUpperCase() + value.slice(1)}} }

試想一個場景,不僅模板內(nèi)用到這個函數(shù),在 method 里也需要同樣功能的函數(shù)。但過濾器無法通過 this 直接引用,難道要在 methods 再定義一個同樣的函數(shù)嗎?
要知道,選項配置都會被存儲在實例的 $options 中,所以只需要獲取 this.$options.filters 就可以拿到實例中的過濾器。

export default {methods: {getDetail() {this.$api.getDetail({id: this.id}).then(res => {let capitalize = this.$options.filters.capitalizethis.title = capitalize(res.data.title)})}} }

除了能獲取到實例的過濾器外,還能獲取到全局的過濾器,因為 this.$options.filters 會順著 __proto__ 向上查找,全局過濾器就存在原型中。
自定義指令獲取實例
有的情況下,當(dāng)需要對普通 DOM 元素進(jìn)行底層操作,這時候就會用到自定義指令。像是項目中常用的權(quán)限指令,它能精確到某個模塊節(jié)點。大概思路為獲取權(quán)限列表,如果當(dāng)前綁定權(quán)限不在列表中,則刪除該節(jié)點元素。

Vue.directive('role', {inserted: function (el, binding, vnode) {let role = binding.valueif(role){const applist = sessionStorage.getItem("applist")const hasPermission = role.some(item => applist.includes(item)) // 是否擁有權(quán)限if(!hasPermission){el.remove() //沒有權(quán)限則刪除模塊節(jié)點}}} })

自定義指令鉤子函數(shù)共接收3個參數(shù),包括 el (綁定指令的真實dom)、binding (指令相關(guān)信息)、vnode (節(jié)點的虛擬dom)。


假設(shè)現(xiàn)在業(yè)務(wù)發(fā)生變化,applist 存儲在 vuex 里, 但指令內(nèi)想要使用實例上的屬性,或者是原型上的 $store。我們是沒有辦法獲取到的,因為鉤子函數(shù)內(nèi)并沒有直接提供實例訪問。vnode 作為當(dāng)前的虛擬dom,它里面可是綁定到實例上下文的,這時候訪問 vnode.context 就可以輕松解決問題。

Vue.directive('role', {inserted: function (el, binding, vnode) {let role = binding.valueif(role){// vnode.context 為當(dāng)前實例const applist = vnode.context.$store.state.applistconst hasPermission = role.some(item => applist.includes(item)) if(!hasPermission){el.remove()}}} })

優(yōu)雅注冊插件


插件通常用來為 Vue 添加全局功能。像常用的 vue-router、vuex 在使用時都是通過 Vue.use 來注冊的。Vue.use 內(nèi)部會自動尋找 install 方法進(jìn)行調(diào)用,接受的第一個參數(shù)是 Vue 構(gòu)造函數(shù)。

一般在使用組件庫時,為了減小包體積,都是采用按需加載的方式。如果在入口文件內(nèi)逐個引入組件會讓 main.js 越來越龐大,基于模塊化開發(fā)的思想,最好是單獨封裝到一個配置文件中。配合上 Vue.use,在入口文件使用能讓人一目了然。


vant.config.js:

import {Toast,Button } from 'vant'const components = {Toast,Button }const componentsHandler = {install(Vue){Object.keys(components).forEach(key => Vue.use(components[key]))} }export default componentsHandler

main.js:

import Vue from 'vue' import vantCompoents from '@/config/vant.config'Vue.config.productionTip = falseVue.use(vantCompoents)new Vue({render: h => h(App) }).$mount('#app')

參考文檔


自動化引入模塊


在開發(fā)中大型項目時,會將一個大功能拆分成一個個小功能,除了能便于模塊的復(fù)用,也讓模塊條理清晰,后期項目更好維護(hù)。


像 api 文件一般按功能劃分模塊,在組合時可以使用 require.context 一次引入文件夾所有的模塊文件,而不需要逐個模塊文件去引入。每當(dāng)新增模塊文件時,就只需要關(guān)注邏輯的編寫和模塊暴露,require.context 會幫助我們自動引入。


需要注意 require.context 并不是天生的,而是由 webpack 提供。在構(gòu)建時,webpack 在代碼中解析它。

let importAll = require.context('./modules', false, /.js$/)class Api extends Request{constructor(){super()//importAll.keys()為模塊路徑數(shù)組importAll.keys().map(path =>{//兼容處理:.default獲取ES6規(guī)范暴露的內(nèi)容; 后者獲取commonJS規(guī)范暴露的內(nèi)容let api = importAll(path).default || importAll(path)Object.keys(api).forEach(key => this[key] = api[key])})} }export default new Api()

require.context 參數(shù):

  • 文件夾路徑
  • 是否遞歸查找子文件夾下的模塊
  • 模塊匹配規(guī)則,一般匹配文件后綴名
  • 只要是需要批量引入的場景,都可以使用這種方法。包括一些公用的全局組件,只需往文件夾內(nèi)新增組件即可使用,不需要再去注冊。如果還沒用上的小伙伴,一定要了解下,簡單實用又能提高效率。
    參考文檔


    路由懶加載(動態(tài)chunkName)


    路由懶加載作為性能優(yōu)化的一種手段,它能讓路由組件延遲加載。通常我們還會為延遲加載的路由添加“魔法注釋”(webpackChunkName)來自定義包名,在打包時,該路由組件會被單獨打包出來。

    let router = new Router({routes: [{path:'/login',name:'login',component: import(/* webpackChunkName: "login" */ `@/views/login.vue`)},{path:'/index',name:'index',component: import(/* webpackChunkName: "index" */ `@/views/index.vue`)},{path:'/detail',name:'detail',component: import(/* webpackChunkName: "detail" */ `@/views/detail.vue`)}] })

    上面這種寫法沒問題,但仔細(xì)一看它們結(jié)構(gòu)都是相似的,作為一名出色的開發(fā)者,我們可以使用map循環(huán)來解決這種重復(fù)性的工作。

    const routeOptions = [{path:'/login',name:'login',},{path:'/index',name:'index',},{path:'/detail',name:'detail',}, ]const routes = routeOptions.map(route => {if (!route.component) {route = {...route,component: () => import(`@/views/${route.name}.vue`)}}return route })let router = new Router({routes })

    在書寫更少代碼的同時,我們也把“魔法注釋”給犧牲掉了。總所周知,代碼中沒辦法編寫動態(tài)注釋。這個問題很尷尬,難道就沒有兩全其美的辦法了嗎?


    強大的 webpack 來救場了,從 webpack 2.6.0 開始,占位符 [index] 和 [request] 被支持為遞增的數(shù)字或?qū)嶋H解析的文件名。我們可以這樣使用“魔法注釋”:

    const routes = routeOptions.map(route => {if (!route.component) {route = {...route,component: () => import(/* webpackChunkName: "[request]" */ `@/views/${route.name}.vue`)}}return route })

    參考文檔, 參考文章

    最后

    往期相關(guān)文章:

    我很酷:前端20個真正靈魂拷問,吃透這些你就是中級前端工程師!?zhuanlan.zhihu.com我很酷:10個vue快捷開發(fā)技巧助你成為中級前端工程師!?zhuanlan.zhihu.com

    喜歡本文的還請點個star~有想學(xué)習(xí)web前端的,或是轉(zhuǎn)行,或是大學(xué)生,還有工作中想提升自己能力的,正在學(xué)習(xí)的小伙伴歡迎加入我的前端開發(fā)群學(xué)習(xí)。

    前端開發(fā)?jq.qq.com原文鏈接:https://juejin.im/post/5f179100f265da22e27a9833

    總結(jié)

    以上是生活随笔為你收集整理的vue中waiting for update signal from wds_10个vue快捷开发技巧助你成为中级前端工程师!(二)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。