一、计算属性(computed)
某些结果是基于之前数据
实时计算
出来的, 我们可以利用计算属性来完成,下面这个例子可以实现:
改变数量时,总价自动实时变更。
<div id="app">
<ul>
<li>西游记: 价格{{xyjPrice}}, 数量:<input type="number" v-model="xyjNum"></li>
<li>水浒传: 价格{{shzPrice}}, 数量:<input type="number" v-model="shzNum"></li>
<li>总价: {{totalPrice}}</li>
</ul>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
xyjPrice: 56.73,
shzPrice: 47.98,
xyjNum: 1,
shzNum: 1
},
computed: {
totalPrice() {
return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum;
}
}
})
</script>
二、侦听(watch)
watch 可以监控一个值的变化。 从而做出相应的反应。
<div id="app">
<ul>
<li>西游记: 价格{{xyjPrice}}, 数量:<input type="number" v-model="xyjNum"></li>
<li>水浒传: 价格{{shzPrice}}, 数量:<input type="number" v-model="shzNum"></li>
<li>总价: {{totalPrice}}</li>
{{msg}}
</ul>
</div>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
xyjPrice: 56.73,
shzPrice: 47.98,
xyjNum: 1,
shzNum: 1,
msg: ""
},
computed: {
totalPrice() {
return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum
}
},
watch: {
xyjNum(newVal, oldVal) {
if (newVal >= 3) {
this.msg = "库存超出限制";
this.xyjNum = 3;
} else {
this.msg = "";
}
}
}
})
</script>
三、过滤器(filters)
过滤器不改变真正的
data
, 而只是改变渲染的结果, 并返回过滤后的版本。 在很多不同的情况下, 过滤器都是有用的, 比如尽可能保持 API 响应的干净, 并在前端处理数据的格式。
<body>
<div id="app">
<table>
<tr v-for="user in userList">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.gender | genderFilter}}</td>
</tr>
</table>
</div>
</body>
<script>
// Vue.filter("genderFilter", function (val) {
// if (val == 1) {
// return "男~~";
// } else {
// return "女~~";
// }
// })
let app = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
}
,
filters: {
genderFilter(val) {
if (val == 1) {
return "男";
} else {
return "女";
}
}
}
});
</script>
四、Vue组件化
在 vue 中, 所有的 vue 实例都是组件。可以把页面的不同部分拆分成独立的组件, 然后在不同页面就可以共享这些组件, 避免重复开发。
- 组件其实也是一个 Vue 实例, 因此它在定义时也会接收:
data
、methods
、生命周期函数
等。 - 组件不会与页面的元素绑定, 否则就无法复用了, 因此
组件没有 el 属性
。 - 组件渲染需要 html 模板, 所以
增加了 template 属性
, 值就是 HTML 模板。 - 全局组件定义完毕, 任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了。
data 必须是一个函数
, 不再是一个对象。
全局组件
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
</div>
<script type="text/javascript">
// 定义全局组件, 两个参数: 1, 组件名称。 2, 组件参数
Vue.component("counter", {
template: '<button v-on:click="count++">你点了我 {{ count }} 次, 我记住了.</button > ',
data() {
return {
count: 0
}
}
})
let app = new Vue({
el: "#app"
})
</script>
</body>
局部组件
采用全局注册, 就意味着即便以后不再使用这个组件, 它依然会随着 Vue 的加载而加载。因此, 对于一些并不频繁使用的组件,通常采用局部注册。
- 先在外部定义一个对象, 结构与创建组件时传递的第二个参数一致,然后将定义的对象注册为组件。
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
</div>
<script type="text/javascript">
// 定义全局组件, 两个参数: 1, 组件名称。 2, 组件参数
const counter = {
template: '<button v-on:click="count++">你点了我 {{ count }} 次, 我记住了.</button > ',
data() {
return {
count: 0
}
}
};
let app = new Vue({
el: "#app",
components:{
// 将定义的对象注册为组件.
counter : counter
}
})
</script>
五、生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程 : 创建实例, 装载模板, 渲染模板等。 Vue为生命周期中的每个状态都设置了钩子函数(监听函数) 。 每当 Vue 实例处于不同的生命周期时, 对应的函数就会被触发调用。
<body>
<div id="app">
<span id="num">{{num}}</span>
<button v-on:click="num++">赞! </button>
<h2>
{{name}}, 非常帅! ! ! 有{{num}}个人点赞。
</h2>
</div>
</body>
<script>
let app = new Vue({
el: "#app",
data: {
name: "张三",
num: 100
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {
console.log("=========beforeCreate=============");
console.log("数据模型未加载: " + this.name, this.num);
console.log("方法未加载: " + this.show());
console.log("html 模板未加载:" + document.getElementById("num"));
},
created: function () {
console.log("=========created=============");
console.log("数据模型已加载: " + this.name, this.num);
console.log("方法已加载: " + this.show());
console.log("html 模板已加载:" + document.getElementById("num"));
console.log("html 模板未渲染:" + document.getElementById("num").innerText);
},
beforeMount() {
console.log("=========beforeMount=============");
console.log("html 模板未渲染:" + document.getElementById("num").innerText);
},
mounted() {
console.log("=========mounted=============");
console.log("html 模板已渲染:" + document.getElementById("num").innerText);
},
beforeUpdate() {
console.log("=========beforeUpdate=============");
console.log("数据模型已更新: " + this.num);
console.log("html 模板未更新:" + document.getElementById("num").innerText);
},
updated() {
console.log("=========updated=============");
console.log("数据模型已更新: " + this.num);
console.log("html 模板已更新:" + document.getElementById("num").innerText);
}
});
</script>