实验目的
熟悉Vue实例模版
熟悉Vue模版语法核心语法
掌握Vue生命周期函数及其执行时机
掌握模板语法中条件渲染语法
掌握模板语法中循环渲染语法
实验步骤
- Vue实例解析
在项目目录 D:/vue/demo 下创建 demo2.html 文件,并引入最新版Vue.js(推荐使用CDN)。该Vue实例拥有常用的配置项,包括生命周期函数、watch、computed等配置项。
javascript
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue3选项式API示例</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
</head>
<body>
<div id="app" class="container">
<h1>{{ title }}</h1>
<div class="section">
<h2>数据绑定</h2>
<p>计数器: {{ counter }}</p>
<button @click="increment">增加</button>
<button @click="decrement">减少</button>
</div>
<div class="section">
<h2>计算属性</h2>
<p>计算属性结果: {{ computedMessage }}</p>
<p>反转消息: {{ reversedMessage }}</p>
</div>
<div class="section">
<h2>侦听器</h2>
<input v-model="inputText" placeholder="输入内容观察watch效果">
<p>输入内容: {{ inputText }}</p>
<p>上次输入: {{ lastInput }}</p>
</div>
<div class="section">
<h2>组件生命周期</h2>
<p>组件创建时间: {{ createTime }}</p>
<button @click="updateTime">更新时间</button>
</div>
</div>
<script>
const { createApp } = Vue;
<!-- 使用构造函数创建Vue对象 -->
createApp({
//
<!-- 数据属性,使用闭包函数,隐藏对象的属性 -->
data() {
return {
title: 'Vue3选项式API示例',
counter: 0,
inputText: '',
lastInput: '',
message: 'Hello Vue3!',
createTime: ''
}
},
<!-- 该对象方法属性,配置在mothod中,定义需要绑定在模板中对应的事件中 -->
methods: {
increment() {
this.counter++;
},
decrement() {
this.counter--;
},
updateTime() {
this.createTime = new Date().toLocaleString();
}
},
<!-- 计算属性,定义模板中需要显式的通过计算得到的数据 -->
computed: {
computedMessage() {
return `当前计数是: ${this.counter}`;
},
reversedMessage() {
return this.message.split('').reverse().join('');
}
},
<!-- 监听属性,监听某个数据发生变化时响应的代码 -->
watch: {
counter(newVal, oldVal) {
console.log(`计数器从 ${oldVal} 变为 ${newVal}`);
},
inputText(newVal) {
this.lastInput = newVal;
console.log(`输入内容更新为: ${newVal}`);
}
},
<!-- 生命周期钩子函数,开发者可以在Vue实例的关键节点中插入自定义代码 -->
mounted() {
console.log('mounted: 组件已挂载到DOM');
}
}).mount('#app');
</script>
<style>
body {
font-family: 'Arial', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f7fa;
}
.container {
background: white;
border-radius: 8px;
padding: 30px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
button {
background: #42b983;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
transition: all 0.3s;
}
button:hover {
background: #369f6b;
}
input {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
margin: 5px;
}
</style>
</body>
</html>
由上例可以看书,使用构造函数CreateAPP创建Vue实例,该实例包含一系列属性(Vue提供一套模版),常用属性包括:data,mehtod、computed、watch等。其他属性如:props、compents等属性在后续介绍
- 常用核心语法
在vue实例中使用函数,而非data属性。组件需要独立的数据空间以避免数据污染。若data为对象类型,所有复用的组件实例会共享同一数据空间,导致数据混乱。而函数返回新对象的方式确保每个组件实例拥有独立的数据副本,互不干扰。
Vue模版语法需使用Vue提供的一系列指令完成,vue指令使用前缀"v-"。新建html文件,演示核心语法,包括v-text指令, 大胡子语法{{}} ,数据绑定指令v-bind,v-bind简写 :,双向绑定:v-model,事件绑定:v-on,简写 @等。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue核心语法演示</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>Vue核心语法演示</h1>
<!-- 1. 大胡子语法演示 -->
<div class="demo-card">
<h2>1. 大胡子语法 {{}}</h2>
<p>消息内容: {{ message }}</p>
<p>计算属性: {{ reversedMessage }}</p>
</div>
<!-- 2. v-text指令演示 -->
<div class="demo-card">
<h2>2. v-text指令</h2>
<p v-text="'使用v-text显示: ' + message"></p>
<p>比较显示: <span v-text="message"></span> vs {{ message }}</p>
</div>
<!-- 3. v-bind指令演示 -->
<div class="demo-card">
<h2>3. v-bind数据绑定</h2>
<div>
<input type="color" v-model="bgColor">
<div class="dynamic-style" v-bind:style="{ backgroundColor: bgColor }">
动态样式绑定
</div>
</div>
<div>
<a v-bind:href="url">完整写法绑定</a>
<a :href="url">简写绑定</a>
</div>
</div>
<!-- 4. v-model双向绑定 -->
<div class="demo-card">
<h2>4. v-model双向绑定</h2>
<input v-model="message" placeholder="输入内容...">
<p>实时显示: {{ message }}</p>
<select v-model="selectedOption">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<p>已选择: {{ selectedOption }}</p>
</div>
<!-- 5. 事件绑定 -->
<div class="demo-card">
<h2>5. 事件绑定 v-on/@</h2>
<button v-on:click="showAlert('完整写法')">完整写法</button>
<button @click="showAlert('简写')">简写@</button>
<button @click="counter++">计数器: {{ counter }}</button>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
bgColor: '#42b983',
url: 'https://vuejs.org',
selectedOption: 'A',
options: [
{ text: '选项A', value: 'A' },
{ text: '选项B', value: 'B' },
{ text: '选项C', value: 'C' }
],
counter: 0
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
},
methods: {
showAlert(type) {
alert(`${type}事件绑定被触发!`);
}
}
});
</script>
<style>
body {
font-family: 'Arial', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f8f9fa;
}
.demo-card {
background: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #42b983;
text-align: center;
}
h2 {
color: #35495e;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
input, button, select {
padding: 8px 12px;
margin: 5px 0;
border-radius: 4px;
border: 1px solid #ddd;
}
button {
background-color: #42b983;
color: white;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #369f6b;
}
.dynamic-style {
padding: 15px;
margin: 10px 0;
border-radius: 4px;
transition: all 0.3s;
}
</style>
</body>
</html>
- 生命周期函数
在vue生命周期关键结点上,预设了一些函数,这些函数称作生命周期钩子函数。钩子函数会在生命周期中自动执行,无须使用事件监听。利用钩子函数,开发人员可以在合适的时机执行相应的业务逻辑代码。开发者必须了解生命周期中各个钩子函数执行的时机和条件。新建html文件,演示生命周期函数的执行时机。代码如下:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue3 选项式生命周期演示</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>Vue3 生命周期演示</h1>
<p>当前计数: {{ count }}</p>
<button @click="count++">增加计数</button>
</div>
<script>
const { createApp } = Vue;
const app = createApp({
data() {
return {
count: 0,
messageCount: NaN
};
},
// 选项式生命周期钩子
beforeCreate() {
console.log('beforeCreate vue实例尚未创建,不能读取count数据'+ this.count);
},
created() {
console.log('created,vue实例已创建创建'+ this.count);
},
beforeMount() {
console.log('beforeMount,数据尚未渲染到页面,可以在此提取后台数据,页面可能会出现白屏');
},
mounted() {
console.log('mounted,数据已完成渲染到页面,可以在此提取后台数据,页面可能不会出现白屏');
},
beforeUpdate() {
console.log('beforeUpdate,在内存中的数据更新完成但页面节点尚未更新时触发,此时可以访问内存中的最新数据,但页面渲染的 DOM 还未同步更新 '+ ', 修改后的值为:'+this.count);
},
updated() {
console.log('updated,数据跟新后代码,但页面渲染已完成'+this.count);
},
beforeUnmount() {
console.log('beforeUnmount,实例销毁前,释放资源');
},
unmounted() {
console.log('unmounted,实例销毁后,记录日志');
}
});
app.mount('#app');
</script>
</body>
</html>
- 条件渲染
新建html文件,演示条件渲染,包括v-if v-else,v-show的使用。代码如下:
html
<style>
body {
font-family: 'Arial', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f7fa;
}
.container {
background: white;
border-radius: 8px;
padding: 30px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
}
button {
background: #42b983;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
transition: all 0.3s;
}
button:hover {
background: #369f6b;
}
.user-card {
background: #f8f9fa;
padding: 15px;
margin: 10px 0;
border-radius: 4px;
}
.hidden {
display: none;
}
</style>
- 循环渲染
新建html文件,演示循环渲染。代码如下:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue3 循环渲染演示</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>Vue3 循环渲染演示</h1>
<div class="controls">
<button @click="addItem">添加新项目</button>
<button @click="shuffleItems">随机排序</button>
<button @click="filterEven">筛选偶数ID</button>
<button @click="reset">重置列表</button>
</div>
<div v-for="(item, index) in items" :key="item.id" class="item-card">
<h3>项目 #{{ item.id }}</h3>
<p>名称: {{ item.name }}</p>
<p>创建时间: {{ item.createdAt }}</p>
<button @click="removeItem(index)">删除</button>
</div>
<p v-if="items.length === 0">暂无项目,点击"添加新项目"按钮开始</p>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
items: [
{ id: 1, name: '项目A', createdAt: this.getCurrentTime() },
{ id: 2, name: '项目B', createdAt: this.getCurrentTime() },
{ id: 3, name: '项目C', createdAt: this.getCurrentTime() }
],
nextId: 4
};
},
methods: {
getCurrentTime() {
return new Date().toLocaleTimeString();
},
addItem() {
const names = ['项目X', '项目Y', '项目Z', '项目W'];
const randomName = names[Math.floor(Math.random() * names.length)];
this.items.push({
id: this.nextId++,
name: randomName,
createdAt: this.getCurrentTime()
});
},
removeItem(index) {
this.items.splice(index, 1);
},
shuffleItems() {
this.items = [...this.items].sort(() => Math.random() - 0.5);
},
filterEven() {
this.items = this.items.filter(item => item.id % 2 === 0);
},
reset() {
this.items = [
{ id: 1, name: '项目A', createdAt: this.getCurrentTime() },
{ id: 2, name: '项目B', createdAt: this.getCurrentTime() },
{ id: 3, name: '项目C', createdAt: this.getCurrentTime() }
];
this.nextId = 4;
}
}
}).mount('#app');
</script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.item-card {
background: #f5f5f5;
border-radius: 8px;
padding: 15px;
margin: 10px 0;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: transform 0.2s;
}
.item-card:hover {
transform: translateY(-3px);
}
button {
background: #42b983;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background: #369f6e;
}
.controls {
margin: 20px 0;
}
</style>
</body>
</html>