Vue3實戰(zhàn)系列:結(jié)合 Ant-Design-of-Vue 實踐 Composition API

入口頁面

首先映入眼簾的是 main.js 的變化:

// Vue 3.0

import { createApp } from 'vue'

import App from './App.vue'

import './index.css'

createApp(App).mount('#app')

// Vue 2.x

import Vue from 'vue'

import App from './App.vue'

new Vue({

? render: h => h(App)

}).$mount('#app')

第一段代碼是 Vue 3 的創(chuàng)建 Vue 實例形式,通過 createApp 的形式,你別說,和 React 真的挺像的??。

第二段是 Vue 2.x 的創(chuàng)建 Vue 實例形式,通過 new 的形式創(chuàng)建。

添加路由 Vue-Router

截止目前,vue-router-next 更新到了 v4.0.0-beta.12 版本。

你如果用 cnpm install vue-router 安裝路由,是會下載到 vue-router 3.x 的版本,我們需要使用:

cnpm install vue-router@next -S

安裝完畢之后,我們開始配置項目路由,在 src 目錄下新建 rourer 文件夾,在文件夾下新建 index.js 文件,添加如下內(nèi)容:

import {createRouter, createWebHashHistory} from 'vue-router'

export default createRouter({

? history: createWebHashHistory(),

? routes: []

})

Vue 2.x 的路由模式通過 mode 選項為 history 或 hash 去控制。

而在 Vue 3 中,通過 createRouter 創(chuàng)建路由實例,history 屬性作為控制路由模式的參數(shù),createWebHashHistory 方法返回的是 hash 模式,createWebHistory 返回的是 history 模式,本項目采用 hash 模式。

同樣,我們需要在 mian.js 中引入 router 實例:

import { createApp } from 'vue'

import App from './App.vue'

import router from './router'

import './index.css'

createApp(App).use(router).mount('#app')

添加全局狀態(tài) Vuex

vuex 更新到了 v4.0.0-beta.4 版本,所以我們需要用如下指令安裝:

cnpm i vuex@next -S

接下來在 src 目錄下創(chuàng)建 store 文件夾,再新建 index.js 文件,添加代碼如下:

// Vue 3

import { createStore } from 'vuex'

export default createStore({

? state() {

? ? return {

? ? ? author: "十三",

? ? };

? },

});

對比 Vue 2.x 寫法:

// Vue 2.x

import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({

? state,

? mutations,

? actions,

? modules: {}

})

同樣是使用新的寫法,通過 vuex 內(nèi)部拋出的 createStore 方法,創(chuàng)建一個 Vuex 實例。

接下來我們將它引入到 main.js 中:

import { createApp } from 'vue'

import App from './App.vue'

import router from './router'

import store from './store'

import './index.css'

// 鏈?zhǔn)秸{(diào)用

createApp(App).use(router).use(store).mount('#app')

引入 Antd for Vue3 版本組件庫

Antdv2.x是唐金州老師(杭州校寶在線)研發(fā)的新一代適配 Vue 3.0 的組件庫,我們來嘗嘗鮮,這邊我們通過如下命令后下載:

cnpm i --save ant-design-vue@next -S

在 mian.js 內(nèi)引入 ant-design-vue 組件如下所示:

import { createApp } from 'vue'

import Antd from 'ant-design-vue';

import App from './App.vue'

import router from './router'

import store from './store'

import 'ant-design-vue/dist/antd.css';

import './index.css'

// 本教程采用的是全局引入組件庫

createApp(App).use(router).use(store).use(Antd).mount('#app')

測試一下是否成功,順便解釋一下 Vue 3 如何聲明變量,以及如何通過方法改變變量,代碼如下:

<template>

? <a-button @click="add" type="primary">

? ? 點我加{{ count }}

? </a-button>

? <a-button @click="add2('a')" type="primary">

? ? 點我加a{{ state.a }}

? </a-button>

? <a-button @click="add2('b')" type="primary">

? ? 點我加b{{ state.b }}

? </a-button>

</template>

<script>

import { ref, reactive } from 'vue'

export default {

? setup() {

? ? const count = ref(0)

? ? const state = reactive({

? ? ? a: 0,

? ? ? b: 0,

? ? })

? ? const add = () => {

? ? ? count.value += 1

? ? }

? ? const add2 = (type) => {

? ? ? state[type] += 1

? ? }

? ? return {

? ? ? state,

? ? ? count,

? ? ? add,

? ? ? add2

? ? }

? }

}

</script>

如上述代碼所示,Vue 3 新增的 setup 方法,顛覆了之前傳統(tǒng)的 options 屬性方式,我們可以將業(yè)務(wù)邏輯都寫在 setup 方法中。

我們有兩種聲明變量的形式:

ref:它用于聲明簡單的基礎(chǔ)類型變量,如單個數(shù)字、boolean、字符串等等。

reactive:它用于對象引用類型的復(fù)雜變量。

所有聲明好的變量和方法,如果想在 template 模板里使用的話,必須在 setup 方法里 return,否則無法調(diào)用。記住返回什么就是聲明,如返回 count,模板中就用 {{ count }},返回 state,模板中就使用 {{ state.a }} 。效果如下所示:

待辦事項 TODO

首先我們新建 views 文件夾用于放置頁面組件,在 views 內(nèi)新建 todo.vue 文件,如下所示:

<template>

? <div id="components-layout-demo-basic">

? ? <a-layout>

? ? ? <a-layout-header>待辦事項</a-layout-header>

? ? ? <a-layout-content>內(nèi)容</a-layout-content>

? ? </a-layout>

? </div>

</template>

<script>

import { ref, reactive } from 'vue'

export default {

? setup() {

? }

}

</script>

<style scoped>

? #components-layout-demo-basic {

? ? min-height: 100vh;

? ? max-width: 40%;

? ? margin: 0 auto;

? ? background-color: #ededed;

? }

? #components-layout-demo-basic .ant-layout-header,

? #components-layout-demo-basic .ant-layout-footer {

? ? background: #7dbcea;

? ? text-align: center;

? ? color: #fff;

? }

</style>

引入 antd-v 的布局組件,再給一些基礎(chǔ)樣式。

然后前往 App.vue 和 router/index.js 做如下改動:

// App.vue

<template>

? <router-view></router-view>

</template>

<script>

export default {

? name: 'App'

}

</script>

import {createRouter, createWebHashHistory} from 'vue-router'

export default createRouter({

? history: createWebHashHistory(),

? routes: [

? ? {

? ? ? path: '/todo',

? ? ? component: () => import('../views/todo.vue')

? ? }

? ]

})

最后頁面出現(xiàn)如下所示,代表配置成功:

添加新增待辦事項輸入框:

<template>

? <div id="components-layout-demo-basic">

? ? <a-layout>

? ? ? <a-layout-header>待辦事項</a-layout-header>

? ? ? <a-layout-content>

? ? ? ? <a-input-search

? ? ? ? ? v-model:value="todo"

? ? ? ? ? placeholder="請輸入要代辦的事項"

? ? ? ? ? size="large"

? ? ? ? ? @search="addTodo"

? ? ? ? >

? ? ? ? ? <template v-slot:enterButton>

? ? ? ? ? ? <a-button>新增</a-button>

? ? ? ? ? </template>

? ? ? ? </a-input-search>

? ? ? </a-layout-content>

? ? </a-layout>

? </div>

</template>

<script>

import { ref, reactive } from 'vue'

import { ref, reactive } from 'vue'

export default {

? setup() {

? ? const todo = ref('')

? ? const addTodo = (value) => {

? ? ? console.log(value)

? ? }

? ? return {

? ? ? todo,

? ? ? onSearch

? ? }

? }

}

</script>

如下圖所示:

添加“待辦事項”和“已辦事項”模板,代碼如下:

<template>

? <div id="components-layout-demo-basic">

? ? <a-layout>

? ? ? <a-layout-header>待辦事項</a-layout-header>

? ? ? <a-layout-content>

? ? ? ? <a-input-search

? ? ? ? ? v-model:value="todo"

? ? ? ? ? placeholder="請輸入要代辦的事項"

? ? ? ? ? size="large"

? ? ? ? ? @search="addTodo"

? ? ? ? >

? ? ? ? ? <template v-slot:enterButton>

? ? ? ? ? ? <a-button>新增</a-button>

? ? ? ? ? </template>

? ? ? ? </a-input-search>

? ? ? ? <h2 class="title">待辦事項</h2>

? ? ? ? <a-card title="標(biāo)題">

? ? ? ? ? <template v-slot:extra>

? ? ? ? ? ? <a-switch />

? ? ? ? ? </template>

? ? ? ? ? 內(nèi)通

? ? ? ? </a-card>

? ? ? ? <h2 class="title">已辦事項</h2>

? ? ? ? <a-card title="標(biāo)題">

? ? ? ? ? <template v-slot:extra>

? ? ? ? ? ? <a-switch />

? ? ? ? ? </template>

? ? ? ? ? 內(nèi)通

? ? ? ? </a-card>

? ? ? </a-layout-content>

? ? </a-layout>

? </div>

</template>

<script>

import { ref, reactive } from 'vue'

export default {

? setup() {

? ? const todo = ref('')

? ? const addTodo = (value) => {

? ? ? console.log(value)

? ? }

? ? return {

? ? ? todo,

? ? ? onSearch

? ? }

? }

}

</script>

<style scoped>

? #components-layout-demo-basic {

? ? min-height: 100vh;

? ? max-width: 40%;

? ? margin: 0 auto;

? ? background-color: #ededed;

? }

? #components-layout-demo-basic .ant-layout-header,

? #components-layout-demo-basic .ant-layout-footer {

? ? background: #7dbcea;

? ? color: #fff;

? ? text-align: center;

? }

? .title {

? ? margin: 0;

? ? padding: 10px;

? }

</style>

效果如下:

接下來我們來添加代辦的相應(yīng)邏輯:

<template>

? <div id="components-layout-demo-basic">

? ? <a-layout>

? ? ? <a-layout-header>待辦事項</a-layout-header>

? ? ? <a-layout-content>

? ? ? ? <a-input-search

? ? ? ? ? v-model:value="todo"

? ? ? ? ? placeholder="請輸入要代辦的事項"

? ? ? ? ? size="large"

? ? ? ? ? @search="addTodo"

? ? ? ? >

? ? ? ? ? <template v-slot:enterButton>

? ? ? ? ? ? <a-button>新增</a-button>

? ? ? ? ? </template>

? ? ? ? </a-input-search>

? ? ? ? <h2 class="title">待辦事項</h2>

? ? ? ? <a-card :title="`${index + 1}、${item.time}`" v-for="(item, index) in todos" :key="item.id">

? ? ? ? ? <template v-slot:extra>

? ? ? ? ? ? <a-switch v-model:checked="item.done" @change="handleCheck(item, true)" />

? ? ? ? ? </template>

? ? ? ? ? {{ item.content }}

? ? ? ? </a-card>

? ? ? ? <h2 class="title">已辦事項</h2>

? ? ? ? <a-card :title="`${index + 1}、${item.time}`" v-for="(item, index) in dones" :key="item.id">

? ? ? ? ? <template v-slot:extra>

? ? ? ? ? ? <a-switch v-model:checked="item.done" @change="handleCheck(item, false)" />

? ? ? ? ? </template>

? ? ? ? ? 內(nèi)通

? ? ? ? </a-card>

? ? ? </a-layout-content>

? ? </a-layout>

? </div>

</template>

<script>

import { ref, reactive, computed } from 'vue'

export default {

? setup() {

? ? const todo = ref('')

? ? const time = `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDate()}`

? ? const state = reactive({

? ? ? todoList: [

? ? ? ? {

? ? ? ? ? id: 1,

? ? ? ? ? done: false,

? ? ? ? ? time: time,

? ? ? ? ? content: '前往老八食堂,共進午餐'

? ? ? ? },

? ? ? ? {

? ? ? ? ? id: 2,

? ? ? ? ? done: false,

? ? ? ? ? time: time,

? ? ? ? ? content: '和giao哥合唱一曲'

? ? ? ? },

? ? ? ? {

? ? ? ? ? id: 3,

? ? ? ? ? done: false,

? ? ? ? ? time: time,

? ? ? ? ? content: '做點陽間的需求'

? ? ? ? }

? ? ? ]

? ? })

? ? // 添加待辦事項

? ? const addTodo = (value) => {

? ? ? if(!value) {

? ? ? ? message.error('請輸入待辦事項')

? ? ? ? return

? ? ? }

? ? ? state.todoList.push({

? ? ? ? content: value,

? ? ? ? id: Date.now(),

? ? ? ? time: time,

? ? ? ? done: false

? ? ? })

? ? ? todo.value = ''

? ? }

? ? // 通過計算屬性,計算出生成的代辦事項列表

? ? const todos = computed(() => {

? ? ? return state.todoList.filter(item => !item.done)

? ? })

? ? // 通過計算屬性,計算出生成的已辦列表

? ? const dones = computed(() => {

? ? ? return state.todoList.filter(item => item.done)

? ? })

? ? // 修改狀態(tài)方法

? ? const handleCheck = (item ,status) => {

? ? ? item.done = status

? ? }

? ? return {

? ? ? todo,

? ? ? addTodo,

? ? ? state,

? ? ? todos,

? ? ? dones,

? ? ? handleCheck

? ? }

? }

}

</script>

<style scoped>

? #components-layout-demo-basic {

? ? min-height: 100vh;

? ? max-width: 40%;

? ? margin: 0 auto;

? ? background-color: #ededed;

? }

? #components-layout-demo-basic .ant-layout-header,

? #components-layout-demo-basic .ant-layout-footer {

? ? background: #7dbcea;

? ? color: #fff;

? ? text-align: center;

? }

? .title {

? ? margin: 0;

? ? padding: 10px;

? }

</style>

深圳網(wǎng)站建設(shè)www.sz886.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。