Vue3浅尝

Vue3浅尝

中文版API文档地址:Vue3中文文档

脚手架文档地址:Vue CLI

本文基于vue-cli@4.5.0脚手架,vue@3.0.0-0,typescript实现。

Gitee代码地址
维护文档地址

CHANGELOG

2020-9-30

refactor

1、重构引入ant-design-vue方式以及写法

2、加上配置git提交规范说明

脚手架安装

安装

# 全局安装
npm i -g @vue/cli
# 创建项目
vue create vue3-study
# 使用typescript
vue add typescript

配置

vue.config.js

// vue.config.js
const path = require('path');
function resolve(dir) {
  return path.join(__dirname, dir)
}

module.exports = {
  chainWebpack: config => {
    // ts
    config.module
      .rule('ts')
      .use('ts-loader')
      .loader('ts-loader')
      .end()
      .use('babel-loader')
      .loader('babel-loader')
      .end()
      .use('cache-loader')
      .loader('cache-loader')
      .end()
    // 配置路径别名
    config.resolve.alias
      .set('@', resolve('src'))
  },
  devServer: {
    inline: true,
    hot: true,
    stats: 'minimal',
    clientLogLevel: 'warning',
    contentBase: __dirname,
    overlay: true,
    historyApiFallback: true
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

启动服务

这里也可以通过package.json修改成自己的命令

yarn serve

具体使用

1. Vue-Router

配套Vue3Vue-Router版本为vue-router@next

1.1 下载配套版本
yarn add vue-router@next
1.2 使用

1.2.1 router

// router/index.ts

import { createRouter, createWebHistory } from 'vue-router';

// * history对象
const routerHistory = createWebHistory()

// 1. 定义路由组件

// * 1.1 Normal
import Normal from '@/pages/Normal/index.vue';
// * 1.2 Todo 
import TodoList from '@/pages/TodoList/index.vue';


// 2. 定义路由
const routes = [{
  path: '/',
  component: Normal
},
{
  path: '/normal',
  component: Normal
},
{
  path: '/todo',
  component: TodoList
}]

// 3. 创建router对象
const router = createRouter(
  {
    history: routerHistory,
    routes
  }
)

// 4. 导出对象
export default router;

1.2.2 main.ts

import { createApp } from 'vue'

import router from './router';
import App from './App.vue'

// 创建vue实例
const app = createApp(App)

app.use(router)

app.mount('#app')

1.2.3 App.vue

<template>
  <div id="root">
    <img src="./assets/logo.png" />
    <div id="nav">
      <router-link to="/"> Home</router-link>
      <router-link to="/normal">Normal </router-link>
      <router-link to="/todo">TodoList</router-link>
    </div>
    <router-view />
  </div>
</template>

2. 父子通信

2.2.1 child

// child.vue

<template>
  <ul>
    <li v-for="(item, index) in todoLists" :key="item.id">
      <p>
        {{ index + 1 }}、{{ item.name }}
        <span class="add" @click="add">新增</span>
        <span class="del" @click="del(item.id)" v-if="todoLists.length > 1"
          >删除</span
        >
      </p>
    </li>
  </ul>
</template>
<script lang="ts">
export default {
  props: {
    todoLists: Array,
    add: Function,
    del: Function,
  },
};
</script>

<style lang="less" scoped>
ul {
  width: 400px;
  margin: 0;
  padding: 0;
  li {
    width: 100%;
    list-style: none;
    text-align: left;
    line-height: 20px;
    span {
      cursor: pointer;
      margin: 0 10px;
      font-size: 12px;
    }
  }
}
</style>

2.2.2 father

// index.vue

<template>
  <div>
    <TodoList :add="add" :del="del" :todoLists="todoLists" />
  </div>
</template>
<script lang="ts">
import { reactive } from "vue";

import TodoList from "./TodoList.vue";

export default {
  components: { TodoList },

  setup() {
    const todoLists: { name: string; id: number }[] = reactive([
      {
        id: 1,
        name: "第1件事",
      },
    ]);
    // 新增
    const add = () => {
      const lastId = todoLists[todoLists.length - 1].id;
      const newId = lastId + 1;
      const newName = `第${newId}件事`;

      todoLists.push({
        id: newId,
        name: newName,
      });
    };
    // 删除
    const del = (id: number) => {
      let delIndex;

      todoLists.forEach((item, index) => {
        if (item.id === id) {
          delIndex = index;
        }
      });
      delIndex !== undefined && todoLists.splice(delIndex, 1);
    };

    return {
      todoLists,
      add,
      del,
    };
  },
};
</script>

3. Vuex

3.1下载配套版本
yarn add vuex@next -D
3.2 使用

3.2.1 新建 store/index.ts

import { createStore } from 'vuex'

export const store = createStore({
  state: {
    count: 1
  },
  getters: {
    getCount: state => state.count
  },
  mutations: {
    changeCount(state, n: number) {
      if (n > 0) {
        state.count = n;
      }
    },
  },
  actions: {
    add({ commit }) {
      const count = this.state.count + 1;
      commit('changeCount', count)
    },
    del({ commit }) {
      const count = this.state.count - 1;
      commit('changeCount', count)
    }
  }
})

3.2.2 main.ts

import { store } from './store';
app.use(store)

3.2.3 *.vue

<template>
  <div class="about">
    <h1>warning</h1>
    <p><span @click="del">-</span>{{ count }}<span @click="add">+</span></p>
  </div>
</template>
<script>
import { useStore } from "vuex";
import { computed } from "vue";

export default {
  setup() {
    const store = useStore();
    const count = computed(() => store.getters["getCount"]);

    const add = () => {
      store.dispatch("add");
    };
    const del = () => {
      store.dispatch("del");
    };

    return {
      count,
      add,
      del,
    };
  },
};
</script>

<style lang="less">
span {
  display: inline-block;
  background: #eee;
  color: #000000;
  width: 20px;
  height: 24px;
  line-height: 24px;
  margin: 0 20px;
  cursor: pointer;
  user-select: none;
}
</style>

4. 生命周期

4.1 生命周期说明
  1. 取消beforeCreatecreated

    在使用componsition api的时候,其实setup就代替了beforeCreatecreated,因为setup就是组件的实际入口函数。

  2. beforeDestroydestroyed 改名了

    setup中,beforeDestroy更名为onBeforeUnmount,destroyed更名为onUnmounted

  3. 将生命周期函数名称变为on+XXX,比如mounted变成了onMounted,updated变成了onUpdated

4.2 使用
<script>
import { onMounted, onUpdated, onUnmounted } from "vue";

export default {
  setup() {
    onMounted(() => {
      console.log("mounted!");
    });
    onUpdated(() => {
      console.log("updated!");
    });
    onUnmounted(() => {
      console.log("unmounted!");
    });
  },
};
</script>

参考

Vue3来袭,你想学的都在这(二)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值