07 class样式与style样式的三种形态
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
- 字符串
- 数组
- 对象
//<div :class="myClass">hello</div>
//<div :style="myStyle">world</div>
let vm = Vue.createApp({
data() {
return {
myClass1: "box box2",
myClass2: ["box", "box2"],
myClass3: { box: true, box2: true },
myStyle1: "background: red; color: white;",
myStyle2: ["background: red", "color: white"],
myStyle3: { background: "red", color: "white" },
};
},
}).mount("#app");
数组和对象的形式要比字符串形式更加的灵活,也更容易控制变化。比如如果使用字符串class,2秒后要修改删除样式,就只能截取字符串,而使用数组就只需要pop。
08 表单处理与双向数据绑定原理
表单是开发过程中经常要进行操作的,一般需要收集表单数据,发送给后端,或者把后端的数据进行回显等。在 Vue 中是通过 v-model 指令来操作表单的,可以非常灵活的实现响应式数据的处理。
<div id="app"><input type="text" v-model="message" /> {{ message }}</div>
<script>
let vm = Vue.createApp({
data() {
return {
message: "hello",
};
},
}).mount("#app");
</script>
尽管有些神奇,但 v-model 本质上不过是语法糖。可通过 value 属性 + input 事件或 change 事件来实现同样的效果。
<div id="app">
<input type="text" :value="message" @input="message = $event.target.value" />
{{ message }}
</div>
<script>
let vm = Vue.createApp({
data() {
return {
message: "hello",
};
},
}).mount("#app");
</script>
v-model 除了可以处理输入框以外,也可以用在单选框、复选框、以及下拉菜单中。
<div id="app">
<input type="checkbox" v-model="fruits" value="苹果" />苹果<br />
<input type="checkbox" v-model="fruits" value="西瓜" />西瓜<br />
<input type="checkbox" v-model="fruits" value="哈密瓜" />哈密瓜<br />
{{ fruits }
<input type="radio" v-model="gender" value="女" />女<br />
<input type="radio" v-model="gender" value="男" />男<br />
{{ gender }}
<select v-model="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="杭州">杭州</option>
</select>
{{ city }}
</div>
<script>
let vm = Vue.createApp({
data() {
return {
fruits: ["西瓜", "哈密瓜"],
gender: "男",
city: "杭州",
};
},
}).mount("#app");
</script>
09 生命周期钩子函数及原理分析
每个组件在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
就像是工厂的流水线,每个工人站在各自的岗位,当任务流转到工人身边的时候,工人就开始工作。
简单来说生命周期钩子函数就是回调函数,在 Vue 的某个时机去调用对应的回调函数。就像定时器一样,谁调用的定时器的回调函数呢?其实就是定时器内部在调用的。
setTimeout(() => {
console.log("2秒后被执行了");
}, 2000);
生命周期可划分为三个部分:
- 初始阶段:beforeCreate、created、beforeMount、mounted
- 更新阶段:beforeUpdate、updated
- 销毁阶段:beforeUnmout、unmounted
activate 在学 keepalive 的时候再讲,最后 3 个是用于调试的。
<div id="app">{{ message }}</div>
<script>
/* function foo(cb){
//指定的时机去调用回调函数
cb();
}
foo(function(){
// 编写复杂的逻辑1
});
foo(function(){
// 编写复杂的逻辑2
}); */
let vueApp = Vue.createApp({
data() {
return {
message: "hello world",
};
},
beforeCreate() {
// console.log( this.message ); // undefined
// console.log( app.innerHTML ); // 空
},
// 响应式数据准备好后触发的生命周期
created() {
// console.log( this.message ); // ✔
// console.log( app.innerHTML ); // 空
// 响应式数据准备好后再发起ajax
/* setTimeout(()=>{
this.message = 'hi vue';
}, 1000) */
},
beforeMount() {
// console.log( this.message ); // ✔
// console.log( app.innerHTML ); // 空
},
// 等DOM加载完毕后触发的生命周期
mounted() {
// console.log( this.message ); // ✔
// console.log( app.innerHTML ); // ✔
/* setTimeout(()=>{
this.message = 'hi vue';
}, 1000) */
},
beforeUpdate() {
// 在更新数据的时候会触发的生命周期
// console.log( this.message ); // hi vue
// console.log( app.innerHTML ); // hello world
},
updated() {
// DOM更新后再触发
// console.log( this.message ); // hi vue
// console.log( app.innerHTML ); // hi vue
},
beforeUnmount() {
// console.log( this.message );
// console.log( app.innerHTML );
},
unmounted() {
console.log(this.message); // hello world
console.log(app.innerHTML); // ''
},
});
vueApp.mount("#app");
setTimeout(() => {
//vm.message = 'hi vue';
vueApp.unmount();
}, 1000);
</script>
官方提供的生命周期图示
清理定时器、解绑事件等可在销毁阶段来做。
注:一般在,created,mounted 中都可以发送数据请求,但是,大部分时候,会在 created 发送请求。因为这样可以更短的时间去响应数据。