1. Vue.js 简介
Vue.js 是一个用于构建用户界面的渐进式框架。与其他重量级框架不同,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,易于上手,也便于与第三方库或既有项目集成。Vue 还完全支持单文件组件格式,让你能够以组件化的方式组织代码,提高开发效率。
2. Vue.js 基础
安装与配置
使用CDN引入
<div id="app">
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
});
</script>
使用Vue CLI创建项目
# 安装 Vue CLI
npm install -g @vue/cli
# 创建 Vue 项目
vue create my-vue-project
# 进入项目目录
cd my-vue-project
# 启动开发服务器
npm run serve
Vue实例
创建一个Vue实例,需要传入一个选项对象。这个选项对象可以包含数据、模板、挂载元素、方法、生命周期钩子等。
<div id="app">
{{ message }}
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
methods: {
updateMessage() {
this.message = 'Hello, World!';
}
},
created() {
console.log('Vue 实例已经创建完成');
}
});
</script>
生命周期钩子
Vue实例有一个完整的生命周期,即从开始创建、初始化数据、编译模板、挂载DOM到运行时的更新、卸载等。
new Vue({
data: {
message: 'Hello, Vue!'
},
beforeCreate() {
console.log('实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。');
},
created() {
console.log('实例创建完成后被调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。');
},
beforeMount() {
console.log('在挂载开始之前被调用:相关的 render 函数首次被调用。');
},
mounted() {
console.log('el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。');
},
beforeUpdate() {
console.log('数据更新时调用,发生在虚拟 DOM 打补丁之前。');
},
updated() {
console.log('由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。');
},
beforeDestroy() {
console.log('实例销毁之前调用。在这一步,实例仍然完全可用。');
},
destroyed() {
console.log('Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。');
}
});
模板语法
插值
<div id="app">
{{ message }}
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
});
</script>
指令
<div id="app">
<p v-if="show">显示的内容</p>
<button v-on:click="show = !show">Toggle</button>
</div>
<script>
new Vue({
el: '#app',
data: {
show: true
}
});
</script>
计算属性与侦听器
<div id="app">
<p>原始消息: {{ message }}</p>
<p>反转消息: {{ reversedMessage }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
},
watch: {
message(newVal, oldVal) {
console.log('消息从 ' + oldVal + ' 变为 ' + newVal);
}
}
});
</script>
条件渲染与列表渲染
条件渲染
<div id="app">
<p v-if="show">显示的内容</p>
<p v-else>隐藏的内容</p>
</div>
<script>
new Vue({
el: '#app',
data: {
show: true
}
});
</script>
列表渲染
<div id="app">
<ul>
<li v-for="(item, index) in items" :key="index">{{ item }}</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
items: ['Vue', 'React', 'Angular']
}
});
</script>
事件处理
事件处理
<div id="app">
<p>{{ message }}</p>
<button v-on:click="message = 'Hello, World!'">点击我</button>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
});
</script>
事件修饰符
<div id="app">
<form v-on:submit.prevent="submitForm">
<input type="text" v-model="name">
<button type="submit">提交</button>
</form>
</div>
<script>
new Vue({
el: '#app',
data: {
name: ''
},
methods: {
submitForm() {
console.log('提交的名字是: ' + this.name);
}
}
});
</script>
表单输入绑定
v-model
<div id="app">
<input type="text" v-model="name">
<p>你的名字是: {{ name }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
name: ''
}
});
</script>
修饰符
<div id="app">
<input type="text" v-model.trim="name">
<p>你的名字是: {{ name }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
name: ''
}
});
</script>
3. Vue.js 组件
组件基础
注册组件可以是全局注册,也可以是局部注册。
// 全局注册
Vue.component('my-component', {
template: '<div>全局组件</div>'
});
// 局部注册
new Vue({
el: '#app',
components: {
'my-component': {
template: '<div>局部组件</div>'
}
}
});
组件通信
Props
Vue.component('child-component', {
props: ['message'],
template: '<div>{{ message }}</div>'
});
new Vue({
el: '#app',
data: {
parentMessage: 'Hello, Vue!'
}
});
自定义事件
<div id="app">
<p>{{ parentMessage }}</p>
<child-component @child-event="updateMessage"></child-component>
</div>
<script>
Vue.component('child-component', {
template: '<button @click="$emit(\'child-event\', \'Hello from child!\')">发送消息</button>'
});
new Vue({
el: '#app',
data: {
parentMessage: ''
},
methods: {
updateMessage(newMessage) {
this.parentMessage = newMessage;
}
}
});
</script>
插槽
<div id="app">
<child-component>
<p>插槽内容</p>
</child-component>
</div>
<script>
Vue.component('child-component', {
template: '<div><slot></slot></div>'
});
new Vue({
el: '#app'
});
</script>
单文件组件
使用 .vue
文件格式来组织组件。
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style scoped>
.hello {
text-align: center;
color: #42b983;
}
</style>
动态组件与异步组件
动态组件
<div id="app">
<component v-bind:is="currentComponent"></component>
<button @click="currentComponent = 'component-a'">切换到组件A</button>
<button @click="currentComponent = 'component-b'">切换到组件B</button>
</div>
<script>
Vue.component('component-a', { template: '<div>Component A</div>' });
Vue.component('component-b', { template: '<div>Component B</div>' });
new Vue({
el: '#app',
data: {
currentComponent: 'component-a'
}
});
</script>
异步组件
Vue.component('async-component', function(resolve, reject) {
setTimeout(function() {
resolve({
template: '<div>异步组件</div>'
});
}, 1000);
});
new Vue({
el: '#app'
});