入口頁面
首先映入眼簾的是 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