JavaScript入门 vue修饰符/computed/watch/生命周期 Day02

修饰符


修饰符是由  . 点 开头的指令后缀

事件修饰符

.prevent

        阻止超链接默认行为

.stop

        阻止事件传播 

.capture

        添加事件监听器时使用事件捕获模式,即内部元素触发的时间先在此处理器,然后再交由内部元素进行处理

.self

        只当在 event.target 是当前元素自身时触发处理函数,即事件不是从内部元素触发的

表单修饰符

v-model.trim

       去空格

v-model.number

        转数值类型

v-model.lazy

         在“change”时而非“input”时更新,即点击确定后再更新,不是即时更新

键盘事件

@keyup

修饰符事例 

​
        <div id="app">
			<div class="c1">
				<a :href="url" @click.prevent="onConfirm">百度</a><!--阻止a标签默认跳转事件-->
                <p>{{username}}</p>
				<form :action="url" @submit.prevent="onSubmit"><!--阻止表单默认提交事件-->
                    <input type="text" v-model.trim="password"><!--去掉密码前后空格-->
                    <input type="text" v-model.lazy="username"><!--懒-->
					<button type="submit">确定</button>
				</form>
			</div>
            <div class="c2">
                <ul @click="onClickUl">
                    <li @click.stop="onClickLiOne">元素一</li><!--阻止事件传播-->
                </ul>
            </div>
            <div class="c3">
                <input type="text" placeholder="请输入数量" v-model.number="num">
                <button @click="getInputValue">获取值</button>
            </div>
		</div>
		<script src="../lib/vue.global.js"></script>
		<script>
			const { createApp } = Vue
			createApp({
				data() {
					return {
						message: 'vue修饰符',
						url: 'http://www.baidu.com',
                        num:'',
                        password:'',
                        username:''
					}
				},
				methods: {
					onConfirm() {
						// event.preventDefault() //阻止默认行为
						alert('helloworld')
					},
					onSubmit() {
						alert('submit提交事件')
					},
                    onClickLiOne(){
                        alert('click li one')
                        // event.stopPropagation()
                    },
                    onClickUl(){
                        alert('click ul ')
                    },
                    getInputValue(){
                        console.log('num: ',this.num,  typeof this.num);
                    }
				},
			}).mount('#app')
		</script>

​

计算属性computed


定义成方法形式使用,本质上是一个属性

一定有返回值,返回值是计算属性值 

依赖于响应式属性, 当响应式属性值变化自动重新计算

计算属性特点: 缓存数据

计算属性会缓存计算的结果,获取计算属性值先从缓存中获取,只有依赖的响应式属性变化时才重新计算

默认只读,若要可写,写成对象形式,设置getter setter方法

computed:{ isBooks(){  //默认只读值 isBooks()是computed方法中定义的计算属性

        return value   // 必须要有'return'值

        //计算属性方法体中,用到响应式属性,只要数据变化,计算属性自动重新执行

} }

<div id="app">
			<h2>作者{{author.name}}是否出版本书籍?</h2>
			<p>已出版本书籍 显示yes否则显示no</p>
			<h3>出版本书籍情况: <span>{{ isBooks }}</span></h3> //isBooks是computed中的计算属性
            <h3>{{fullName}}</h3>
            <button @click="updateIsBooks">确定</button>
		</div>
		<script src="../lib/vue.global.js"></script>
		<script>
			const { createApp } = Vue
			const app =createApp({
				data() {
					return {
						author: {
							name: 'John Doe',
							books: ['javascript高级编程', 'css入门', 'vue3高级编程'],
						},
                        firstName:'Doe'                   
					}
				},
				methods: {
                    updateIsBooks(){
                        this.isBooks = 'no'
                        this.fullName = '张三'
                        console.log(this.isBooks);
                    }
                },
                computed:{
                    isBooks(){
                        console.log('计算属性值');
                        return this.author.books.length>0?'Yes':'No'
                    },
                    // 定义成geter seter形式
                    fullName:{
                        get(){
                            console.log('get >>>');
                            return this.firstName  //获取依赖的属性值
                        },
                        set(value){
                            console.log('value ',value)
                            this.firstName = value //改变依赖的属性的值 
                        }                
                    }
                }
			}).mount('#app')
		</script>

 使用computed完成总价的计算

		<div id="app">
			<table class="y-table">
				<tr>
					<th>序号</th>
					<th>名称</th>
					<th>价格</th>
					<th>数量</th>
					<th>总价</th>
					<th>操作</th>
				</tr>
				<tr v-for="(item,index) in list">
					<td>{{item.id}}</td>
					<td>{{item.name}}</td>
					<td>{{item.price}}</td>
					<td>
						<input type="text" value="-" />
						<input type="text" v-model="item.num" />
						<input type="text" value="+" />
					</td>
					<td>{{ item.price * item.num }}</td>
					<td><a href="javascript:void(0)">删除</a></td>
				</tr>
			</table>
			<h2>商品总价:{{total}}</h2> <!--total是计算属性-->
			<!-- Form 表单 -->
			<form class="y-form">
				<div class="y-form-item">
					<label for="id">序号:</label>
					<input type="text" class="y-input-parmary" />
				</div>
				<div class="y-form-item">
					<label for="name">书名:</label>
					<input type="text" class="y-input-parmary" />
				</div>
				<div class="y-form-item">
					<label for="price">价格:</label>
					<input type="text" class="y-input-parmary" />
				</div>
				<div class="y-form-item">
					<label for="num">数量:</label>
					<input type="text" class="y-input-parmary" />
				</div>

				<div class="y-form-item">
					<a href="#" class="y-btn-primary">添加</a>
				</div>
			</form>
		</div>
		<script src="../lib/vue.global.js"></script>
		<script>
			const { createApp } = Vue
			const vm = createApp({
				data() {
					return {
						list: [
							{ id: 1001, name: 'vue高级编程', price: 88.88, num: 2 },
							{ id: 1002, name: 'react高级编程', price: 98.48, num: 1 },
							{ id: 1003, name: 'js高级编程', price: 68.08, num: 3 },
						],
					}
				},
				methods: {},
				computed: {
					total() {
						let totalPrice = this.list.reduce((previus, current) => previus + current.price * current.num,0)
						return totalPrice.toFixed(2)
					},
				},
			}).mount('#app')
		</script>

侦听属性 watch


侦听Vue 实例上data中的数据和一些非DOM元素改变
可以获取数据改变前的值和改变后的值

    const { createApp } = Vue
			const app = createApp({
				data() {
					return {
						username: 'jack',
					}
				},
				//侦听器 响应式属性
				watch: {
					username(newValue, oldValue) { //改变前的值,改变后的值
						console.log('newValue ', newValue, ' oldValue ', oldValue)
					},
				},
			}).mount('#app')

 侦听属性搜索事例

<div id="app">
			<input type="text" placeholder="请输入搜索内容" v-model.lazy="keyword" />
		</div>
		<script src="../lib/vue.global.js"></script>
		<script src="../lib/axios.min.js"></script>
		<script>
			const { createApp } = Vue
			const app = createApp({
				data() {
					return {
						keyword: '',
					}
				},
				//侦听器 响应式属性
				watch: {
					keyword(newValue, oldValue) {
						axios({
							method: 'get',
							url: 'https://api.yuguoxy.com/api/shop/search',
							params: {
								keyword:newValue,
							},
						}).then(res => {
							console.log(res.data)
						})
					},
				},
			}).mount('#app')
		</script>

immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项。

immediate:true   立即侦听

停止观察

watch函数接收两个参数,然后函数执行以后,会返回一个WatchStopHandle(停止观察的处理器)对象

const stopWatchCallback = watch(
                // 第一个参数是要监听的数据
                firstValue,
                // 第二个参数是监听的处理函数
                // 处理函数的参数:第一个参数是当前值,第二个参数为更新前的值
                function(newValue, oldValue) {
                    second.list = Array(5).fill().map((_, i) => {
                        return {
                            id: newValue + i,
                            name: newValue + '课程' + i,
                            value: newValue + i
                        }
                    })
                }
            )
 stopWatchCallback()//调用执行

deep 选项

如果侦听对象的属性,就要使用deep深度侦听才能获取到对象的属性,下方data的keyword是单个字符串就不需要deep,user是对象就需要。

		<div id="app">
			<input type="text" placeholder="请输入搜索内容" v-model.lazy="keyword" />
		</div>
		<script src="../lib/vue.global.js"></script>
		<script src="../lib/axios.min.js"></script>
		<script>
			const { createApp } = Vue
			const app = createApp({
				data() {
					return {
						keyword: '衣',
						user: {
							name: 'jack',
							age: 18,
						},
					}
				},
				//侦听器 响应式属性
				watch: {
					keyword: {
						handler(newValue) {
							axios({
								method: 'get',
								url: 'https://api.yuguoxy.com/api/shop/search',
								params: {
									keyword: newValue,
								},
							}).then(res => {
								console.log(res.data)
							})
						},
						immediate: false, // 立刻侦听 为true是立即监听
					},
					// 侦听对象属性值变化,开启深度侦听
					user: {
						handler(newValue) {
							console.log('newValue >>>> ',newValue)
						},
						deep:true // 深度侦听 
					},
					// 侦听user对象age属性
					'user.age':{
						handler(newValue){
							console.log('user.age >>> ',newValue);
						}
					}
				},
			}).mount('#app')

computed 和 watch区别[面试]

watch可以取代computed,watch更多是响应数据,但是和computed相比性能会降低,并且watch不会有返回结构,需要单独定义变量来进行缓存。

computed不能取代watch,watch是观察一个值的变化,再去执行一个业务,这业务可以是异步甚至没有返回值

生命周期


vue实例开始创建->数据初始化->挂载->渲染->更新->渲染->销毁 所经过的一系列过程统称为生命周期,强调的是一个时间段。简单说就是创建->挂载->更新->销毁四个阶段,每个阶段都有之前和之后,共八个生命周期。

生命周期是一个过程,是指虚拟dom的生命周期,更新生命周期只有当一个值绑定到虚拟dom,以后的更新,才会触发。created赋值不会二次渲染,mounted赋值会二次渲染

生命周期函数:是由 vue 框架提供的内置函数,会伴随着生命周期,自动按次序执行

注: 生命周期强调的是时间段,生命周期函数强调的是时间点

生命周期函数的分类

1.创建期间的生命周期钩子函数

beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 

**created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板。赋值不会造成二次渲染

2.挂载期间的生命周期钩子函数

beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中

**mounted[操作vue生命周期节点]:此时,已经将编译好的模板,挂载到了页面指定的容器中显示,操作节点,会造成二次渲染,但可以获取到dom元素。

创建和挂载生命周期只会在组件初始化的时候执行一次,后边的所有操作都是更新生命周期

3.更新期间的生命周期函数

beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点

updated:更新生命周期只有当一个值绑定到虚拟dom,以后的更新,才会触发。实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了

4.销毁期间的生命周期函数

beforeUnmount:实例销毁之前调用。在这一步,实例仍然完全可用。这个生命周期可以获取虚拟dom所以常用

Unmounted:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。卸载生命周期常用于事件解绑、定时器销毁、大数据销毁等业务

const { createApp } = Vue
			const app = createApp({
				data() {
					return {
						message: '生命周期',
					}
				},
				methods: {
					test() {
						console.log('test')
					},
				},
				//beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
				beforeCreate() {
					console.log('beforeCreate :', this.message)
				},
				//实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
				created() {
					console.log('created :', this.message)
				},
                //此时已经完成了模板的编译,但是还没有挂载到页面中
                beforeMount() {
                    console.log('beforeMount :',)
                },
                //此时,已经将编译好的模板,挂载到了页面指定的容器中显示
                mounted() {
                    console.log('mounted :',  document.querySelector('h2'))
                },
                //状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
                beforeUpdate() {
                    console.log('beforeUpdate >>>>');
                },
                //实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
                updated() {
                    console.log('updated >>>>');
                },
                //实例销毁之前调用。在这一步,实例仍然完全可用。
                beforeUnmount(){
                    console.log('beforeUnmount >>>>');
                },
                //实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
                unmounted(){
                    console.log('unmounted >>>>');
                }
			}).mount('#app')

生命周期事例

		<div id="app">
			<table class="y-table">
				<tr>
					<th>序号</th>
					<th>名称</th>
					<th>图片</th>
					<th>价格</th>
					<th>分类</th>
					<th>操作</th>
				</tr>
				<tr v-for="(item,index) in list">
					<td>{{item.id}}</td>
					<td>{{item.shop}}</td>
					<td><img :src="item.picture" alt="" /></td>
					<td>¥{{item.price}}</td>
					<td>{{ item.categoryname }}</td>
					<td><a href="javascript:void(0)">删除</a></td>
				</tr>
			</table>
		</div>
		<script src="../lib/vue.global.js"></script>
		<script src="../lib/axios.min.js"></script>
		<script>
			const { createApp } = Vue

			const app = createApp({
				data() {
					return {
						list: [], //商品数组
					}
				},
				methods: {
					/**
					 * 获取商品列表
					 */
					async getProductList() {
						let res = await axios({
							method: 'get',
							url: 'https://api.yuguoxy.com/api/shop/list',
						})

						const { resultCode, resultInfo } = res.data
						if (resultCode == 1) {
							let list = resultInfo.list
							this.list = list
						}
					},
				},
				created() {
					this.getProductList()
				},
			}).mount('#app')
		</script>
			.y-table {
				text-align: center;
				margin: 100px auto;
			}
			.y-table img {
				width: 100px;
				height: 100px;
			}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值