【Vue】vue專案目錄介紹 es6的匯入匯出語法 vue專案開發規範 Vue專案編寫步驟

2023-02-20 21:01:34

昨日回顧

# 1 計算屬性
	-屬性放在data設定項中,方法放在methods中
    -computed:{
        方法名(){}
    }
    -把它當屬性用,快取:只有當該計算屬性使用的變數發生變化時,它才重新運算
    
   
# 2 重寫過濾案例
    - 通過計算屬性,重寫過濾案例
    	-newDataList做成計算屬性,v-for直接回圈它
        -newDataList使用的變數只要發生變化,它就會重新運算,使用了mytext,只要input輸入內容,它就會重新運算,不需要加事件了
        
# 3 監聽屬性
	- data中定義的屬性,可以使用watch繫結一個方法,以後只要這個屬性發生變化,就會觸發方法的執行
    - watch:{
        page(){
            
        }
    }
    
# 4 元件:有自己的html,css,js,以後相用,直接註冊使用即可
	-全域性,區域性
    -var child={template:``,data(){return {}},methods:{}}
	-元件中註冊:components:{child}
    
# 5 元件間通訊-元件間資料,方法都是隔離的
	-父傳子:自定義屬性
        <child :myname='lqz'></child>
        -在子元件中:props:['myname']
        
    -子傳父:自定義事件
    	-子元件中某種情況下把子元件的資料傳給父元件
        <child @myevnet='handleClick'></child>
        -點選事件函數內部:this.$emit('自定義事件名字',name)
        
        
    -ref屬性:
    	-放在普通標籤上: this.$refs.標籤上的名字  原生dom物件
        -放在元件上:this.$refs.元件上的名字       元件物件  它有變數,方法
    
 # 6 動態元件
	-不確定顯示的元件是什麼,動態變化的
    <component :is='變數'></component>
    -<keep-alive></keep-alive>
    
# 7 插槽
	-寫了元件,元件內部,空一個位置 <slot></slot>
    -<child >   <div></div>  </child>
    
    -預設插槽
    -具名插槽:挖多個坑,給每個坑命個名
    <slot name="b"></slot>
    
    
    <child >   <div slot="b"></div>  </child>
    <child >   <div v-slot:b></div>  </child>
    
# 8 vue-cli 
	-對比djagno,建立djagno專案需要怎麼做?
    	-裝python直譯器,安裝模組django,django-admin建立專案
    
    -nodejs,安裝模組vue-cli
    	-npm install @vue/cli -g
        -vue 可執行檔案
        -vue create專案名
        	-bable
            -vuex
            -vue-router
            
    -編輯器選擇
    	-jetbrains公司:Pycharm,goland,phpstorm,IDEA,webstorm
    		-pycharm+vue外掛  開發前端
        -vscode:微軟出的,輕量級,免費
		-eclipse my eclipse
        -谷歌買了jetbrains授權, AndroidStadio
        -sublime Text
        -vim+外掛
    
    -vue專案執行的兩種方式
    	-命令列中執行:npm run serve
        -pycharm的綠色箭頭執行
        
   # 9 學過的設定項
	- el(template)
    - data :組建中 方法
    - methods
    - 8個生命週期勾點
    - components  
    - watch
    - computed 
    

今日內容

0 vue-cli建立專案

node.js環境

# 前端做成專案----》使用工具(vue-cli),建立出vue專案,單頁面應用(spa),元件化開發,  把 xx.vue,ts,saas,less-----》編譯---》在瀏覽器中執行


# vue-cli建立專案開發,在專案中開發,最後上線,一定要編譯--->純粹的html,js,css

# 瀏覽器只能識別 js  html  css

# vue-cli 工具,使用nodejs寫的,要執行,需要node環境

# 下載node直譯器
	-一路下一步 
    -環境變數:可執行檔案路徑  就在環境變數
    -兩個可執行檔案:
    	-node:    python
        -npm:     pip

# nodejs 怎麼來的
	-js只能執行在瀏覽器中,因為瀏覽器中有它的直譯器環境
    -基於谷歌瀏覽器的v8引擎,使它可以執行在作業系統之上   網路包,檔案,資料庫。。。 用c寫的
    	-js語法 完成後端的編寫,全棧
    -號稱效能高,大量使用協程

# 檔案防篡改校驗
	-把檔案生成md5值
    -以後被下載下來,再生成md5值肯定是一樣,如果不一樣說明被篡改了,不能用了
    
    -1 百度網路硬碟 
    	-秒傳   
        	-傳到伺服器上---》生成md5---》存著
            -本地生成md5---》傳送到伺服器端---》一查----》有---》不傳了
            
        - 遮蔽
        

    -2 王小云 破解md5 
        		

        
        
# 直譯語言和編譯型語言
	-js,node,php,python    直譯語言   執行直譯器之上   pyinstaller
    -c,go,c++               編譯型語言   直接把原始碼編譯成不同平臺的可執行檔案
    	-cpython直譯器用c寫的----》編譯成不同平臺的可執行檔案---》在不同平臺雙擊執行即可
        	-win
            -mac
            -linux
    -java:一處編碼處處執行
    	-java 虛擬機器器 ---》虛擬機器器跨平臺
        -java位元組碼檔案執行在虛擬機器器之上
        -java寫了程式碼----》編譯成位元組(區別與可執行檔案  jar,war,.class)
 

建立vue-cli專案

# 建立vue專案使用什麼?
	-2.x 使用vue-cli :https://cli.vuejs.org/zh/
    -3.x 使用vue-cli
    -vite只能建立vue3 效率非常高

    
 # 按裝vue-cli
	npm install -g @vue/cli  
    # 使用cnpm替換npm    cnpm淘寶出的工具,下載的時候,去淘寶映象下載,速度快
    # -g 表示裝全域性
    #--registry=https://registry.npm.taobao.org 指定淘寶映象
    npm install -g cnpm --registry=https://registry.npm.taobao.org
        
    # 以後使用cnpm 代替npm
    
    cnpm install -g @vue/cli
    
    # cmd控制檯就可以輸入 vue 命令(裝了djagno可以使用django-admin建立django專案)
    	-vue 建立vue專案
    
# 使用vue-cli建立專案(找個目錄)
	vue create myfirstvue   # 速度很慢,等,可以ctrl+c停止 執行npm cache clean --force
    # 很慢的原因
    	-從github拉一個空專案
        -按照該專案所有的依賴,npm裝
    # 按下圖操作
    
    
    vue ui # 使用圖形化介面建立專案 ,自己點選即可

1 vue專案目錄介紹

myfirstvue                    # 專案名字
    node_modules              # 資料夾,內部有很多當前專案依賴的模組,可以刪除,npm install
    public                    # 資料夾
        -favicon.ico           # 網站小圖示
        -index.html            # spa:單頁面應用  
    src                       # 以後咱們寫程式碼,都在這下面
    	-assets                # 靜態資源,js,css,圖片  類似於static資料夾
    		logo.png          # 靜態資源的圖片
    	-components           # 元件:小元件,用在別的大(頁面元件)元件中
    		-HelloWorld.vue   # 預設了一個hello world元件
    	-router                    # 裝了vue-router自動生成的,如果不裝就沒有
    		index.js              # vue-router的設定
    	-store                # 裝了vuex自動生成的,如果不裝就沒有
    		index.js          # vuex的設定
    	-views                # 放了一堆元件,頁面元件
            AboutView.vue     # 關於 頁面元件
            HomeView.vue      # 主頁  頁面元件
    	-App.vue              # 根元件
    	-main.js              # 整個專案啟動入口
    .gitignore                # git的忽略檔案 不用動
    babel.config.js           # babel的設定 不用動
    jsconfig.json             # 組態檔 不用動
    package.json              # 重要:類似於python專案的requirements.txt  當前專案所有依賴
    package-lock.json         # 鎖定檔案:package.json中寫了依賴的版本,這個檔案鎖定所有版本
    README.md                 # 讀我,專案的介紹
    vue.config.js             # vue專案的組態檔

node_modules

# node_modules是個資料夾,內部有很多當前專案依賴的模組(第三方模組)
# 沒有node_modules專案不能執行
# 傳送給別人的時候需要刪除【上傳git要忽略掉】,刪除了使用cnpm install可以重新安裝回來

比如建立python專案時,如果勾選了虛擬環境,會建立一個venv資料夾:

這個venv資料夾,放置了一個python直譯器的環境,如果你再下了第三方依賴,是安裝在這個venv資料夾下的python環境的。好處是,每一個專案都不會互相影響。相當於每一個python專案都有一個自己的直譯器。

而這個node_modules也是類似的效果,存放了很多專案的第三方依賴模組。node_modules是可以刪除的(這個檔案比較大),如果你要提交到倉庫、傳送給別人,需要把它刪除掉。但是你把node_modules刪除掉了,專案就無法啟動了(缺乏第三方依賴)。但是可以使用npm install命令,該命令會根據package.json檔案給你重新裝上這些依賴。

補充:webpack是程式碼編譯的工具 ---> 編譯成只有html、js、css

index.html

  public                    # 資料夾
        -favicon.ico           # 網站小圖示
        -index.html            # spa:單頁面應用 
        -assets                # 靜態資源,js,css,圖片  類似於static資料夾

現在我們寫的專案只有一個index.html頁面。

所有元件都在這個div內部切換,也就實現首頁、登入頁面、註冊頁面切換。這個div很重要,不要在這個標籤內寫東西。

通過<%= BASE_URL %>可以找到在public資料夾下的小圖示。

網站名字是在package.json裡面定義的:

noscript:

如果你的網站禁用了js:

就會顯示上面的提示語句:

app.vue

# app.vue是根元件

根元件的內容會直接替換到index.html頁面下的這個div內。

package.json

# package.json當前專案的依賴項

如果刪除,npm install就不知道裝什麼了。

package-lock.json

package.json寫了一些專案依賴的版本。

這些依賴的版本新增了上箭頭^,這表示安裝時會裝3版本里最新的3.6.2。但是總是安裝最新的版本,可能會出現版本不相容問題。

lock檔案可以對版本進行鎖定:

以後安裝就按照這個鎖定版本進行安裝,而不是按照package.json檔案安裝,這樣不會出現問題。所以我們也不要動這個lock檔案。

總結:以後經常用的就兩個views (寫頁面),components(寫元件)。

2 es6的匯入匯出語法

# node.js中如果要匯入,必須先匯出
	-預設匯出
    -命名匯出
    
# python建立包,只需要在其他py檔案中匯入
    
# 預設匯出寫法
	
    # 語法
    -匯出語法
    	export default 一般是個物件
    -匯入語法
    	import 別名  from '路徑'
        以後 別名   就是 匯出的物件
    
    # 範例
    1.在js檔案中定義變數,函數,最後使用export defalut匯出
    export default {
        name: '彭于晏',
        printName () {
            console.log(this.name)
        }
    }
    2 在想使用的js中,匯入
    import 隨便起 from './lqz/utils'
    
    
# 命名匯出和匯入
	-匯出語法  可以匯出多個
    export const name = '劉亦菲'
    export const printName = () => {
        console.log('星象銜新寵')
    }
    -匯入語法
    import {printName} from './lqz/utils'
    
    
# 在包下可以建立一個名為index.js 的檔案,以後匯入的時候,會預設找它
	-對比python中得__init__.py

main.js檔案介紹

# 找到index.html 中的id為app的div,以後都在App.vue中寫
new Vue({
  render: h => h(App)
}).$mount('#app')

main.js是專案的入口,程式執行的時候是從這裡開始執行的:

解釋main.js的程式碼含義:

Vue提供了一些開發過程中的提示,通過如上設定項可以選擇是否需要開啟這些提示。

這裡等同於el:'#app',但這是如何做到的呢?

$mount這裡就是去public/index.html掛載了那個id='app'的div。
注意public、index這兩個名字必須是固定的。

render後面對應的是一個箭頭函數,傳入了一個h,返回一個h(app)。
而這個app是匯入進來的:

也就是匯入了App.vue下的內容:

匯入這個app之後,用h(app)執行了一下,進行了掛載。

本質是在App.vue中寫的程式碼,會原封不動的插入到index.html內的div:

在utils.js內寫程式碼:

我們想在main.js中引入utils.js檔案,並使用其中的變數和函數,那麼應該怎麼做?

需要先在util.js匯出,別的檔案才能匯入,這一點和python不一樣:

預設匯出

預設匯出用的最多,只能匯出一次。

這相當於匯出了一個物件。(還可以使用es6的語法將其簡寫)
只有在export default匯出的,在別的檔案才能匯入。

使用預設匯出,沒有給匯出的物件取一個名字。
關於預設匯出,我們可以這樣匯入:

main.js匯入了之後這個xxx,xxx就是之前匯出的物件:

儘量使用包名作為匯入物件的名字:

執行專案:

f沒有匯出所以會報錯。

預設匯出的其他寫法:

這裡的this指代當前物件,this.name='彭于晏'

命名匯出

使用命名匯出,name相當於一個變數:

在main.js匯入:
使用命名匯出時,匯入的時候可以匯入多個名字。

注意:同一個需要匯出的檔案中,預設匯出和命名匯出不能混用。

index檔案的特殊含義

將我們需要匯入的包中的檔案改名為index.js:

這樣匯入的時候就可以直接導包了(如果包下檔名不是index不能這樣做):

這個index.js就類似於python中的__init__。(導包的時候會自動執行__init__檔案)

3 vue專案開發規範

# 以後寫的元件,都是單頁面元件  也就是xx.vue檔案 

# 以後寫一個元件就是一個xx.vue  xx.vue --分為-> 頁面元件和小元件

# 以後一個元件就是一個xx.vue檔案,xx.vue檔案內部都有三部分
	-<template></template>  # html內容寫在裡面
    	-並且必須套在一個div標籤裡
    -<script></script>      # 寫js內容
    -<style></style>        # 寫css樣式
    
# main.js 是整個專案的入口
1 把App.vue根元件匯入了
2 使用new Vue({render: h => h(App)}).$mount('#app') 把App.vue元件中得資料和模板,插入到了index.html的id為app的div中了
3 以後,只要在每個元件的export default {} 寫之前學過的所有js的東西
4 以後,只要在每個元件的template,寫模板,插值語法,指令...
5 以後,只要在每個元件的style,寫樣式...

Vue專案編寫步驟

# 1 以後只需要寫xx.vue   
	-頁面元件
    -小元件   給頁面元件用的
    
# 2 元件中匯出
	export default {
          name: 'HelloWorld',
          data() {
            return {
              xx: '彭于晏'
            }
          },
	}

# 3 在別的元件中要用,匯入,註冊
	# 匯入
	import HelloWorld from '../components/HelloWorld.vue'
    # 註冊
    export default {
      components: {
        HelloWorld 
      }
    }
 # 4 註冊以後,在這個元件中就可以使用匯入的元件 ,寫在<template>
	# 自定義屬性
	<HelloWorld msg="傳進來的p"/>

檢視HomeView.vue(頁面元件):

檢視HelloWorld.vue(小元件):

注意這裡匯出都需要使用預設匯出,匯出一個物件,在其他頁面直接使用這個物件進行註冊。

正常情況下,想要使用區域性元件,需要在設定項components寫元件相關資訊:

但是,我們可以通過匯入的方式,把HelloWorld(子)中的元件到HomeView(父)中註冊:

元件註冊成功之後,就可以在HomeView使用了:

子元件的msg屬性,是通過父元件標籤裡寫的自定義屬性傳過來的:

main.js匯入根元件

main.js匯入了App.vue根元件:

根元件中也需要有template、script、style三種標籤。如果根元件中沒有script標籤,會導致掛載時沒有資料,只有一個template設定項。

在根元件script標籤內寫匯出的內容:

不用給匯出的物件寫template屬性,這裡會自動將上面template標籤的內容掛載到這個物件上。

根元件的內容會通過new Vue({render: h => h(App)}).$mount('#app')這行程式碼,最終掛載到index.html的div標籤內。

以後開發元件,只需要在template標籤內寫就可以了:

跟之前的寫法一樣,只是換了寫程式碼的位置。

4 vue專案整合axios、vue專案前後端打通

# 安裝axios
	-npm install axios -S
    
# 匯入使用
<script>
	import axios from 'axios'
</script>	

# 傳送請求,獲取資料
    axios.get('http://127.0.0.1:8000/books/').then(res => {
      console.log(res.data)
      this.bookList=res.data
    })
             
# 先用這種方式解決跨域(django 專案)
	1 pip3 install django-cors-headers
    2 app中註冊:
        INSTALLED_APPS = (
            ...
            'corsheaders',
            ...
        )
    3 中介軟體註冊
        MIDDLEWARE = [
        ...
        'corsheaders.middleware.CorsMiddleware',
        ...
        ]
    4 把下面的複製到組態檔中
        CORS_ORIGIN_ALLOW_ALL = True
        CORS_ALLOW_METHODS = (
            'DELETE',
            'GET',
            'OPTIONS',
            'PATCH',
            'POST',
            'PUT',
            'VIEW',
        )
        CORS_ALLOW_HEADERS = (
            'XMLHttpRequest',
            'X_FILENAME',
            'accept-encoding',
            'authorization',
            'content-type',
            'dnt',
            'origin',
            'user-agent',
            'x-csrftoken',
            'x-requested-with',
            'Pragma',
        )
   

在App.vue根元件寫程式碼:

# 安裝axios
	-npm install axios -S
    -npm install -S axios
    -npm install -S [email protected]  # 安裝老版本
	'''-S 表示將axios模組儲存到package.json中'''
      
# 匯入使用
	import axios from 'axios'

在App.vue的script標籤內匯入axios:

通過axios傳送請求:

處理跨域問題,參照上面的設定即可。

在template標籤內使用插值語法,顯示後端的資料:

前後端互動流程分析:

4.1 前後端互動版登入功能

登入功能:

寫事件函數,通過axios傳送post請求:

後端寫登入介面:

前端傳送的post請求裡面攜帶的是json字串,所以使用原生django應該在request.body裡面接受。

5 props設定項

# props設定項: 在裡面寫接受父傳子自定義的屬性

# props設定項有三種寫法:
	-1 陣列寫法
    -2 物件物件寫法
    -3 物件套物件寫法
    
# 寫法總結
  // 普通使用
  // props: ['msg'],
  // 屬性驗證
  // props: {msg: String},
  // 指定型別,必填和預設值
  props: {
    msg: {
      type: String, //型別
      required: true, //必要性
      default: '老王' //預設值
    }
  },

新建元件child.vue:

在根元件引入元件:

在根元件中註冊:

在根元件中使用:

根元件通過自定義屬性進行父傳子(可以寫多個自定義屬性):

子元件通過props設定項接受資料(陣列寫法):

子元件通過props設定項接受資料(物件寫法):

可以進行屬性的驗證,雖然報錯,但前端還是顯示。

子元件通過props設定項接受資料(物件套物件寫法):

這裡設定了,如果自定義屬性沒填寫數值,那麼預設值是老王,且控制檯不會報錯:

如果設定了required:true,自定義屬性不填,控制檯會報錯,但是前端還是會渲染預設值老王

6 混入

# mixin(混入) 可以把多個元件共用的設定提取成一個混入物件
	-把多個元件中公用的東西,抽取出來,以後可以全域性使用和區域性使用
# 使用步驟
	-1 寫個mixin/index.js
    export const hunhe = {
        data() {
        return {
          name: '彭于晏'
        }
      },
        methods: {
            handlePrintName() {
                alert(this.name)
            }
        },
    }
    -2 區域性匯入:在元件中
    import {hunhe} from "@/mixin";
    mixins:[hunhe,]
    
    -3 全域性使用,在main.js 中  以後所有元件都可以用
    import {hunhe} from "@/mixin";
	Vue.mixin(hunhe)

區域性使用mixins

新建一個元件,並將其匯入到根元件:

寫根元件程式碼:

寫child元件程式碼:

可見根元件和子元件有同樣的函數handlePrintName。

在src新建mixin資料夾,在此資料夾下新建index.js檔案,寫如下程式碼:

這裡的函數,直接將元件中的函數部分賦值過來。

在根元件中匯入混入物件,開始使用:

再寫一個mixins設定項:

如果一個元件的設定項裡既有mixins,又有methods,這兩個可以一起用嗎?

注意:如上範例中,混入匯入的和methods中的函數都是同一個名字。

直接說結論:先使用methods中的函數,如果在methods中找不到,再用mixins的。

擴充套件:
混入不僅僅可以抽取methods中的函數,還可以抽取data()資料。
查詢順序和之前的一樣,先使用元件自己的資料,如果沒有資料,再去mixins中找資料。
create()這種生命週期勾點函數也可以抽取到mixins。

全域性引入mixins

需要在main.js中匯入mixin包:

全域性引入之後,相當於在所有元件中都加入了mixins設定項,所有元件就都可以使用混入的函數和資料了。

mixins具體使用情景:
比如有一個記錄使用者瀏覽記錄的功能,通過引入mxins,可以實現在每個元件都可以使用這個功能。

7 外掛

# 功能:用於增強Vue
本質:包含install方法的一個物件,install的第一個引數是Vue,第二個以後的引數是外掛使用者傳遞的資料

# 使用步驟
	-寫一個 plugins/index.js
    import Vue from "vue";
    import axios from "axios";
    import {hunhe} from '@/mixin'
    export default {
        install(miVue) {
            // console.log(miVue)
            // 1 vue 範例上放個變數
            // Vue.prototype.$name = 'lqz'  // 類比python,在類上放了一個屬性,所有物件都能取到
            // Vue.prototype.$ajax = axios

            // 2 使用外掛,加入混入
            // 全域性使用混入
            // Vue.mixin(hunhe)


            // 3 定義全域性元件
            // 4 定義自定義指令  v-lqz
            Vue.directive("fbind", {
                //指令與元素成功繫結時(一上來)
                bind(element, binding) {
                    element.value = binding.value;
                },
                //指令所在元素被插入頁面時
                inserted(element, binding) {
                    element.focus();
                },
                //指令所在的模板被重新解析時
                update(element, binding) {
                    element.value = binding.value;
                },
            });

        }
    }
    
    2 在main.js 中使用外掛
    import plugins from '@/plugins'
	Vue.use(plugins)  // 本子,使用use,會自動觸發外掛物件中得install
    
    3 以後再元件中可以直接用外掛中寫的東西

8 scoped樣式

# 父元件寫了style,子元件都會使用父元件的style
	如果在根元件中寫了樣式,會在所有頁面元件都生效,這樣不太好,所有需要使用scoped。

# 父元件的樣式,在子元件中會生效,在style上寫 <style scoped>  </style>讓該樣式只在當前元件中生效

# 範例
<style scoped>
h1 {
  background-color: chartreuse;
}
</style>

父元件寫了style,子元件都會使用父元件的style

路由:

const routes = [
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/login',
        name: 'login',
        component: () => import('@/views/loginView')  // 匯入login檢視
    },

loginView.vue:

<template>
  <div>
    <h2>我是登入頁面</h2>
    <p>請輸入名字:<input type="text" v-model="username"></p>
    <p>請輸入密碼:<input type="password" v-model="password"></p>
    <button @click="handleSend">提交按鈕1</button>
    <button @click="handleSend2">提交按鈕2</button>


  </div>

</template>

<script>
// 匯入axios
import axios from 'axios'

// 匯入登入函數 (方式一:使用預設匯出)
import tools from '@/test_import/index'
let handleSend = tools.handleSend // 不能直接放,需要用一個變數裝一下

// 匯入登入函數 (方式二:使用有名匯出)
import {handleSend2} from '@/test_import'


export default {
  name: "loginView",
  data() {
    return {
      username: '',
      password: '',
      data: null,
    }
  },
  methods: {
    handleSend, // 預設匯出
    handleSend2, // 有名匯出
  }

}
</script>

<style scoped>

</style>

test_import\index.js:

import axios from "axios";  // 這裡必須匯入axios,因為別的包會直接呼叫下面的函數,而下面的函數需要使用這個axios

// 預設匯出
export default {
    handleSend() {

        axios.post('http://127.0.0.1:8000/api/v1/login/', {
            username: this.username,
            password: this.password
        }).then(res => {
            this.data = res.data
            if (res.data.code === 1000) {
                alert(res.data.msg)
                window.location.href = 'http://localhost:8080/'
            } else {
                alert(res.data.msg)
            }
        })
    }
}

// 有名匯出
export const handleSend2 = function handleSend2() {  // 這裡如果使用匿名函數,由於匿名函數沒有this,在別的元件中使用會導致獲取不了資料。
    axios.post('http://127.0.0.1:8000/api/v1/login/', {username: this.username, password: this.password}).then(res => {
        this.data = res.data
        if (res.data.code === 1000) {
            alert(res.data.msg)
            window.location.href = 'http://localhost:8080/'
        } else {
            alert(res.data.msg)
        }
    })

}

父子通訊展示圖片

前期準備:

imgFather.vue:

<template>
  <div> <!-- 注意這個div,別忘了,不然會報錯 -->

    <!-- 1. 通過自定義屬性url,給子元件傳資料(父傳子) -->
    <imgShow url="https://img1.baidu.com/it/u=3494536116,3351731546&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
             @sonEvent="eventFunc"></imgShow>

    <!-- 2. 通過自定義事件sonEvent,接受子元件傳遞的資料,並使用插值語法顯示(子傳父) -->
    <p>{{ text }}</p>

  </div>
</template>


<script>
import imgShow from "@/components/imgShow"; // 匯入子元件
export default {
  name: "imgFather",
  data() {
    return {
      text: null,
    }
  },
  methods: {
    eventFunc(data) {
      this.text = data  // 接受子元件傳遞的資料data
    }
  },
  components: {
    imgShow,  // 註冊子元件
  }
}
</script>

<style scoped>
</style>

imgShow.vue:

<template>
  <div> <!-- 注意這個div,別忘了,不然會報錯 -->

    <img :src="url">

為頁面元件註冊路由:

 {
        path: '/testSlot',
        name: 'testSlot',
        component: () => import('@/views/testSlot')  // 匯入testSlot檢視
    },

imgSlot.vue:

<template>
  <div>
    <slot></slot>               <!-- 匿名插槽 -->
    <div class="img-padding">
      <slot name="girl"></slot>   <!-- 有名插槽 -->
    </div>

  </div>

</template>

<script>
export default {
  name: "imgSlot"
}
</script>

<style scoped>

.img-padding {
  width: 500px;
  height: 500px;
  border: 8px outset white;
  border-radius: 50%;
  margin: 20px auto;
  overflow: hidden;
}
</style>

testSlot.vue:

<template>
  <div>
    <imgSlot>
      <p>這是一張小姐姐圖片:</p>  <!-- 使用匿名插槽 -->

      <div slot="girl">        <!-- 使用有名插槽 -->
        <img src="https://inews.gtimg.com/newsapp_bt/0/14043245848/641" alt="">
      </div>
    </imgSlot>
  </div>

</template>

<script>
import imgSlot from "@/components/imgSlot";

export default {
  name: "testSlot",
  components: {
    imgSlot,
  }
}
</script>

<style scoped>

</style>