最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中選項式和組合式API的使用詳解

 更新時間:2025年12月16日 10:53:30   作者:鈍挫力PROGRAMER  
本文介紹了Vue.js中的兩種主要API風(fēng)格:選項式API和組合式API,選項式API通過在單文件組件中使用,本文結(jié)合實例代碼對每種方式給大家詳細(xì)講解,感興趣的朋友跟隨小編一起看看吧

Vue 的組件可以按兩種不同的風(fēng)格書寫 :組合式 API和選項式 API 。

組合式 API (Composition API)

通過組合式 API,可以使用導(dǎo)入的 API 函數(shù)來描述組件邏輯。在單文件組件中,組合式 API 通常會與

<script setup>
import { ref, onMounted } from 'vue'
// 響應(yīng)式狀態(tài)
const count = ref(0)
// 用來修改狀態(tài)、觸發(fā)更新的函數(shù)
function increment() {
  count.value++
}
// 生命周期鉤子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>
<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

選項式 API (Options API)

使用選項式 API,可以用包含多個選項的對象來描述組件的邏輯,例如 data、methodsmounted。選項所定義的屬性都會暴露在函數(shù)內(nèi)部的 this 上,它會指向當(dāng)前的組件實例。

<script>
    export default {
	  name: '',  //`name` 屬性標(biāo)識組件名稱
      components: { //使用 `components` 選項注冊子組件 
       }
       // data() 返回的屬性將會成為響應(yīng)式的狀態(tài)
       // 并且暴露在 `this` 上
      data() {
        return {
          // 所有響應(yīng)式數(shù)據(jù)在這里定義
          count: 0
        };
      },
      // methods 是一些用來更改狀態(tài)與觸發(fā)更新的函數(shù)
      // 它們可以在模板中作為事件處理器綁定
      methods: {
        // 所有組件方法在這里定義
      },
      // 生命周期鉤子會在組件生命周期的各個不同階段被調(diào)用
      created() { /* 實例創(chuàng)建后 */ },
      mounted() { /* DOM掛載后 */ },
      updated() { /* 數(shù)據(jù)更新后 */ },
      destroyed() { /* 實例銷毀前 */ },
      // 組件注冊
      components: {
        // 子組件注冊
      }
    }
<script>

export default 的作用

export default 是 ES6 模塊系統(tǒng)的語法,用于導(dǎo)出模塊的默認(rèn)內(nèi)容。在 Vue 中,它用于導(dǎo)出一個 Vue 組件配置對象

export default {
  // 組件配置選項
}

當(dāng)在另一個文件中使用 import 時,導(dǎo)入的就是這個默認(rèn)導(dǎo)出的對象。

data

  • 作用:定義組件的響應(yīng)式數(shù)據(jù)
  • 必須是函數(shù):返回一個包含數(shù)據(jù)的對象
  • 為什么是函數(shù):確保每個組件實例都有獨(dú)立的數(shù)據(jù)副本,避免數(shù)據(jù)共享問題
data() {
  return {
    newUser: { name: '', email: '' },  // 創(chuàng)建新用戶時的表單數(shù)據(jù)
    users: [],                         // 存儲從API獲取的用戶列表
    editingUser: null                  // 當(dāng)前正在編輯的用戶
  };
}

created

  • 生命周期鉤子:在組件實例創(chuàng)建完成后立即調(diào)用
  • 執(zhí)行時機(jī):數(shù)據(jù)觀測已建立,但DOM還未掛載
  • 常見用途:初始化數(shù)據(jù)、調(diào)用API
created() {
  this.fetchUsers(); // 組件創(chuàng)建時自動獲取用戶列表
}

methods

  • 作用:定義組件的方法
  • 特點(diǎn):這些方法可以直接在模板中調(diào)用
methods: {
  // 異步獲取用戶列表
  async fetchUsers() {
    try {
      const response = await axios.get('https://api.example.com/users');
      this.users = response.data; // 更新響應(yīng)式數(shù)據(jù)
    } catch (error) {
      console.error('獲取用戶列表失敗:', error);
    }
  }
}

兩種風(fēng)格對比

組合式 API 的核心思想是直接在函數(shù)作用域內(nèi)定義響應(yīng)式狀態(tài)變量,并將從多個函數(shù)中得到的狀態(tài)組合起來處理復(fù)雜問題。這種形式更加自由,也需要對 Vue 的響應(yīng)式系統(tǒng)有更深的理解才能高效使用。相應(yīng)的,它的靈活性也使得組織和重用邏輯的模式變得更加強(qiáng)大。

選項式 API 是在組合式 API 的基礎(chǔ)上實現(xiàn)的。選項式 API 以“組件實例”的概念為中心 (即上述例子中的 this),基于面向?qū)ο蟾拍顚崿F(xiàn)。同時,它將響應(yīng)性相關(guān)的細(xì)節(jié)抽象出來,并強(qiáng)制按照選項來組織代碼。

以下是官方給出的建議:

  • 在學(xué)習(xí)的過程中,推薦采用更易于理解的風(fēng)格。大部分的核心概念在這兩種風(fēng)格之間都是通用的。熟悉了一種風(fēng)格以后,也能夠很快地理解另一種風(fēng)格。
  • 在生產(chǎn)項目中:
    • 當(dāng)不需要使用構(gòu)建工具,或者打算主要在低復(fù)雜度的場景中使用 Vue,例如漸進(jìn)增強(qiáng)的應(yīng)用場景,推薦采用選項式 API。
    • 當(dāng)你打算用 Vue 構(gòu)建完整的單頁應(yīng)用,推薦采用組合式 API + 單文件組件。

在其他 Vue 組件中導(dǎo)入和使用export default定義的組件 有幾種方式

基本導(dǎo)入和使用

導(dǎo)入組件

<template>
  <div>
    <!-- 使用導(dǎo)入的組件 -->
    <ArticleList />
  </div>
</template>
// 選項式
<script>
// 導(dǎo)入組件
import ArticleList from '@/components/ArticleList.vue'
export default {
  name: 'ParentComponent',
  components: {
    // 注冊導(dǎo)入的組件
    ArticleList
  }
}
</script>

調(diào)用子組件的方法

方法一:使用 ref 引用

<template>
  <div>
    <button @click="refreshArticles">刷新文章</button>
    <button @click="createNewArticle">創(chuàng)建文章</button>
    <!-- 給組件添加 ref 屬性 -->
    <ArticleList ref="articleListRef" />
  </div>
</template>
<script>
import ArticleList from '@/components/ArticleList.vue'
export default {
  name: 'ParentComponent',
  components: {
    ArticleList
  },
  methods: {
    refreshArticles() {
      // 調(diào)用子組件的 fetchArticles 方法
      this.$refs.articleListRef.fetchArticles()
    },
    createNewArticle() {
      // 調(diào)用子組件的 handleCreateArticle 方法
      this.$refs.articleListRef.handleCreateArticle()
    }
  }
}
</script>

方法二:通過 props 傳遞回調(diào)函數(shù)

父組件:

<template>
  <div>
    <ArticleList 
      :onRefresh="handleRefresh"
      :onCreate="handleCreate"
    />
  </div>
</template>
<script>
import ArticleList from '@/components/ArticleList.vue'
export default {
  components: {
    ArticleList
  },
  methods: {
    handleRefresh() {
      console.log('父組件處理刷新邏輯')
    },
    handleCreate(articleData) {
      console.log('父組件處理創(chuàng)建邏輯', articleData)
    }
  }
}
</script>

子組件 (ArticleList.vue):

<script>
export default {
  name: 'ArticleList',
  props: {
    onRefresh: Function,
    onCreate: Function
  },
  methods: {
    fetchArticles() {
      // 原有的獲取文章邏輯
      fetch('http://localhost:8000/posts')
        .then(r => r.json())
        .then(data => {
          this.articles = data
          // 如果有傳遞回調(diào)函數(shù),則調(diào)用
          if (this.onRefresh) {
            this.onRefresh(data)
          }
        })
    },
    handleCreateArticle() {
      // 原有的創(chuàng)建邏輯...
      // 如果有傳遞回調(diào)函數(shù),則調(diào)用
      if (this.onCreate) {
        this.onCreate(this.newArticle)
      }
    }
  }
}
</script>

完整的父子組件通信示例

父組件

<template>
  <div class="parent">
    <h1>博客管理</h1>
    <div class="controls">
      <button @click="triggerRefresh" :disabled="isLoading">
        {{ isLoading ? '加載中...' : '刷新文章' }}
      </button>
      <button @click="showCreateForm = true">新建文章</button>
    </div>
    <!-- 使用子組件 -->
    <ArticleList 
      ref="articleList"
      :externalCreateData="createFormData"
      @articles-loaded="onArticlesLoaded"
      @article-created="onArticleCreated"
    />
    <!-- 父組件的創(chuàng)建表單 -->
    <div v-if="showCreateForm" class="modal">
      <h3>創(chuàng)建新文章</h3>
      <input v-model="createFormData.title" placeholder="標(biāo)題">
      <textarea v-model="createFormData.content" placeholder="內(nèi)容"></textarea>
      <button @click="submitCreateForm">提交</button>
      <button @click="cancelCreate">取消</button>
    </div>
  </div>
</template>
<script>
import ArticleList from '@/components/ArticleList.vue'
export default {
  name: 'BlogManagement',
  components: {
    ArticleList
  },
  data() {
    return {
      isLoading: false,
      showCreateForm: false,
      createFormData: {
        title: '',
        content: ''
      }
    }
  },
  methods: {
    // 觸發(fā)子組件的刷新方法
    triggerRefresh() {
      this.isLoading = true
      this.$refs.articleList.fetchArticles()
    },
    // 觸發(fā)子組件的創(chuàng)建方法
    submitCreateForm() {
      this.$refs.articleList.handleCreateArticle(this.createFormData)
      this.showCreateForm = false
    },
    cancelCreate() {
      this.showCreateForm = false
      this.createFormData = { title: '', content: '' }
    },
    // 監(jiān)聽子組件的事件
    onArticlesLoaded(articles) {
      this.isLoading = false
      console.log('文章加載完成:', articles)
    },
    onArticleCreated(newArticle) {
      console.log('新文章創(chuàng)建:', newArticle)
      this.createFormData = { title: '', content: '' }
    }
  }
}
</script>

子組件 (ArticleList.vue)

<template>
  <div class="article-list">
    <div v-if="articles.length === 0" class="empty">暫無文章</div>
    <ArticleCard 
      v-for="article in articles" 
      :key="article.id" 
      :article="article" 
    />
  </div>
</template>
<script>
import ArticleCard from './ArticleCard.vue'
export default {
  name: 'ArticleList',
  components: {
    ArticleCard
  },
  props: {
    // 從父組件接收創(chuàng)建數(shù)據(jù)
    externalCreateData: {
      type: Object,
      default: () => ({ title: '', content: '' })
    }
  },
  data() {
    return {
      articles: [],
      newArticle: {
        title: '',
        content: '',
        author: '左越'
      }
    }
  },
  watch: {
    // 監(jiān)聽外部創(chuàng)建數(shù)據(jù)的變化
    externalCreateData: {
      handler(newData) {
        if (newData.title || newData.content) {
          this.newArticle = { ...newData, author: '左越' }
          this.handleCreateArticle()
        }
      },
      deep: true
    }
  },
  created() {
    this.fetchArticles()
  },
  methods: {
    async fetchArticles() {
      try {
        const response = await fetch('http://localhost:8000/posts')
        const data = await response.json()
        this.articles = data
        // 觸發(fā)事件通知父組件
        this.$emit('articles-loaded', data)
      } catch (err) {
        console.log('error', err)
        this.$emit('articles-loaded', [])
      }
    },
    async handleCreateArticle(externalData = null) {
      const articleData = externalData || this.newArticle
      if (!articleData.title.trim() || !articleData.content.trim()) {
        alert('請?zhí)顚懰凶侄?)
        return
      }
      try {
        const response = await fetch('http://localhost:8000/posts', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(articleData)
        })
        const newArticle = await response.json()
        this.articles.unshift(newArticle)
        // 觸發(fā)事件通知父組件
        this.$emit('article-created', newArticle)
        // 重置表單
        this.resetForm()
      } catch (err) {
        console.error('error: ', err)
      }
    },
    resetForm() {
      this.newArticle = {
        title: '',
        content: '',
        author: '左越'
      }
    }
  }
}
</script>

關(guān)鍵點(diǎn)總結(jié):

  1. 導(dǎo)入組件:使用 import ComponentName from 'path/to/component'
  2. 注冊組件:在 components 選項中注冊
  3. 使用 ref:通過 this.$refs.refName.methodName() 調(diào)用子組件方法
  4. 事件通信:子組件使用 this.$emit('event-name', data),父組件使用 @event-name="handler"
  5. Props 傳遞:父組件通過 props 向子組件傳遞數(shù)據(jù)和方法

選擇哪種方式取決于具體需求:

  • 簡單的調(diào)用使用 ref
  • 復(fù)雜的通信使用 propsevents
  • 狀態(tài)管理考慮使用 Vuex(對于大型應(yīng)用)

這種結(jié)構(gòu)讓 Vue 能夠自動處理數(shù)據(jù)與視圖的同步,大大簡化了前端開發(fā)的復(fù)雜度。

愿你我都能在各自的領(lǐng)域里不斷成長,勇敢追求夢想,同時也保持對世界的好奇與善意!

到此這篇關(guān)于Vue中選項式和組合式API的學(xué)習(xí)的文章就介紹到這了,更多相關(guān)vue選項式和組合式API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

都江堰市| 浮山县| 临桂县| 乌鲁木齐市| 廉江市| 红桥区| 临海市| 临清市| 巨野县| 蓝山县| 定南县| 肥城市| 和顺县| 静乐县| 盈江县| 镇安县| 甘泉县| 屯昌县| 醴陵市| 四子王旗| 环江| 革吉县| 乐业县| 建昌县| 田林县| 满洲里市| 云阳县| 武宁县| 晋州市| 平昌县| 邵武市| 府谷县| 德清县| 灵山县| 龙里县| 望江县| 平江县| 工布江达县| 武鸣县| 麻阳| 奉化市|