Vue 的入门,发现不是很难,其实只要是有对应的编程语言基础,将其进行类比,学习起来还是很简单的。不过开始的时候是通过引入 vue.js 来学习,后期要真正的使用 Vue 去开发网页的时候,将使用的是 vite 或者基于 webpack 的 vue 脚手架进行开发

初学时很简单,引入以下 js 文件

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js" type="text/javascript" charset="utf-8"></script>

Hello World

我没使用 cdn ,我使用的是本地的 vue.js 文件

通过 {{}} 来读取 data 属性中的内容。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<h3>{{msg}}</h5>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					msg: "Hello xiaohehe",
                }
            });
        </script>
    </body>
</html>

条件判断

条件判断使用 v-if、v-else-if、v-else 就和使用 if、else if、else 一样的。猜猜在网页上输出的结果是什么呢?

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<h3 :title="msg">{{msg}}</h5>
			<!-- if else -->
			<div>
				<p v-if="score < 60">不及格</p>
				<p v-else-if="score < 70">及格</p>
				<p v-else-if="score < 80">普通</p>
				<p v-else-if="score < 90">良好</p>
				<p v-else-if="score < 100">优秀</p>
				<p v-else>完美</p>
			</div>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					score: 60,
                }
            });
        </script>
    </body>
</html>

循环

循环使用的是 v-for 去循环的,比如 v-for="g in grades" 其中 v-for 右边的值所代表的意义是,g 在 grade 的里面。也就是说将 grade 数组中的元素挨个遍历出来。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
    <body>
        <table border="1">
            <thead>
                <tr>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>性别</th>
                    <th>分数</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="g in grades">
                    <td>{{g.name}}</td>
                    <td>{{g.age}}</td>
                    <td>{{g.sex}}</td>
                    <td>{{g.score}}</td>
                    <a href="javascript:void(0)" @click="showDetail">查看详情</a>
                </tr>
            </tbody>
        </table>
        <script>
        	var vm = new Vue({
				el: "#box",
				data: {
					grades: [
						{
							name: "xiaohehe",
							age: "22",
							sex: "男",
							score: 100,
						},
						{
							name: "xiaozhezhe",
							age: "22",
							sex: "男",
							score: 90,
						},
					]
                }
            })
        </script>
    </body>
</html>

单向数据绑定和双向数据绑定

单向绑定使用的是 v-bind ,而双向绑定使用的是 v-model 。

单向数据绑定

使用方法:v-bind:属性名="值" ,比如我要给 h3 标签添加 title 属性。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<h3 v-bind:title="msg">{{msg}}</h5>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					msg: "Hello xiaohehe",
                }
            });
        </script>
    </body>
</html>

当然,v-bind 可以去掉,也就是说 h3 标签对中可以这样

<h3 :title="msg">{{msg}}</h5>

双向数据绑定

使用方法:v-model="值" ,常用于各种输入框。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<!-- 普通输入框 -->
				<p>
					<input placeholder="" v-model="value1" type="text"/>&nbsp;{{value1}}
				</p>
				<!-- 单选框 -->
				<p>
					<input name="gender" v-model="value2" value="" type="radio" /><input name="gender" v-model="value2" value="" type="radio" /><br> 你的性别是:{{value2}}
				</p>
				<!-- 多选框 -->
				<p>
					<input name="gender" v-model="value3" value="" type="checkbox" /><input name="gender" v-model="value3" value="" type="checkbox" /><input name="gender" v-model="value3" value="rap" type="checkbox" />rap
					<input name="gender" v-model="value3" value="篮球" type="checkbox" />篮球
					<br> 你的爱好是:{{value3}}
				</p>
				<!-- 下拉选择框 -->
				<p>
					<select v-model="value4">
						<option value="">请选择你的老婆</option>
						<option value="香风智乃">香风智乃</option>
						<option value="血小板妹妹">血小板妹妹</option>
						<option value="御坂">御坂</option>
						<option value="莹草老师">莹草老师</option>
					</select>
					你选择的老婆是:{{value4}}
				</p>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					value1: "",
					value2: "",
					value3: [],
					value4: "",
                }
            });
        </script>
    </body>
</html>

事件与方法

使用 v-on 来触发事件,如果是点击事件,则 v-on:click="方法名" 。如果要自己写一个方法,那么需要在 Vue 对象中,创建一个 methods 属性 ,里面写的是方法。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<button v-on:click="showMessgae">打开对话框</button>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					msg: "Hello xiaohehe",
                },
                // 方法
                methods: {
					showMessgae: function() {
						alert(this.data);
					}
                }
            });
        </script>
    </body>
</html>

还有一种更简单的写法,使用 @事件名='方法名' ,比如 @click=”方法名” 。

<button @click="showMessgae">打开对话框</button>

计算属性

写法和方法类似,但还是有区别的。计算属性的性质和变量一样,而方法在调用的时候必须要加一个括号。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<p>{{showMessgae()}}</p>
            <p>{{currentTimeStamp}}</p>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					msg: "Hello xiaohehe",
                },
                // 方法
                methods: {
					showMessgae: function() {
						return Date.now();
					}
                },
                // 计算属性
                computed: {
                    // ES6 语法
					currentTimeStamp() {
						return Date.now();
					}
				}
            });
        </script>
    </body>
</html>

请求发送

请求发送使用的是 axios 来发送的。发送 get 请求就 axios.get ,post 请求时就 axios.post 。通过调用 then 方法来接收服务端的响应,最终展示到页面上。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<p>
                最近更新日期:{{weather.lastUpdate}}<br>
                城市:{{weather.location.name}}<br>
                地点:{{weather.location.path}}<br>
            </p>
        </div>
        <script>
        	// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					weather: {},
                },
                mounted: function(){
					axios.get("http://weather.cma.cn/api/weather/")
					.then((response) => {
						console.log(response);
						if(response.data.code === 0) {
							this.weather = response.data.data;
						}
					});
				},
            });
        </script>
    </body>
</html>

自定义组件与数据传递

自定义组件就像是编程中的方法封装,就是将使用频繁,重复的代码将其封装到方法中。Vue.component 就和它类似。这样一来,前端的代码也可以通过模块化的方式开发了。

通过它来注册一个组件。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<div>
				<!-- 自定义组件 -->
				<grade-xiaohehe @details="getDetail" v-bind:grades="grades"></grade-xiaohehe>
			</div>
		</div>
		<script>
			// 注册组件
			Vue.component('grade-xiaohehe', {
				props: ['grades'], // 父传子使用 props 
				template: `
				<table border="1">
					<thead>
						<tr>
							<th>姓名</th>
							<th>年龄</th>
							<th>性别</th>
							<th>分数</th>
							<th>操作</th>
						</tr>
					</thead>
					<tbody>
						<tr v-for="g in grades">
							<td>{{g.name}}</td>
							<td>{{g.age}}</td>
							<td>{{g.sex}}</td>
							<td>{{g.score}}</td>
							<a href="javascript:void(0)" @click="showDetail">查看详情</a>
						</tr>
					</tbody>
				</table>
				`,
				methods: {
					showDetail() {
						this.$emit("details", {name: "xiaohehe", score: 100}); // 子传父使用 $emit 方法,通过触发自定义事件来传值,
					}
				}
			});
			// vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					weather: {}
				},
				methods: {
					getDetail(data) {
						alert("姓名:" + data.name + ", 得分:" + data.score);
					}
				},
				mounted: function(){
					axios.get("http://weather.cma.cn/api/weather/")
					.then((response) => {
						console.log(response);
						if(response.data.code === 0) {
							this.weather = response.data.data;
						}
					});
				}
			});
		</script>
	</body>
</html>

在上述的代码中,有出现数据传递,也就是所谓的“父传子”和“子传父”了。

如果是从 Vue 实例中的数据传递到自己注册的组件中(父传子),则需要使用 props;如果是子传父则使用 $emit 方法,通过触发自定义事件来传值。

插槽

在注册的组件中个,我们还可以在自己注册的组件中使用 slot 标签对用于注册组件。如果要插入一段 html 的代码在插槽中,则必须使用 template 标签对将需要插入的代码放到里面去,这样才会生效。

如果插槽中放入的是我们自定义的组件的话,那么就不要用 template 标签对将其包裹起来。

如果在我们自定义的组件中定义多个插槽,那么则需要对每一个插槽进行命名,然后通过插槽名字来对应其插槽。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="box">
			<!-- 插槽 -->
            <p>
                <weather-days>
                    <template slot="weather-head">
                        <tr>
                            <th>日期</th>
                            <th>天气</th>
                            <th>风向</th>
                            <th>温度</th>
                            <th>白天风速</th>
                            <th>夜间风速</th>
                        </tr>
                    </template>
                    <template slot="weather-item">
                        <tr v-for="detail in weather.daily">
                            <td>{{detail.date}}</td>
                            <td>{{detail.dayText}} 转 {{detail.nightText}}</td>
                            <td>{{detail.dayWindDirection}}</td>
                            <td>{{detail.low}} - {{detail.high}}℃</td>
                            <td>{{detail.dayWindScale}}</td>
                            <td>{{detail.nightWindScale}}</td>
                        </tr>
                    </template>
                </weather-days>
            </p>
        </div>
        <script>
        	// 注册日期组件
			Vue.component('weather-days', {
				template: `
				<table border="1">
					<thead>
						<slot name="weather-head"></slot>
					</thead>
					<tbody>
						<slot name="weather-item"></slot>
					</tbody>
				</table>
				`
			});
            
            // vue 对象
			var vm = new Vue({
				el: "#box",
				data: {
					weather: {}
				},
				mounted: function(){
					axios.get("http://weather.cma.cn/api/weather/")
					.then((response) => {
						console.log(response);
						if(response.data.code === 0) {
							this.weather = response.data.data;
						}
					});
				}
        </script>
    </body>
</html>