内置指令(v-if/v-else-if/v-else/v-show)、双向绑定、侦听器、生命周期
提示:以下是本篇文章正文内容,下面案例可供参考
<div id="first" v-cloak>
<div class="in-box">
姓名: <input type="text" v-model="name" placeholder="请输入姓名">
性别: <input type="radio" v-model="gender" value="female"> 女士
<input type="radio" v-model="gender" value="male"> 先生
<input type="radio" v-model="gender" value="unknow"> 未知
div>
<div class="condition">
<div v-if="gender == 'female'" class="welcome female">欢迎{{name}}女士div>
<div v-else-if="gender == 'male'" class="welcome male">欢迎{{name}}先生div>
<div v-else>欢迎{{name}}div>
div>
<div class="show">
<div v-show="gender == 'female'" class="welcome female">欢迎{{name}}女士div>
<div v-show="gender == 'male'" class="welcome male">欢迎{{name}}先生div>
div>
div>
<a href="https://cn.vuejs.org/api/built-in-directives.html#v-if">vue.js API: 内置指令(v-if/v-else-if/v-else/v-show)a>
<script src="[email protected]" type="text/javascript">script>
<script>
const options = {
data() {
return {
name: '阿芳',
gender: 'female'
}
},
methods: {},
computed: {}
}
Vue.createApp(options).mount( '#first' );
script>
<div v-if="gender == 'female'" class="welcome female">欢迎{{name}}女士div>
v-if 会和 v-else-if 、 v-else 相伴出现,也可以单独出现。
<div v-else-if="gender == 'male'" class="welcome male">欢迎{{name}}先生div>
<div v-else>欢迎{{name}}div>
<div v-show="gender == 'female'" class="welcome female">欢迎{{name}}女士div>
<div v-show="gender == 'male'" class="welcome male">欢迎{{name}}先生div>
虽然 v-if 和 v-show 都是互斥条件,但 v-if 是在满足条件后在深层要显示的内容;但 v-show 是先将所有内容生成,然后根据条件调整内容的可见性,从而实现根据条件显示内容。
<p v-once>{{name}}, {{gender}}p>
仅在开始时渲染一次,之后不管页面中怎么改变,通过 v-once 修饰的标签(组件)是没有动态变化的。
<input v-bind:type="inputType" placeholder="请输入密码" v-model="passwd">
<button v-on:click="toggle">{{buttonText}}button>
通过点击按钮进行对 input 标签进行内容格式的变化(当满足条件后应该怎么做,否则应该怎么做):
methods: {
toggle() {
if( this.inputType === 'text' ) {
this.inputType = 'password';
this.buttonText = '显示密码';
return;
}
this.inputType = 'text';
this.buttonText = '隐藏密码';
}
}
其中可以绑定:
<div class="row">
<span>爱好span>
<input type="checkbox" v-model="hobby" value="eat"> 吃
<input type="checkbox" v-model="hobby" value="eat-ji"> 吃鸡
<input type="checkbox" v-model="hobby" value="sleep"> 睡
div>
例如,将 input 中的值赋给一个名叫 name 的属性中:
<div class="row">
<span>姓名span>
<input type="text" v-model="name">
div>
通过标签划分分组:
<div class="row">
<span>省份span>
<select v-model="province">
<optgroup label="省">
<option value="gansu">甘肃省option>
<option value="sichuan">四川省option>
<option value="shaanxi">陕西省option>
<option value="shanxi">山西省option>
<option value="henan">河南省option>
<option value="hubei">湖北省option>
optgroup>
<optgroup label="直辖市">
<option value="chongqing">重庆市option>
optgroup>
<optgroup label="自治区">
<option value="ningxia">宁夏回族自治区option>
<option value="neimenggu">内蒙古自治区option>
optgroup>
select>
div>
可以通过 添加分组标签,在 value 属性中确定值的来源。
之后将接收的值存放进对象中,多个选项的放进数组中,而 province 中的值是 中的 value属性中确定的,将值绑定在一起:
return {
name: '王某然',
gender: 'male',
hobby: [ 'eat', 'sleep' ],
province: 'gansu',
confession: '我交代...'
}
const input = document.querySelector('input[type=text]');
const second = document.querySelector('.second');
创建一个 Object 实例,为了之后存放属性值:
const stu = Object.create(null);
之后通过 Object.defineProperty(对象, 属性名, 属性描述符 )
方法确定对象中属性的属性描述符:
Object.defineProperty(stu, '_content', {
value: '', enumerable: true, configurable: true, writable: true
});
Object.defineProperty(stu, 'content', {
enumerable: true,
configurable: true,
get() {
console.log('geter');
return stu._content;
},
set(value) {
console.log('setter');
stu._content = value;
second.innerHTML = stu._content;
if( stu._content != input.value ) {
input.value = stu._content;
}
}
}
也可以将对象的属性设置为唯有变量,之后通过 getter/setter 方法为其赋值,以及取值:
class Data {
// 以`#`为前缀的属性是私有属性
#content = 12345;
// getter
get content(){
console.log('getter');
return this.#content;
}
// setter
set content(value) {
console.log('setter');
this.#content = value;
}
}
通过在属性前加 # 将属性设置为唯有变量,虽然在浏览器中是可以看到的,但在 node 中是是无法查看的。
data() {
return {
kilogram: '',
jin: '',
length: {
meter: 0,
centimetre: 0
},
time: {
hours: 0,
shiChen: 0
}
}
},
把要绑定的值通过内置指令 v-model 将其指定:
<span>
<input type="text" v-model="kilogram">千克
span>
<span>
<input type="text" v-model="jin">斤
span>
div>
<div class="length">
<span>
<input type="text" v-model="length.meter">米
span>
<span>
<input type="text" v-model="length.centimetre">公分
span>
div>
<div class="time">
<span>
<input type="text" v-model="time.hours">小时
span>
<span>
<input type="text" v-model="time.shiChen">时辰
span>
当侦测到要侦测的值发生变化时,进行操作:
// 侦听器
watch: {
// 监听 kilogram 属性的变化
kilogram(){
console.log('watch kilogram');
this.jin = this.kilogram * 2 ;
},
jin(){
console.log('watch jin');
this.kilogram = this.jin / 2 ;
},
// 监听 meter 属性的变化并指定 meter 变化后调用的方法
'length.meter': 'meterChanged',
'length.centimetre': 'centimetreChanged' },
之后设定生命周期钩子,通过组件的 $watch 函数绑定侦听器
mounted() {
const self = this;
// 通过组件的 $watch 函数绑定侦听器
self.$watch( 'time.hours', value => {
console.log( value );
self.time.shiChen = value / 2 ;
});
self.$watch( 'time.shiChen', value => {
console.log( value );
self.time.hours = value * 2 ;
});
}
}
Vue
实例有一个完整的生命周期,也就是从开始创建初始化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue
的生命周期。
声明周期钩子: 就是生命周期事件的别名而已
beforeCreate
在组件实例初始化完成之后立即调用。
beforeCreate() {
console.log( 'beforeCreate' );
console.log( '\t', 'username: ', this.surname );
console.log( '\t', 'show: ', this.show );
console.log( '\t', 'fullName: ', this.fullName );
// 将当前组件(即根组件)保存到root变量中
root = this;
},
created() {
console.log( 'created' );
console.log( '\t', 'username: ', this.surname );
console.log( '\t', 'show: ', this.show );
console.log( '\t', 'fullName: ', this.fullName );
},
beforeMount
在组件被挂载之前调用。
beforeMount() {
console.log( 'beforeMount');
console.log( '\t', '$el: ', this.$el );
},
在组件被挂载之后调用。
mounted() {
console.log( 'mounted' );
console.log( '\t', '$el: ', this.$el );
},
beforeUpdate
在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用。
beforeUpdate() {
console.log( 'beoferUpdate');
console.log( '\t', 'surname:', this.surname );
let input = document.querySelector('#surname');
console.log( '\t', 'input.value:', input.value );
},
updated() {
console.log( 'updated' );
console.log( '\t', 'surname:', this.surname );
let input = document.querySelector('#surname');
console.log( '\t', 'input.value:', input.value );
},
beforeUnmount
在一个组件实例被卸载之前调用。
beforeUnmount() {
console.log( 'beforeUnmount');
console.log( '\t', document.querySelector('.wrapper') );
},
unmounted() {
console.log( 'unmounted' );
console.log( '\t', document.querySelector('.wrapper') );
}
其实有关生命周期的方法有很多:
unmounted
:在一个组件实例被卸载之后调用。errorCaptured
:在捕获了后代组件传递的错误时调用。renderTracked
(Dev only) : 在一个响应式依赖被组件的渲染作用追踪后调用。renderTriggered
(Dev only) : 在一个响应式依赖被组件触发了重新渲染之后调用。(这个钩子仅在开发模式下可用,且在服务器端渲染期间不会被调用。)activated
:若组件实例是
缓存树的一部分,当组件被插入到 DOM 中时调用。(这个钩子在服务端渲染时不会被调用。)deactivated
:若组件实例是
缓存树的一部分,当组件从 DOM 中被移除时调用。(这个钩子在服务端渲染时不会被调用。)serverPrefetch
(SSR only
):当组件实例在服务器上被渲染之前要完成的异步函数。