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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Vue自定义指令原来这么简单

發布時間:2023/12/13 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue自定义指令原来这么简单 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇學習目標

  • 能夠了解組件進階知識
  • 能夠掌握自定義指令創建和使用
  • 能夠完成tabbar案例的開發
  • 1. 組件進階

    1.0 組件進階 - 動態組件

    目標: 多個組件使用同一個掛載點,并動態切換,這就是動態組件

    需求: 完成一個注冊功能頁面, 2個按鈕切換, 一個填寫注冊信息, 一個填寫用戶簡介信息

    效果如下:

  • 準備被切換的 - UserName.vue / UserInfo.vue 2個組件

  • 引入到UseDynamic.vue注冊

  • 準備變量來承載要顯示的"組件名"

  • 設置掛載點, 使用is屬性來設置要顯示哪個組件

  • 點擊按鈕 – 修改comName變量里的"組件名"

  • <template><div><button @click="comName = 'UserName'">賬號密碼填寫</button><button @click="comName = 'UserInfo'">個人信息填寫</button><p>下面顯示注冊組件-動態切換:</p><div style="border: 1px solid red;"><component :is="comName"></component></div></div> </template><script> // 目標: 動態組件 - 切換組件顯示 // 場景: 同一個掛載點要切換 不同組件 顯示 // 1. 創建要被切換的組件 - 標簽+樣式 // 2. 引入到要展示的vue文件內, 注冊 // 3. 變量-承載要顯示的組件名 // 4. 設置掛載點<component :is="變量"></component> // 5. 點擊按鈕-切換comName的值為要顯示的組件名import UserName from '../components/01/UserName' import UserInfo from '../components/01/UserInfo' export default {data(){return {comName: "UserName"}},components: {UserName,UserInfo} } </script>

    在App.vue - 引入01_UseDynamic.vue并使用顯示

    總結: vue內置component組件, 配合is屬性, 設置要顯示的組件名字

    1.1 組件進階 - 組件緩存

    目標: 組件切換會導致組件被頻繁銷毀和重新創建, 性能不高

    使用Vue內置的keep-alive組件, 可以讓包裹的組件保存在內存中不被銷毀

    演示1: 可以先給UserName.vue和UserInfo.vue 注冊created和destroyed生命周期事件, 觀察創建和銷毀過程

    演示2: 使用keep-alive內置的vue組件, 讓動態組件緩存而不是銷毀

    語法:

    ? Vue內置的keep-alive組件 包起來要頻繁切換的組件

    02_UseDynamic.vue

    <div style="border: 1px solid red;"><!-- Vue內置keep-alive組件, 把包起來的組件緩存起來 --><keep-alive><component :is="comName"></component></keep-alive> </div>

    補充生命周期:

    • activated - 激活
    • deactivated - 失去激活狀態

    總結: keep-alive可以提高組件的性能, 內部包裹的標簽不會被銷毀和重新創建, 觸發激活和非激活的生命周期方法

    1.2 組件進階 - 激活和非激活

    目標: 被緩存的組件不再創建和銷毀, 而是激活和非激活

    補充2個鉤子方法名:

    ? activated – 激活時觸發

    ? deactivated – 失去激活狀態觸發

    1.3 組件進階 - 組件插槽

    目標: 用于實現組件的內容分發, 通過 slot 標簽, 可以接收到寫在組件標簽內的內容

    vue提供組件插槽能力, 允許開發者在封裝組件時,把不確定的部分定義為插槽

    插槽例子:

    需求: 以前折疊面板案例, 想要實現不同內容顯示, 我們把折疊面板里的Pannel組件, 添加組件插槽方式

    語法口訣:

  • 組件內用占位
  • 使用組件時夾著的地方, 傳入標簽替換slot
  • 03/Pannel.vue - 組件(直接復制)

    <template><div><!-- 按鈕標題 --><div class="title"><h4>芙蓉樓送辛漸</h4><span class="btn" @click="isShow = !isShow">{{ isShow ? "收起" : "展開" }}</span></div><!-- 下拉內容 --><div class="container" v-show="isShow"><p>寒雨連江夜入吳,</p><p>平明送客楚山孤。</p><p>洛陽親友如相問,</p><p>一片冰心在玉壺。</p></div></div> </template><script> export default {data() {return {isShow: false,};}, }; </script><style scoped> h3 {text-align: center; }.title {display: flex;justify-content: space-between;align-items: center;border: 1px solid #ccc;padding: 0 1em; }.title h4 {line-height: 2;margin: 0; }.container {border: 1px solid #ccc;padding: 0 1em; }.btn {/* 鼠標改成手的形狀 */cursor: pointer; }img {width: 50%; } </style>

    views/03_UserSlot.vue - 使用組件(直接復制)

    框: 在這個基礎重復使用組件

    <template><div id="container"><div id="app"><h3>案例:折疊面板</h3></div></div> </template><script> export default { }; </script><style> #app {width: 400px;margin: 20px auto;background-color: #fff;border: 4px solid blueviolet;border-radius: 1em;box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);padding: 1em 2em 2em; } </style>

    views/03_UseSlot.vue - 組件插槽使用

    <template><div id="container"><div id="app"><h3>案例:折疊面板</h3><Pannel><img src="../assets/mm.gif" alt=""><span>我是內容</span></Pannel><Pannel><p>寒雨連江夜入吳,</p><p>平明送客楚山孤。</p><p>洛陽親友如相問,</p><p>一片冰心在玉壺。</p></Pannel><Pannel></Pannel></div></div> </template><script> import Pannel from "../components/03/Pannel"; export default {components: {Pannel,}, }; </script>

    總結: 組件內容分發技術, slot占位, 使用組件時傳入替換slot位置的標簽

    1.4 組件進階 - 插槽默認內容

    目標: 如果外面不給傳, 想給個默認顯示內容

    口訣: 夾著內容默認顯示內容, 如果不給插槽slot傳東西, 則使用夾著的內容在原地顯示

    <slot>默認內容</slot>

    1.5 組件進階 - 具名插槽

    目標: 當一個組件內有2處以上需要外部傳入標簽的地方

    傳入的標簽可以分別派發給不同的slot位置

    要求: v-slot一般用跟template標簽使用 (template是html5新出標簽內容模板元素, 不會渲染到頁面上, 一般被vue解析內部標簽)

    components/04/Pannel.vue - 留下具名slot

    <template><div><!-- 按鈕標題 --><div class="title"><slot name="title"></slot><span class="btn" @click="isShow = !isShow">{{ isShow ? "收起" : "展開" }}</span></div><!-- 下拉內容 --><div class="container" v-show="isShow"><slot name="content"></slot></div></div> </template>

    views/04_UseSlot.vue使用

    <template><div id="container"><div id="app"><h3>案例:折疊面板</h3><Pannel><template v-slot:title><h4>芙蓉樓送辛漸</h4></template><template v-slot:content><img src="../assets/mm.gif" alt=""><span>我是內容</span></template></Pannel><Pannel><template #title><span style="color: red;">我是標題</span></template><template #content><p>寒雨連江夜入吳,</p><p>平明送客楚山孤。</p><p>洛陽親友如相問,</p><p>一片冰心在玉壺。</p></template></Pannel></div></div> </template><script> import Pannel from "../components/04/Pannel"; export default {components: {Pannel,}, }; </script>

    v-slot可以簡化成#使用

    v-bind可以省略成: v-on: 可以省略成@ 那么v-slot: 可以簡化成#

    總結: slot的name屬性起插槽名, 使用組件時, template配合#插槽名傳入具體標簽

    1.6 組件進階 - 作用域插槽

    目標: 子組件里值, 在給插槽賦值時在父組件環境下使用

    復習: 插槽內slot中顯示默認內容

    例子: 默認內容在子組件中, 但是父親在給插槽傳值, 想要改變插槽顯示的默認內容

    口訣:

  • 子組件, 在slot上綁定屬性和子組件內的值
  • 使用組件, 傳入自定義標簽, 用template和v-slot=“自定義變量名”
  • scope變量名自動綁定slot上所有屬性和值
  • components/05/Pannel.vue - 定義組件, 和具名插槽, 給slot綁定屬性和值

    <template><div><!-- 按鈕標題 --><div class="title"><h4>芙蓉樓送辛漸</h4><span class="btn" @click="isShow = !isShow">{{ isShow ? "收起" : "展開" }}</span></div><!-- 下拉內容 --><div class="container" v-show="isShow"><slot :row="defaultObj">{{ defaultObj.defaultOne }}</slot></div></div> </template><script> // 目標: 作用域插槽 // 場景: 使用插槽, 使用組件內的變量 // 1. slot標簽, 自定義屬性和內變量關聯 // 2. 使用組件, template配合v-slot="變量名" // 變量名會收集slot身上屬性和值形成對象 export default {data() {return {isShow: false,defaultObj: {defaultOne: "無名氏",defaultTwo: "小傳同學"}};}, }; </script>

    views/05_UseSlot.vue

    <template><div id="container"><div id="app"><h3>案例:折疊面板</h3><Pannel><!-- 需求: 插槽時, 使用組件內變量 --><!-- scope變量: {row: defaultObj} --><template v-slot="scope"><p>{{ scope.row.defaultTwo }}</p></template></Pannel></div></div> </template><script> import Pannel from "../components/05/Pannel"; export default {components: {Pannel,}, }; </script>

    總結: 組件內變量綁定在slot上, 然后使用組件v-slot=“變量” 變量上就會綁定slot身上屬性和值

    1.7 組件進階 - 作用域插槽使用場景

    目標: 了解作用域插槽使用場景, 自定義組件內標簽+內容

    案例: 封裝一個表格組件, 在表格組件內循環產生單元格

    準備MyTable.vue組件 – 內置表格, 傳入數組循環鋪設頁面, 把對象每個內容顯示在單元格里

    準備UseTable.vue – 準備數據傳入給MyTable.vue使用

    components/06/MyTable.vue - 模板(直接復制)

    <template><div><table border="1"><thead><tr><th>序號</th><th>姓名</th><th>年齡</th><th>頭像</th></tr></thead><thead><tr><td></td><td></td><td></td><td></td></tr></thead></table></div> </template><script> export default {} </script>

    views/06_UseTable.vue - 準備數據, 傳入給MyTable.vue組件里循環使用

    list: [{name: "小傳同學",age: 18,headImgUrl:"http://yun.itheima.com/Upload/./Images/20210303/603f2d2153241.jpg",},{name: "小黑同學",age: 25,headImgUrl:"http://yun.itheima.com/Upload/./Images/20210304/6040b101a18ef.jpg",},{name: "智慧同學",age: 21,headImgUrl:"http://yun.itheima.com/Upload/./Images/20210302/603e0142e535f.jpg",}, ],

    例子: 我想要給td內顯示圖片, 需要傳入自定義的img標簽

    正確做法:

    ? 在MyTable.vue的td中準備占位, 但是外面需要把圖片地址賦予給src屬性,所以在slot上把obj數據綁定

    components/06/MyTable.vue - 正確代碼

    <template><div><table border="1"><thead><tr><th>序號</th><th>姓名</th><th>年齡</th><th>頭像</th></tr></thead><tbody><tr v-for="(obj, index) in arr" :key="index"><td>{{ index + 1 }}</td><td>{{ obj.name }}</td><td>{{ obj.age }}</td><td><slot :row="obj"><!-- 默認值給上,如果使用組件不自定義標簽顯示默認文字 -->{{ obj.headImgUrl}}</slot></td></tr></tbody></table></div> </template><script> export default {props: {arr: Array} } </script>

    ? 在UseTable使用MyTable的時候, template上v-slot綁定變量, 傳入img組件設置圖片地址

    <template><div><MyTable :arr="list"></MyTable><MyTable :arr="list"><!-- scope: {row: obj} --><template v-slot="scope"><a :href="scope.row.headImgUrl">{{ scope.row.headImgUrl }}</a></template></MyTable><MyTable :arr="list"><template v-slot="scope"><img style="width: 100px;" :src="scope.row.headImgUrl" alt=""></template></MyTable></div> </template><script> import MyTable from "../components/06/MyTable"; export default {components: {MyTable,},data() {return {list: [{name: "小傳同學",age: 18,headImgUrl:"http://yun.itheima.com/Upload/./Images/20210303/603f2d2153241.jpg",},{name: "小黑同學",age: 25,headImgUrl:"http://yun.itheima.com/Upload/./Images/20210304/6040b101a18ef.jpg",},{name: "智慧同學",age: 21,headImgUrl:"http://yun.itheima.com/Upload/./Images/20210302/603e0142e535f.jpg",},],};}, }; </script><style> </style>

    總結: 插槽可以自定義標簽, 作用域插槽可以把組件內的值取出來自定義內容

    2. 自定義指令

    自定義指令文檔

    除了核心功能默認內置的指令 (v-model 和 v-show),Vue 也允許注冊自定義指令。 v-xxx

    html+css的復用的主要形式是組件

    你需要對普通 DOM 元素進行底層操作,這時候就會用到自定義指令

    2.0 自定義指令-注冊

    目標: 獲取標簽, 擴展額外的功能

    局部注冊和使用

    07_UseDirective.vue - 只能在當前組件.vue文件中使用

    <template><div><!-- <input type="text" v-gfocus> --><input type="text" v-focus></div> </template><script> // 目標: 創建 "自定義指令", 讓輸入框自動聚焦 // 1. 創建自定義指令 // 全局 / 局部 // 2. 在標簽上使用自定義指令 v-指令名 // 注意: // inserted方法 - 指令所在標簽, 被插入到網頁上觸發(一次) // update方法 - 指令對應數據/標簽更新時, 此方法執行 export default {data(){return {colorStr: 'red'}},directives: {focus: {inserted(el){el.focus()}}} } </script><style></style>

    全局注冊

    在main.js用 Vue.directive()方法來進行注冊, 以后隨便哪個.vue文件里都可以直接用v-fofo指令

    // 全局指令 - 到處"直接"使用 Vue.directive("gfocus", {inserted(el) {el.focus() // 觸發標簽的事件方法} })

    總結: 全局注冊自定義指令, 哪里都能用, 局部注冊, 只能在當前vue文件里用

    2.1 自定義指令-傳值

    目標: 使用自定義指令, 傳入一個值

    需求: 定義color指令-傳入一個顏色, 給標簽設置文字顏色

    main.js定義處修改一下

    // 目標: 自定義指令傳值 Vue.directive('color', {inserted(el, binding) {el.style.color = binding.value},update(el, binding) {el.style.color = binding.value} })

    Direct.vue處更改一下

    <p v-color="colorStr" @click="changeColor">修改文字顏色</p><script>data() {return {theColor: "red",};},methods: {changeColor() {this.theColor = 'blue';},}, </script>

    總結: v-xxx, 自定義指令, 獲取原生DOM, 自定義操作

    3. 案例-tabbar

    完成如下案例和各步功能

    知識點:

    • 組件封裝
    • 動態組件
    • keep-alive
    • 作用域插槽
    • 自定義指令

    3.0 案例-tabbar-初始化項目

    目標: 創建項目文件夾, 引入字體圖標, 下載bootstrap, less, less-loader@5.0.0 axios, 在App.vue注冊組件

    • 需求: 從0新建項目, 拆分組件, 創建使用

    組件分析:

    • 組件拆分:

      • MyHeader.vue – 復用之前的
      • MyTabBar.vue – 底部導航
      • MyTable.vue – 封裝表格
    • 三個頁面

      • -MyGoodsList.vue – 商品頁
      • MyGoodsSearch.vue – 搜索頁
      • -MyUserInfo.vue – 用戶信息頁

    思路分析:

    ? ①: vue create tabbar-demo

    ? ②: yarn add less less-loader@5.0.0 -D

    ? ③: yarn add bootstrap axios 并在main.js 引入和全局屬性

    ? ④: 根據需求-創建需要的頁面組件

    ? ⑤: 把昨天購物車案例-封裝的MyHeader.vue文件復制過來復用

    ? ⑥: 從App.vue – 引入組織相關標簽

    新建工程:

    vue create tabbar-demo yarn add less less-loader@5.0.0 -D yarn add bootstrap axios

    在main.js中引入bootStrap.css和字體圖標樣式

    import "bootstrap/dist/css/bootstrap.css" import "./assets/fonts/iconfont.css"

    創建/復制如下文件

    從昨天案例中-直接復制過來components/MyHeader.vue

    components/MyTabBar.vue

    views/MyGoodsList.vue

    views/MyGoodsSearch.vue

    views/MyUserInfo.vue

    components/MyTable.vue

    3.1 案例-tabbar-底部封裝

    目標: 實現MyTabBar.vue組件

    • 需求: 把底部導航也靈活封裝起來

    分析:

    ? ①: 基本標簽+樣式(md里復制)

    ? ②: 為tabbar組件指定數據源

    ? ③: 數據源最少2個, 最多5個(validator)

    ? ④: 從App.vue給MyTabBar.vue傳入底部導航的數據

    ? ⑤: MyTabBar.vue中循環展示

    App.vue-數組準備

    tabList: [{iconText: "icon-shangpinliebiao",text: "商品列表",componentName: "MyGoodsList"},{iconText: "icon-sousuo",text: "商品搜索",componentName: "MyGoodsSearch"},{iconText: "icon-user",text: "我的信息",componentName: "MyUserInfo"} ]

    MyTabBar.vue - 標簽模板

    <template><div class="my-tab-bar"><div class="tab-item"><!-- 圖標 --><span class="iconfont"></span><!-- 文字 --><span></span></div></div> </template><script> export default {} </script><style lang="less" scoped> .my-tab-bar {position: fixed;left: 0;bottom: 0;width: 100%;height: 50px;border-top: 1px solid #ccc;display: flex;justify-content: space-around;align-items: center;background-color: white;.tab-item {display: flex;flex-direction: column;align-items: center;} }.current {color: #1d7bff; } </style>

    MyTabBar.vue正確代碼(不可復制)

    <template><div class="my-tab-bar"><divclass="tab-item"v-for="(obj, index) in arr":key="index"><!-- 圖標 --><span class="iconfont" :class="obj.iconText"></span><!-- 文字 --><span>{{ obj.text }}</span></div></div> </template><script> export default {props: {arr: {type: Array,required: true,// 自定義校驗規則validator(value) {// value就是接到數組if (value.length >= 2 && value.length <= 5) {return true; // 符合條件就return true} else {console.error("數據源必須在2-5項");return false;}},},} }; </script>

    不要忘了把tabList數組從App.vue -> MyTabBar.vue

    3.2 案例-tabbar-底部高亮

    目標: 點擊底部導航實現高亮效果

    • 需求: 點擊底部實現高亮效果

    分析:

    ? ①: 綁定點擊事件, 獲取點擊的索引

    ? ②: 循環的標簽設置動態class, 遍歷的索引, 和點擊保存的索引比較, 相同則高亮

    效果演示:

    MyTabBar.vue(正確代碼)

    <template><div class="my-tab-bar"><div class="tab-item" v-for="(obj, index) in arr" :key="index":class="{current: activeIndex === index}"@click="activeIndex = index"><!-- 圖標 --><span class="iconfont" :class="obj.iconText"></span><!-- 文字 --><span>{{ obj.text }}</span></div></div> </template><script> export default {data(){return {activeIndex: 0 // 高亮元素下標}},// ....其他代碼 }; </script>

    3.3 案例-tabbar-組件切換

    目的: 點擊底部導航, 切換頁面組件顯示

    需求: 點擊底部切換組件

    分析:

    ? ①: 底部導航傳出動態組件名字符串到App.vue

    ? ②: 切換動態組件is屬性的值為要顯示的組件名

    效果演示:

    補充: 給內容div.app- 設置上下內邊距

    App.vue - 引入并注冊

    <template><div><MyHeader:background="'blue'":fontColor="'white'"title="TabBar案例"></MyHeader><div class="main"><component :is="comName"></component></div><MyTabBar :arr="tabList"@changeCom="changeComFn"></MyTabBar></div> </template><script> import MyHeader from "./components/MyHeader"; // 目標: 完成底部封裝 // 1. MyTabBar.vue 組件標簽+樣式 準備 // 2. 字體圖標引入 // 3. 準備底部數據 // 4. 使用MyTabBar組件, 傳入數據(父->子), 循環產生底部導航 // 5. 子組件內props自定義檢驗規則(2-5項) // 6. 子組件內循環產生底部導航 import MyTabBar from './components/MyTabBar'// 目標: 切換組件顯示 // 1. 創建組件 - 編寫內容 // 2. 引入App.vue注冊 // 3. 掛載點設置is // 4. 切換comName的值(重要) // 5. 底部導航點擊- MyTabBar.vue里 // 子 -> 父技術 (傳要切換的組件名出來)import MyGoodsList from './views/MyGoodsList' import MyGoodsSearch from './views/MyGoodsSearch' import MyUserInfo from './views/MyUserInfo' export default {data() {return {comName: "MyGoodsList", // 默認顯示的組件tabList: [ // 底部導航的數據{iconText: "icon-shangpinliebiao",text: "商品列表",componentName: "MyGoodsList",},{iconText: "icon-sousuo",text: "商品搜索",componentName: "MyGoodsSearch",},{iconText: "icon-user",text: "我的信息",componentName: "MyUserInfo",},],};},components: {MyHeader,MyTabBar,MyGoodsList,MyGoodsSearch,MyUserInfo},methods: {changeComFn(cName){this.comName = cName; // MyTabBar里選出來的組件名賦予給is屬性的comName// 導致組件的切換}} }; </script><style scoped> .main{padding-top: 45px;padding-bottom: 51px; } </style>

    MyTabBar.vue - 點擊傳遞過來組件名

    methods: {btn(index, theObj) {this.selIndex = index; // 點誰, 就把誰的索引值保存起來this.$emit("changeCom", theObj.componentName); // 要切換的組件名傳App.vue},},

    3.4 案例-tabbar-商品列表

    目標: 為MyGoodsList頁面, 準備表格組件MyTable.vue-鋪設展示數據

    • 需求: 商品列表鋪設頁面

    分析:

    ? ①: 封裝MyTable.vue – 準備標簽和樣式

    ? ②: axios在MyGoodsList.vue請求數據回來

    ? ③: 請求地址: https://www.escook.cn/api/goods

    ? ④: 傳入MyTable.vue中循環數據顯示

    ? ⑤: 給刪除按鈕添加bootstrap的樣式: btn btn-danger btn-sm

    效果演示:

    MyTable.vue - 準備table整個表格標簽和樣式(可復制)

    <template><table class="table table-bordered table-stripped"><!-- 表格標題區域 --><thead><tr><th>#</th><th>商品名稱</th><th>價格</th><th>標簽</th><th>操作</th></tr></thead><!-- 表格主體區域 --><tbody><tr ><td>1</td><td>商品</td><td>998</td><td>xxx</td><td>xxx</td></tr></tbody></table> </template><script> export default {name: 'MyTable' } </script><style scoped lang="less"> .my-goods-list {.badge {margin-right: 5px;} } </style>

    使用axios請求數據, 把表格頁面鋪設出來

    main.js - 注冊axios配置默認地址

    import axios from "axios"; axios.defaults.baseURL = "https://www.escook.cn";

    MyGoodsList.vue - 使用axios請求數據, 把數據傳入給MyTable.vue里循環鋪設

    <template><div><MyTable :arr="list"></MyTable></div> </template><script> import MyTable from "../components/MyTable"; import axios from "axios"; axios.defaults.baseURL = "https://www.escook.cn"; // 目標: 循環商品列表表格 // 1. 封裝MyTable.vue 整體表格組件-一套標簽和樣式 // 2. axios請求數據 // 3. 傳入MyTable組件里循環tr顯示數據// 目標: 展示tags標簽 // 1. tags數組 - 某個td循環span使用文字 // 2. span設置bs的樣式// 目標: 刪除數據 // 1. 刪除按鈕 - 點擊事件 // 2. 作用域插槽把索引值關聯出來了 // scope身上就有row和index // 3. 刪除中使用scope.index的索引值 // 4. 刪除事件里刪除數組里對應索引值的數據 export default {components: {MyTable,},data() {return {list: [] // 所有數據};},created() {axios({url: "/api/goods",}).then((res) => {console.log(res);this.list = res.data.data;});} }; </script>

    MyTable.vue里正確代碼(不可復制)

    <template><table class="table table-bordered table-stripped"><!-- 表格標題區域 --><thead><tr><th>#</th><th>商品名稱</th><th>價格</th><th>標簽</th><th>操作</th></tr></thead><!-- 表格主體區域 --><tbody><tr v-for="(obj, index) in arr":key="obj.id"><td>{{ obj.id }}</td><td>{{ obj.goods_name }}</td><td>{{ obj.goods_price }}</td><td>{{ obj.tags }}</td><td><button class="btn btn-danger btn-sm">刪除</button></td></tr></tbody></table> </template><script> export default {name: 'MyTable',props: {arr: Array} } </script><style scoped lang="less"> .my-goods-list {.badge {margin-right: 5px;} } </style>

    3.5_案例-tabbar-商品表格-插槽

    目標: 使用插槽技術, 和作用域插槽技術, 給MyTable.vue組件, 自定義列標題, 自定義表格內容

    • 需求: 允許用戶自定義表格頭和表格單元格內容

    分析:

    ? ①: 把MyTable.vue里準備slot

    ? ②: 使用MyTable組件時傳入具體標簽

    步驟:

  • 提高組件復用性和靈活性, 把表格列標題thead部分預留標簽, 設置name屬性
  • 使用MyTable.vue時, 傳入列標題標簽
  • 表格內容td部分也可以讓組件使用者自定義, 也給tbody下tr內留好標簽和name屬性名
  • 使用插槽需要用到插槽內的obj對象上的數據, 使用作用域插槽技術
  • MyTable.vue - 留好具名插槽

    <template><table class="table table-bordered table-stripped"><!-- 表格標題區域 --><thead><tr><!-- <th>#</th><th>商品名稱</th><th>價格</th><th>標簽</th><th>操作</th> --><slot name="header"></slot></tr></thead><!-- 表格主體區域 --><tbody><tr v-for="(obj, index) in arr":key="obj.id"><!-- <td>{{ obj.id }}</td><td>{{ obj.goods_name }}</td><td>{{ obj.goods_price }}</td><td>{{ obj.tags }}</td><td><button class="btn btn-danger btn-sm">刪除</button></td> --><slot name="body" :row="obj" :index="index"></slot></tr></tbody></table> </template><script> export default {name: 'MyTable',props: {arr: Array} } </script>

    MyGoodsList.vue 使用

    <template><div><MyTable :arr="list"><template #header><th>#</th><th>商品名稱</th><th>價格</th><th>標簽</th><th>操作</th></template><!-- scope的值: {row: obj, index: 索引值} --><template #body="scope"><td>{{ scope.row.id }}</td><td>{{ scope.row.goods_name }}</td><td>{{ scope.row.goods_price }}</td><td>{{ scope.row.tags }}</td><td><button class="btn btn-danger btn-sm">刪除</button></td></template></MyTable></div> </template><script> import MyTable from "../components/MyTable"; import axios from "axios"; axios.defaults.baseURL = "https://www.escook.cn"; // 目標: 循環商品列表表格 // 1. 封裝MyTable.vue 整體表格組件-一套標簽和樣式 // 2. axios請求數據 // 3. 傳入MyTable組件里循環tr顯示數據// 目標: 展示tags標簽 // 1. tags數組 - 某個td循環span使用文字 // 2. span設置bs的樣式// 目標: 刪除數據 // 1. 刪除按鈕 - 點擊事件 // 2. 作用域插槽把索引值關聯出來了 // scope身上就有row和index // 3. 刪除中使用scope.index的索引值 // 4. 刪除事件里刪除數組里對應索引值的數據 export default {components: {MyTable,},data() {return {list: [] // 所有數據};},created() {axios({url: "/api/goods",}).then((res) => {console.log(res);this.list = res.data.data;});} }; </script><style> </style>

    3.6 案例-tabbar-商品表格-tags微標

    目標: 把單元格里的標簽, tags徽章鋪設下

    • 需求: 標簽列自定義顯示

    分析:

    ? ①: 插槽里傳入的td單元格

    ? ②: 自定義span標簽的循環展示-給予樣式

    效果演示:

    bootstrap徽章: https://v4.bootcss.com/docs/components/badge/

    MyGoodsList.vue - 插槽

    <span v-for="(str, ind) in scope.row.tags" :key="ind"class="badge badge-warning">{{ str }} </span>

    下面額外添加樣式

    <style lang="less" scoped> .my-goods-list {.badge {margin-right: 5px;} } </style>

    3.7 案例-tabbar-商品表格-刪除功能

    目標: 點擊刪除對應這條數據

    • 需求: 點擊刪除按鈕刪除數據

    分析:

    ? ①: 刪除按鈕綁定點擊事件

    ? ②: 作用域插槽綁定id值出來

    ? ③: 傳給刪除方法, 刪除MyGoodsList.vue里數組里數據

    效果演示

    提示: id在MyTable.vue里, 但是MyGoodsList.vue里要使用, 而且在插槽位置, 使用作用域插槽已經把整個obj對象(包含id)帶出來了

    MyTable.vue

    <slot name="body" :row="obj"></slot>
  • MyGoodsList.vue - 注冊點擊事件
  • <button class="btn btn-danger btn-sm"@click="removeBtn(scope.row.id)">刪除</button>

    ? 2. my-goods-list.vue 根據 id 刪除

    removeBtn(id){let index = this.list.findIndex(obj => obj.id === id)this.list.splice(index, 1) },

    3.8 案例-tabbar-添加tab

    目標: 實現點擊tab按鈕, 出現輸入框自動獲取焦點, 失去焦點關閉input, 回車新增tag, esc清空內容

    • 需求1: 點擊Tab, 按鈕消失, 輸入框出現
    • 需求2: 輸入框自動聚焦
    • 需求3: 失去焦點, 輸入框消失, 按鈕出
    • 需求4: 監測input回車, 無數據攔截
    • 需求5: 監測input取消, 清空數據
    • 需求6: 監測input回車, 有數據添加

    效果目標:

    3.8.0 點擊按鈕消失, 輸入框出現

    MyGoodsList.vue - 標簽位置添加

    注意: 每個tab按鈕和input都是獨立變量控制, 那么直接在row身上的屬性控制即可

    <inputclass="tag-input form-control"style="width: 100px;"type="text"v-if="scope.row.inputVisible"/><button v-else style="display: block;" class="btn btn-primary btn-sm add-tag"@click="scope.row.inputVisible = true">+Tag</button>

    3.8.1 input自動獲取焦點

    main.js - 定義全局自定義指令

    // 全局指令 Vue.directive("focus", {inserted(el){el.focus()} })

    MyGoodsList.vue - 使用 v-focus指令

    3.8.2 input失去焦點關閉input

    監聽input失去焦點事件, 讓input消失

    @blur="scope.row.inputVisible = false"

    3.8.3 input回車新增tag

    監聽input的回車事件, 如果無數據攔截代碼

    @keydown.enter="enterFn(scope.row)"

    事件處理函數

    enterFn(obj){ // 回車// console.log(obj.inputValue);if (obj.inputValue.trim().length === 0) {alert('請輸入數據')return}obj.tags.push(obj.inputValue) // 表單里的字符串狀態tags數組obj.inputValue = "" }

    3.8.4 input框esc清空內容

    @keydown.esc="scope.row.inputValue = ''"

    今日總結

  • 動態組件的使用步驟
  • 組件緩存使用步驟和作用
  • 組件插槽默認使用
  • 插槽默認顯示的內容
  • 多個插槽時, 具名插槽如何使用
  • 作用域插槽如何使用以及目的
  • 自定義命令如何使用
  • 跟隨視頻完成tabbar案例
  • 面試題

    1. vue中solt的使用方式,以及solt作用域插槽的用法

    使用方式:當組件當做標簽進行使用的時候,用slot可以用來接受組件標簽包裹的內容,當給solt標簽添加name屬性的 時候,可以調換響應的位置
    (高級用法) 插槽作用域: 當傳遞的不是單一的標簽, 例如需要循環時, 把要循環的標簽傳入, 組件內使用v-for在slot標簽上, 內部可以v-bind:把值傳出來, 再外面把值賦予進去, 看示例

    <current-user><template v-slot:default="slotProps">{{ slotProps.user.firstName }}</template> </current-user>// current-user組件, user屬性和值, 綁定給slotProps上 <span><slot v-bind:user="user">{{ user.lastName }}</slot> </span>

    擴展閱讀: https://cn.vuejs.org/v2/guide/components-slots.html (了解即可, 一般用不上)

    2. 跟keep-alive有關的生命周期是哪些?(必會)

    ? 1**)前言:**在開發Vue項目的時候,大部分組件是沒必要多次渲染的,所以Vue提供了一個內置組件keep-alive來緩存組件內部狀態,避免重新渲染,在開發Vue項目的時候,大部分組件是沒必要多次渲染的,所以Vue提供了一個內置組件keep-alive來緩存組件內部狀態,避免重新渲染

    ? 2**)生命周期函數:**在被keep-alive包含的組件/路由中,會多出兩個生命周期的鉤子:activated 與 deactivated。

    ? 1**、activated鉤子:**在在組件第一次渲染時會被調用,之后在每次緩存組件被激活時調用。

    ? 2**、Activated鉤子調用時機:** 第一次進入緩存路由/組件,在mounted后面,beforeRouteEnter守衛傳給 next 的回調函數之前調用,并且給因為組件被緩存了,再次進入緩存路由、組件時,不會觸發這些鉤子函數,beforeCreate created beforeMount mounted 都不會觸發

    ? 1**、deactivated鉤子:**組件被停用(離開路由)時調用。

    ? 2**、deactivated鉤子調用時機**:使用keep-alive就不會調用beforeDestroy(組件銷毀前鉤子)和destroyed(組件銷毀),因為組件沒被銷毀,被緩存起來了,這個鉤子可以看作beforeDestroy的替代,如果你緩存了組件,要在組件銷毀的的時候做一些事情,可以放在這個鉤子里,組件內的離開當前路由鉤子beforeRouteLeave => 路由前置守衛 beforeEach =>全局后置鉤子afterEach => deactivated 離開緩存組件 => activated 進入緩存組件(如果你進入的也是緩存路由)

    3. 自定義指令(v-check、v-focus)的方法有哪些?它有哪些鉤子函數?還有哪些鉤子函數參數?(必會)

    ? 全局定義指令:在vue對象的directive方法里面有兩個參數,一個是指令名稱,另外一個是函數。組件內定義指令:directives

    ? 鉤子函數:bind(綁定事件觸發)、inserted(節點插入的時候觸發)、update(組件內相關更新)

    ? 鉤子函數參數:el、binding

    4. is這個特性你有用過嗎?主要用在哪些方面?(高薪常問)

    ? 1**)動態組件**

    ? , componentName可以是在本頁面已經注冊的局部組件名和全局組件名,也可以是一個組件的選項對象。 當控制componentName改變時就可以動態切換選擇組件。

    ? 2**)is的用法**

    ? 有些HTML元素,諸如 <ul><ol><table><select>,對于哪些元素可以出現在其內部是有嚴格限制的。? 而有些HTML元素,諸如 <li><tr><option>,只能出現在其它某些特定的元素內部。 ? <ul>? <card-list></card-list>? </ul>

    ? 所以上面會被作為無效的內容提升到外部,并導致最終渲染結果出錯。應該這么寫:

    ? <ul>? <li is="cardList"></li>? </ul>

    總結

    以上是生活随笔為你收集整理的Vue自定义指令原来这么简单的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。