引言Vue.js作为一款流行的前端框架,以其简洁的语法、高效的组件化和双向数据绑定等特性,深受开发者喜爱。本文将通过30个经典案例,带你从入门到精通,解锁前端开发新技能。1. Vue.js 简介Vue...
Vue.js作为一款流行的前端框架,以其简洁的语法、高效的组件化和双向数据绑定等特性,深受开发者喜爱。本文将通过30个经典案例,带你从入门到精通,解锁前端开发新技能。
Vue.js是一个渐进式JavaScript框架,允许开发者使用简洁的模板语法来构建用户界面。它不仅易于上手,而且能够帮助开发者快速开发复杂的前端应用。
<template> <div> <h1>Vue Counter</h1> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="decrement">Decrement</button> <button @click="reset">Reset</button> </div>
</template>
<script>
export default { data() { return { count: 0 }; }, methods: { increment() { this.count++; }, decrement() { this.count--; }, reset() { this.count = 0; } }
};
</script><template> <div> <input v-model="newItem" placeholder="Add new item" /> <button @click="addItem">Add</button> <ul> <li v-for="(item, index) in items" :key="index"> {{ item }} <button @click="removeItem(index)">Remove</button> </li> </ul> </div>
</template>
<script>
export default { data() { return { items: [], newItem: "" }; }, methods: { addItem() { if (this.newItem.trim() !== "") { this.items.push(this.newItem.trim()); this.newItem = ""; } }, removeItem(index) { this.items.splice(index, 1); } }
};
</script><template> <div> <input v-model="inputValue" placeholder="Enter text" /> <p v-if="inputValue.length > 0">You entered: {{ inputValue }}</p> <p v-else>No text entered</p> </div>
</template>
<script>
export default { data() { return { inputValue: "" }; }
};
</script><template> <div> <button @click="handleClick">Click me</button> <button @dblclick="handleDoubleClick">Double click me</button> <button @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave"> Hover over me </button> </div>
</template>
<script>
export default { methods: { handleClick() { alert("Clicked!"); }, handleDoubleClick() { alert("Double clicked!"); }, handleMouseEnter() { alert("Mouse entered!"); }, handleMouseLeave() { alert("Mouse left!"); } }
};
</script><!-- ParentComponent.vue -->
<template> <div> <ChildComponent :message="message" @custom-event="handleCustomEvent" /> </div>
</template>
<script>
import ChildComponent from "./ChildComponent.vue";
export default { components: { ChildComponent }, data() { return { message: "Hello, Vue!" }; }, methods: { handleCustomEvent() { alert("Custom event triggered!"); } }
};
</script>
<!-- ChildComponent.vue -->
<template> <div> <h1>{{ message }}</h1> <button @click="$emit('custom-event')">Trigger custom event</button> </div>
</template>
<script>
export default { props: { message: String }
};
</script><!-- main.js -->
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import Home from "./components/Home.vue";
import About from "./components/About.vue";
Vue.use(VueRouter);
const router = new VueRouter({ routes: [ { path: "/", component: Home }, { path: "/about", component: About } ]
});
new Vue({ router, render: h => h(App)
}).$mount("#app");
<!-- Home.vue -->
<template> <div> <h1>Home</h1> </div>
</template>
<!-- About.vue -->
<template> <div> <h1>About</h1> </div>
</template><!-- store.js -->
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++; }, decrement(state) { state.count--; } }, actions: { increment({ commit }) { commit("increment"); }, decrement({ commit }) { commit("decrement"); } }
});
<!-- App.vue -->
<template> <div> <h1>Count: {{ count }}</h1> <button @click="increment">Increment</button> <button @click="decrement">Decrement</button> </div>
</template>
<script>
import { mapState, mapActions } from "vuex";
export default { computed: { ...mapState(["count"]) }, methods: { ...mapActions(["increment", "decrement"]) }
};
</script><!-- TransitionComponent.vue -->
<template> <transition name="fade"> <div v-if="show">Hello, Vue!</div> </transition>
</template>
<script>
export default { data() { return { show: true }; }
};
</script>
<style>
.fade-enter-active, .fade-leave-active { transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to { opacity: 0;
}
</style><!-- ParentComponent.vue -->
<template> <div> <ChildComponent :message="message" @custom-event="handleCustomEvent" /> </div>
</template>
<script>
import ChildComponent from "./ChildComponent.vue";
export default { components: { ChildComponent }, data() { return { message: "Hello, Vue!" }; }, methods: { handleCustomEvent() { alert("Custom event triggered!"); } }
};
</script>
<!-- ChildComponent.vue -->
<template> <div> <h1>{{ message }}</h1> <button @click="$emit('custom-event')">Trigger custom event</button> </div>
</template>
<script>
export default { props: { message: String }
};
</script>// myPlugin.js
export default { install(Vue) { Vue.prototype.$myMethod = function() { console.log("Hello, myPlugin!"); }; }
};
// main.js
import Vue from "vue";
import App from "./App.vue";
import MyPlugin from "./myPlugin.js";
Vue.use(MyPlugin);
new Vue({ render: h => h(App)
}).$mount("#app");// Counter.spec.js
import { shallowMount } from "@vue/test-utils";
import Counter from "./Counter.vue";
describe("Counter", () => { it("increments count when clicked", async () => { const wrapper = shallowMount(Counter); await wrapper.find("button").trigger("click"); expect(wrapper.vm.count).toBe(1); });
});<!-- AsyncComponent.vue -->
<template> <div>Async Component</div>
</template>
<script>
export default { // AsyncComponent
};
</script>// index.js
import axios from "axios";
export default { getItems() { return axios.get("/api/items"); }, addItem(item) { return axios.post("/api/items", item); }, updateItem(item) { return axios.put(`/api/items/${item.id}`, item); }, deleteItem(id) { return axios.delete(`/api/items/${id}`); }
};<!-- EChartsComponent.vue -->
<template> <div ref="chart"></div>
</template>
<script>
import * as echarts from "echarts";
export default { mounted() { this.initChart(); }, methods: { initChart() { const chart = echarts.init(this.$refs.chart); chart.setOption({ title: { text: "ECharts" }, tooltip: {}, legend: { data: ["销量"] }, xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"] }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20] } ] }); } }
};
</script>// main.js
import { app, BrowserWindow } from "electron";
import Vue from "vue";
import App from "./App.vue";
let mainWindow;
app.on("ready", () => { mainWindow = new BrowserWindow({ width: 800, height: 600 }); mainWindow.loadURL(`file://${__dirname}/index.html`); new Vue({ render: h => h(App) }).$mount("#app");
});// server.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.get("/api/items", (req, res) => { res.json([{ id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }]);
});
app.post("/api/items", (req, res) => { const item = req.body; res.json(item);
});
app.put("/api/items/:id", (req, res) => { const id = req.params.id; const item = req.body; res.json(item);
});
app.delete("/api/items/:id", (req, res) => { const id = req.params.id; res.json({ id });
});
app.listen(3000, () => { console.log("Server is running on port 3000");
});<!-- App.vue -->
<template> <div> <form @submit.prevent="handleSubmit"> <input v-model="username" placeholder="Username" /> <input v-model="password" type="password" placeholder="Password" /> <button type="submit">Login</button> </form> </div>
</template>
<script>
export default { data() { return { username: "", password: "" }; }, methods: { handleSubmit() { // 表单验证等 } }
};
</script>// Counter.spec.js
import { shallowMount } from "@vue/test-utils";
import Counter from "./Counter.vue";
describe("Counter", () => { it("increments count when clicked", async () => { const wrapper = shallowMount(Counter); await wrapper.find("button").trigger("click"); expect(wrapper.vm.count).toBe(1); });
});// router/index.js
import Vue from "vue";
import Router from "vue-router";
import Home from "../views/Home.vue";
Vue.use(Router);
export default new Router({ routes: [ { path: "/", name: "home", component: Home }, { path: "/about", name: "about", component: () => import(/* webpackChunkName: "about" */ "../views/About.vue") } ]
});// main.js
import Vue from "vue";
import App from "./App.vue";
import Sentry from "@sentry/vue";
Vue.use(Sentry, { dsn: "your-sentry-dsn"
});
new Vue({ render: h => h(App)
}).$mount("#app");”`bash