Vue.js框架(二)
一、 v-on的修饰符
<body><div id='app'><div @click='divHandle'><button @click.stop='buttonHandle'>按钮</button></div></div>
</body>
@click.stop => 修饰符.阻止冒泡
@click.prevent => 修饰符.阻止默认事件
@click.prevent.stop => 修饰符.阻止默认事件和冒泡
<script src="js/vue.js"></script><script>new Vue({el: "#app",methods: {buttonHandle(ev) {// 阻止冒泡// ev.stopPropagation();console.log('按钮被点')},divHandle() {console.log('div被点')}}})</script>
二、 v-model的修饰符
<body><div id='app'><!-- <input type="text" :value='msg' @input='setMsg'> --><!-- <input type="text" v-model='msg'> --><hr><!-- <input type="text" :value='msg' @change='setMsg'> --><input type="text" v-model.lazy.trim.number='msg'><div>{{msg}}</div></div>
</body>
:value='msg' => 数据变,视图也跟着变
@input='setMsg' => 视图变,数据也跟着变.
v-model实际上是上面两个操作的语法糖.
lazy => change事件触发时才会修改vue数据.(输入完成之后,再修改vue数据msg)
<script>new Vue({el: "#app",data: {msg: ''},methods: {setMsg(ev) {this.msg = ev.target.value}}})</script>
三、 v-for
<body><div id='app'><ul><li v-for='item in 3'>{{item}}</li></ul><ul><li v-for='item in "abcd"'>{{item}}</li></ul></div>
</body>
<script src="js/vue.js"></script><script>new Vue({el: '#app', })</script>
四、 v-once
<body><div id='app'><button @click='fn'>按钮</button><div v-once>{{msg}}</div><div>{{msg}}</div></div>
</body>
v-once => 视图只更新一次,后续绑定的数据变化,不会更新当前的视图
v-once没有指令的值.
<script src="js/vue.js"></script><script>new Vue({el: '#app',data: {msg: 10},methods: {fn() {this.msg = Math.random();}}})</script>
五、 v-html
<body><div id='app'><div>{{str}}</div><div v-text='str'></div><div v-html='str'></div></div>
</body>
v-html => 可以用于实现插入一个标签. => 它有安全问题.容易手动xss攻击.=> 必须保证内容是安全的
xss => 脚步注入攻击.v-text => 根插值表达式的功能一模一样
<script src="js/vue.js"></script><script>new Vue({el: '#app',data: {str: '<p>你好</p>'}})</script>
六、v-pre和v-cloak
<style>[v-cloak]{display: none;}</style>
</head>
<body><div id="app"><div>{{msg}}</div><div v-pre>{{msg}}</div><div v-cloak>{{strrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr}}</div></div>
</body>
v-pre => 让插值表达式不会求值
v-cloak => 为了cdn引入Vue的用户准备的.
<script src="js/vue.js"></script><script>new Vue({el: '#app',data: {msg: 10000,strrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr: 20000}})</script>
七、 created
<body><div id='app'><button @click='fn'>按钮</button><div>{{msg1}}</div><div>{{msg2}}</div><div>{{num}}</div><div>{{msg1 + msg2}}</div></div>
</body>
<script src="js/vue.js"></script><script>let arr = [1,2,3,4,5]new Vue({el: '#app',data: {msg1: 0,msg2: 0,num: 0},// 用于给data的数据进行初始化的.// 程序运行,created会默认触发一次.// created => 生命周期钩子函数.created() {this.msg1 = Math.random();this.msg2 = Math.random();this.num = this.msg1 + this.msg2// for (let i = 0; i < arr.length; i++) {// this.msg += arr[i]// }},methods: {fn() {this.msg1 = Math.random();this.msg2 = Math.random();// this.num = this.msg1 + this.msg2;}}})</script>
八、视图更新发生了什么事情
<body><div id='app'> <button @click='fn'>按钮</button><div>{{msg1}}</div><div>{{msg2}}</div><div>{{msg1 + msg2}}</div></div>
</body>
视图更新后,视图内的所有逻辑(插值表达式和指令)都会重新运行和求值.
msg1和msg2变化,会导致视图更新,视图更新,会导致msg1 + msg2重新求值.
<script src="js/vue.js"></script><script>// new Vue({// el: '#app',// data: {// msg1: Math.random(),// msg2: Math.random(),// },// methods: {// fn() {// this.msg1 = Math.random();// this.msg2 = Math.random();// }// }// })// let [oBtn] = document.querySelectorAll('button');// let msg1 = Math.random();// let msg2 = Math.random();oBtn.onclick = function() {// 修改数据msg1 = Math.random();msg2 = Math.random();// 修改数据后更新视图renderView();}// function renderView() {// console.log(msg1 + msg2);// oDiv1.innText = msg1;// oDiv2.innText = msg2;// oDiv3.innText = msg1 + msg2;// }</script>
九、视图更新的后的指令
<body><div id='app'> <button @click='fn'>按钮</button><div :style='{backgroundColor: msg < 5 ? "red" : "green"}'>1222</div><div :style='{backgroundColor: msg > 5 ? "blue" : "yellow"}'>1222</div></div>
</body>
视图更新后,视图内的所有逻辑(插值表达式和指令)都会重新运行和求值.
msg变化就会导致视图更新,视图更新会导致 msg < 5 ? "red" : "green"重新运行.
<script src="js/vue.js"></script><script>new Vue({el: '#app',data: {msg: 0},methods: {fn() {this.msg = Math.floor(Math.random() * 10) + 1;}}})// let [oBtn] = document.querySelectorAll('button');// let msg = Math.random();// oBtn.onclick = function() {// 修改数据// msg = Math.floor(Math.random() * 10) + 1;// 修改数据后更新视图// renderView();// }// :style='{backgroundColor: msg < 5 ? "red" : "green"}' 的对应DOM操作逻辑// 视图每次更新,都会运行下面的DOM逻辑.// function renderView() {// if (msg < 5) {// oDiv.style.backgroundColor = 'red'// } else {// oDiv.style.backgroundColor = 'green'// }// }</script>
十、高亮
<body><div id='app'><ul><li v-for='(d, i) in 5':style='{backgroundColor: index===i ? "red" : ""}'@click='toRed(i)' >{{d}}</li></ul></div><ul id='wrap'><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
</body>
<script src="js/vue.js"></script><script>// index改变 => 视图更新 => 让v-for和v-bind对应的逻辑重新运行.new Vue({el: '#app',data: {index:2},methods: {toRed(i) {this.index = i;}}});</script>
<script src="js/vue.js"></script><script>let aLi = document.querySelectorAll('#wrap>li');let oUl = document.querySelectorAll('#wrap')[0];被点击的li的下标。let index = 0;aLi.forEach(function(item, i) {item.onclick = function() {记录下标index = i;根据index的值来渲染视图.renderView();}});index改变之后的DOM操作逻辑function renderView() {for (let i = 0; i < 5; i++) {if (index === i) {aLi[i].style.backgroundColor = 'red'} else {aLi[i].style.backgroundColor = ''}}}</script>
十一、视图更新
<body><div id='app'><div>{{msg}}</div><div>{{arr[0]}}</div><ul><li v-for='(item, i) in colors':style='{backgroundColor: colors[i]}'@click='toRed(i)'>1111</li></ul></div>
</body>
msg => 会导致视图更新 => msg和arr[0]会重新求值
只修改arr[0]视图不更新,但是数据是改变了
后续通过修改msg来驱动视图更新,视图更新又会显示最新的arr[0]的值.
<script src="js/vue.js"></script><script>let vm = new Vue({el: '#app',data: {msg: 0,arr: [1,2,3],colors: ['', '', '']},methods: {toRed(i) {// 这里for循环内的操作不会导致视图更新.但是数据变了for (let i = 0; i < this.colors.length; i++) {this.colors[i] = '';}// 这个操作会导致视图更新,也会显示for循环的结果.this.colors.splice(i, 1, 'red');}}})</script>
十二、defineProperty
js对象的属性都有4种描述
1:是否可以修改 writable: true
2:是否可以删除 configurable: true
3:是否可以枚举 enumerable: true => 是否可以for in 检测
4:值是什么 value
<script>const oYm = {name: '幂幂'}// 获取oYm对象的name属性的4中描述const desc = Object.getOwnPropertyDescriptor(oYm, 'name');console.log(desc);// 修改oYm的name属性的描述.Object.defineProperty(oYm, 'name', {value: '超越',enumerable: false});</script>
十三、defineProperty
<body><div id='app'></div>
</body>
defineProperty是Vue的数据驱动的底层核心方法.
当一个监听的数据发生变化时,可以通过视图更新.(DOM操作)如何监听一个数据,能捕获到这个数据的变化呢?
用defineProperty来设置监听
<script>const data = { msg: 100 };const [oDiv] = document.querySelectorAll('div');let val = data.msg;// 设置了set和get方法的属性,它的值,只能通过get返回.Object.defineProperty(data, 'msg', {// msg被访问时触发get() {console.log('msg被访问');return val},// msg被修改时触发(可以在这里做DOM操作)// 参数就是新修改的值.set(newVal) {val = newVal;console.log('msg被修改');oDiv.innerText = newVal;}});</script>
十四、模拟vue监听数据
<body><div id='app'><div>{{str}}</div><div>{{msg}}</div><div>{{person}}</div><div>{{person.name}}</div><div>{{arr[0]}}</div></div>
</body>
实例化Vue时,Vue会给data内的所有字段(属性)进行数据劫持.
vm.$data => vue的实例监听的data数据
<script src="js/vue.js"></script><script>const vm = new Vue({el: '#app',data: {msg: 100,str: 200,person: {name: '幂幂'},arr: [1,2,3, {name: '超越'}]}});</script>
const data = {msg: 100,str: 200,}myVue({data: data});function myVue({ data }) {// 循环data对象,进行数据监听(劫持).for (let key in data) {let val = data[key];Object.defineProperty(data, key, {get() {return val;},set(newVal) {val = newVal;}})}}
十五、set方法
<body><div id='app'><button @click='fn'>按钮</button><div>{{obj.name}}</div></div>
</body>
obj没有name属性,因此实例化时,没办法给这个name属性设置监听.
因此后续对name的修改,视图不会更新.
<script src="js/vue.js"></script><script>const vm = new Vue({el: '#app',data: {obj:{}},methods: {fn() {// 新增属性name.(不算修改)// this.obj.name = 1000;// 如何在新增一个属性的同时去给它添加数据劫持?// 用实例方法添加初始值和数据劫持// this.$set(this.obj, 'name', 1000);// 通过Vue的静态方法添加.// Vue.set(this.obj, 'name', 1000);// 访问实例的默认属性data.// console.log(this.$data);}}})</script>
十六、视图更新后的重新收集依赖
<body><div id='app'><div>{{obj.name}}</div><p>{{fn()}}</p></div>
</body>
数据劫持 => 还需要视图订阅 => 必须在视图上有对应的劫持数据.
要实现响应式的条件:
1:数据要有劫持.
2:视图上必须出现对应的数据.
满足以上两个条件的数据 => Watcher的依赖.
这个例子中,有3个字段被劫持,但是只有obj叫Watcher的依赖。
当obj变化时,产生了新的属性name,则在obj导致的视图更新后,Vue会自动给这个新生的name属性添加数据劫持.
如何给一个一开始不存在的属性添加数据劫持?
1:手动用$set添加.
2:通过修改这个属性所在的对象(把它变成新的对象).
<script src="js/vue.js"></script><script>const vm = new Vue({el: '#app',data: {obj:{},msg: 100,str: 200},methods: {fn() {console.log('视图更新了');}}})</script>
十七、计算属性
<body><div id='div'><input type="button" value="随机取数" @click='fn'><span>第一个随机数:{{num1}}</span><span>第二个随机数:{{num2}}</span><span>两个数的和是:{{num3}}</span></div>
</body>
Vue的数据
1:data中的数据
2:计算属性数据.
一个Vue的数据应该写在data中,还是应该写在computed中?
一个数据写在data中后就不能写在computed中,反之亦然.
计算属性的值,依赖别的数据的值变化而变化.(身不由己).
<script src="../js/vue.js"></script>
<script>let vm = new Vue({el: '#div',data: {num1: Math.floor(Math.random() * 10) + 1,num2: Math.floor(Math.random() * 10) + 1,},// 计算属性.可以简写成一个函数.return最终的值.// 这个计算属性的函数,在num1或者num2变化时,都会自动触发返回新的值.// 函数名就是我们需要使用的数据名.computed: {num3() {console.log('num3函数触发了');return this.num1 + this.num2}},methods: {fn() {this.num1 = Math.floor(Math.random() * 10) + 1;this.num2 = Math.floor(Math.random() * 10) + 1;}}});</script>
十八、计算属性
<body><div id='div'><input type="button" value="随机取数" @click='fn'><span>第一个随机数:{{num1}}</span><span>第二个随机数:{{num2}}</span><span>两个数的和是:{{num3}}</span><input type="text" v-model='num3'></div>
</body>
- 计算属性默认是不能手动修改的.(不能主动改变值).
- 如果需要手动修改计算属性,需要给计算属性设置setter
- 在setter中修改计算属性依赖的数据.
<script src="../js/vue.js"></script>
<script>new Vue({el: '#div',data: {num1: Math.floor(Math.random() * 10) + 1,num2: Math.floor(Math.random() * 10) + 1,},// 计算属性的函数简写,实际上是全写的只有get的形式.computed: {num3: {get() {return this.num1 + this.num2},set(newVal) {this.num1 = newVal - this.num2}}},methods: {fn() {this.num1 = Math.floor(Math.random() * 10) + 1;this.num2 = Math.floor(Math.random() * 10) + 1;}}});</script>
十九、watch
<body><div id='div'><input type="button" value="随机取数" @click='fn'><span>第一个随机数:{{num1}}</span><span>第二个随机数:{{num2}}</span><span>两个数的和是:{{num3}}</span></div>
</body>
<script src="../js/vue.js"></script>
<script>new Vue({el: '#div',data: {num1: Math.floor(Math.random() * 10) + 1,num2: Math.floor(Math.random() * 10) + 1,num3: 0},// 侦测属性(监听)watch: {// 当num1变化时,就触发这个函数,num1() {this.num3 = this.num1 + this.num2;},// 当num2变化时,就触发这个函数num2() {this.num3 = this.num1 + this.num2;}},methods: {fn() {this.num1 = Math.floor(Math.random() * 10) + 1;this.num2 = Math.floor(Math.random() * 10) + 1;}}});
</script>
二十、watch的immediate属性
<body><div id='div'><input type="button" value="随机取数" @click='fn'><span>第一个随机数:{{num1}}</span><span>第二个随机数:{{num2}}</span><span>两个数的和是:{{num3}}</span></div>
</body>
<script src="../js/vue.js"></script>
<script>new Vue({el: '#div',data: {num1: Math.floor(Math.random() * 10) + 1,num2: Math.floor(Math.random() * 10) + 1,num3: 0},// 侦测属性(监听)watch: { num1: {// 立即,默认触发一次handler.immediate: true,// handler在每次num1变化时都会触发.handler() {this.num3 = this.num1 + this.num2;}},// 当num2变化时,就触发这个函数num2: {immediate: true,// handler在每次num2变化时都会触发.handler() {this.num3 = this.num1 + this.num2;}}},methods: {fn() {this.num1 = Math.floor(Math.random() * 10) + 1;this.num2 = Math.floor(Math.random() * 10) + 1;}}});</script>
二十一、计算属性和watch的区别
vue 数据更新流程
<body><div id='div'><input type="button" value="随机取数" @click='fn'><span>第一个随机数:{{num1}}</span><span>第二个随机数:{{num2}}</span><span>两个数的和是:{{num3}}</span></div>
</body>
计算属性是watch的一种特例.
计算属性能够实现的功能,watch都能实现.
watch能够实现的功能,计算属性不一定能够实现.例如异步操作.
计算属性内部不能包含异步操作.计算属性有缓存,watch没有.
<script src="../js/vue.js"></script>
<script>new Vue({el: '#div',data: {num1: Math.floor(Math.random() * 10) + 1,num2: Math.floor(Math.random() * 10) + 1,num3: 0},// computed: {// num3() {// // 计算属性内部能包含异步操作.// let total = 0;// setTimeout(() => {// total = this.num1 + this.num2// }, 3000);// return total// }// },watch: {num1: {immediate: true,handler() {setTimeout(() => {this.num3 = this.num1 + this.num2}, 3000);}}},methods: {fn() {this.num1 = Math.floor(Math.random() * 10) + 1;this.num2 = Math.floor(Math.random() * 10) + 1;}}});</script>
二十二、计算属性的缓存
<body><div id='div'><input type="button" value="随机取数" @click='fn'><span>第一个随机数:{{num1}}</span><span>第二个随机数:{{num2}}</span><span>两个数的和是:{{num3}}</span><h3>{{msg}}</h3></div>
</body>
- 计算属性的缓存 => 如有闭包,尽可能使用前一次的计算结果。
- 这样做是问了避免不必要的函数调用.
<script src="../js/vue.js"></script>
<script>let vm = new Vue({el: '#div',data: {num1: Math.floor(Math.random() * 10) + 1,num2: Math.floor(Math.random() * 10) + 1,msg: 0},computed: {num3: {// 关闭计算属性的缓存功能.// 这样做会导致每次视图更新,计算属性的get都会重复调用.返回计算属性的值.cache: false,get() {console.log('num3计算属性函数触发了')return this.num1 + this.num2}}},methods: {fn() {this.num1 = Math.floor(Math.random() * 10) + 1;this.num2 = Math.floor(Math.random() * 10) + 1;}}});</script>
Vue.js框架(二)相关推荐
- js 获得明天0点时间戳_Python 3+Django 3 结合Vue.js框架构建前后端分离Web开发平台实战...
点击上方"测试开发技术",选择设为"设为星标" 优质文章,第一时间送达! 学习全文大概需要 12分钟,内容实战性较强. 1. 前言 本篇将基于Python 3. ...
- Vue.js 框架基础笔记
Vue.js 框架基础笔记 1. Vue.js 基本概念 1.1 遇见 Vue.js 1.1.1 为什么要学习 Vue.js 1.1.2 前端开发的复杂化 1.1.3 Vue.js 特点 1.1.4 ...
- 如何进行 Vue.js 框架的安装?
cmd如何进行 Vue.js 框架的安装? 步骤总结: 本地磁盘建立对应的空文件夹:举例:路径如C:\个人\vuejs\secondvue 电脑单击"开始",搜索程序**" ...
- Vue.js框架简介(1)
1.Vue.js框架简介 Vue(读音 /vju:/,发音类似于 view)是一套用于构建用户界面的渐进式的JavaScript框架. 1.1.为什么要学习Vue.js 什么是Vue.js Vue.j ...
- 前端Vue.js框架是什么?有哪些特点?
前端Vue.js框架是什么?有哪些特点?Vue.js是一个前端框架,用于构建用户界面的渐进式框架.在Vue中一个核心的概念是让用户不再操作DOM元素解放了用户的双手,让程序员可以更多的时间去关注业务逻 ...
- 前端_快速入门Vue.js框架
文章目录 快速入门Vue.js框架 0.前言 1.Vue.js框架 1.1.Vue简介 1.2.第一个Vue程序 1.3.el:挂载点 2.Vue指令 2.2.v-html 2.3.v-on 2.4. ...
- Vue.js 框架从入门到精通,只需要它!
点击蓝字 关注我们 你还在一行一行低效代码吗?你还在不停地操作 DOM 吗?你的代码还会频繁出现 CSS.Javascript 配置文件冲突吗? Vue3 框架快速解决你的代码低效问题! 01 Vue ...
- 从零吃透 Vue.js 框架,这里全部有!
点击蓝字 关注我们 你还在一行一行低效代码吗?你还在不停地操作 DOM 吗?你的代码还会频繁出现 CSS.Javascript 配置文件冲突吗? Vue3 框架快速解决你的代码低效问题! 01 Vue ...
- vue事件总线_[面试] 聊聊你对 Vue.js 框架的理解
作者:yacan8 https://github.com/yacan8/blog/issues/26 本文为一次前端技术分享的演讲稿,所以尽力不贴 Vue.js 的源码,因为贴代码在实际分享中,比较枯 ...
- Vue.js 框架源码与进阶 - 搭建自己的SSR
文章目录 一.Vue SSR 介绍 1.1 Vue SSR 是什么 1.2 使用场景 1.3 如何实现 Vue SSR 二.Vue SSR 基本使用 2.1 渲染一个 Vue 实例 2.2 与服务器集 ...
最新文章
- 再见,Kaggle!
- 如何理解“跳出率”,它对SEO有什么影响?
- html盒子移动动画代码,HTML5/Canvas 盒子追踪动画
- 数据结构与算法之选择排序图文详解及代码 (C++实现)
- centos7挂载windows共享文件
- 400W SOD-123封装 TVS管SMF4L系列 型号齐全
- SAP 电商云 Spartacus UI 实现的 ngrx-router-store.js 的 serializer
- 以管理员身份运行IJ
- amos看拟合度在哪里看_哪里可以看亲爱的热爱的电视剧全集
- CSDN编程挑战——《-3+1》
- leetcode 778. 水位上升的泳池中游泳(并查集)
- 一、node.js搭建最简单的服务器
- ctk 组件创建 ui_创建可重复使用的UI组件的提示和技巧
- splunk 提取字段_全面的Splunk应用日志分析介绍
- 英业达软件测试工程师,「天津英业达软件测试工程师」面试招聘|工资待遇 - 看准网...
- 海龟交易法则01_玩风险的交易者
- Flink CDC 系列 - Flink MongoDB CDC 在 XTransfer 的生产实践
- Node2Vec实战
- 信息系统监理师备考知识点
- 手把手教你获取一年免费通配符泛域名SSL证书
热门文章
- ​smooth-signature​.js: 前端canvas实现H5带笔锋手写签名,支持PC端和移动端使用,无框架限制,Vue、React等均可使用
- java 去掉图片水印文字_Java实现图片水印工具类
- 给定两个字符串 s 和 t,它们只包含小写字母。
- 前端遮罩层实现_前端制作遮罩与蒙版
- java开发手机app_java 怎么开发手机app接口?
- dell 服务器引导盘安装2003
- H77、Z75、Z77主板有什么区别?
- P2P追债也用上大数据
- 已解决-改变macOS和Windows双系统的默认启动顺序
- ff7重制版青魔法_《FF7重制》敌方招式获取方式与效果