MVVM模式

M:model 模型 包括数据和一些基本操作

V:view 视图,页面渲染结果

VM:view model 把视图与数据联系到一起 模型与视图的双向操作(无需开发人员干涉) 将DOM操作完全封装

数据与视图互相独立

只要Model发生改变,View上自然会表现出来

当用户修改了View,Model也会跟着改变 视图与数据模型的双向绑定

通过视图与模型的双向绑定,简化前端操作

vue中不涉及到视图与数据的绑定 例如jquery中视图与数据进行绑定

$('#app').click(function(){})

渐进式框架

可以选择性的使用该框架的一个或者一些组件,也不要求系统都使用该框架,提高开发效率

创建一个vue实例

var app = new Vue({//el 绑定到哪个地方el: '#app',// 数据data: {message: 'test',messages: 1},// 方法methods: {num() {this.messages = this.messages - 0 + 1},}})

Object.freeze() 阻止响应系统

Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化。

var obj = {foo: 'bar'
}Object.freeze(obj)new Vue({el: '#app',data: obj
})
<div id="app"><p>{{ foo }}</p><!-- 这里的 `foo` 不会更新! 因为响应被阻止了--><button v-on:click="foo = 'baz'">Change it</button>
</div>

v-on 事件处理

可以直接用 @

<div><button @click='num'>添加</button>
</div>

生命周期及钩子函数

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会,当实例处于不同的周期的时候,对应的函数会被触发。

比如 created 钩子可以用来在一个实例被创建之后执行代码

不能使用箭头函数来定义生命周期方法

不要在选项 property 或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误

Vue 实例生命周期

看懂这个图[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tGNEF2VQ-1601186966016)(file:///C:\Users\asus\AppData\Roaming\Tencent\Users\504708627\QQ\WinTemp\RichOle{5_}UXMZESZ~V[@WF2[TF4J.png)]

在mounted时将挂在的el中的{{}}里面的内容进行解析

let app = new Vue({el: '#app',data: {masg: 'hgellovue',id: 'redbg',message: '',isShow: true},beforeCreate: function() {// vue实例创建出来   但是数据还没有绑定 事件也没有绑定console.log('beforecreate')console.log(this)// undefinedconsole.log(this.masg)console.log(this.event1)},created: function() {// 数据已经绑定  方法也已经初始化完成  // 但是只是拿到了数据  并没有渲染到视图上console.log('created')console.log(this.masg)console.log(this.event1)},beforeMount: function() {// null  渲染之前 拿不到根据数据生成的dom对象let classname = document.querySelector('.redbg');console.log(classname)},mounted: function() {//渲染之后  可以获得根据数据生成的数据对象let classname = document.querySelector('.redbg');console.log(classname)},beforeUpdate: function() {console.log('这是修改之前的阶段')},updated: function() {console.log('修改完成,现在的数据是' + this.message)},// 总共8个生命周期  剩下两个 destroy brforedestroy用不太到methods: {event1: function() {console.log('事件1');},event2: function() {alert('输入完成')},event3: function() {this.isShow = !this.isShow}},// 组件分全局注册与局部注册  // 全局注册是vue.component   必须在创建实例之前填写// 局部注册只在当前实例中生效  在实例中添加componentscomponents: {'hello-vom': {// data是要 return出来data: function() {return {vom: 'hellovom'}},template: `<div>这是一个局部注册的组件{{vom}}</div>`,// destroy brforedestroy一般用于销毁组件  // 比如给组件一个v-if  当为false的时候就涉及到了组件的销毁  性能消耗大// v-show是将数据进行隐藏  并不是销毁destroyed: function() {console.log('销毁已经完成')},}}})

指令

带有v-前缀的特殊属性

指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

指令中的动态参数问题

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:[attributeName]="url"> ... </a>

这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href就是相当于吧[]里的当作一个js表达式来进行解析

同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:

<a v-on:[eventName]="doSomething"> ... </a>

在这个示例中,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus

属实我觉得没啥用。

对动态参数的值的约束

动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。

对动态参数表达式的约束

动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:

<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>

变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。

插值表达式

{{表达式}}

说明:

  • 该表达式支持JS语法,可以调用JS内置函数(必须有返回值)
  • 表达式必须有返回的结果 例如 1+1
  • 可以直接获取VUE实例中的数据或者函数
  • 这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式

以下表达式可以生效:

{{ number + 1 }}{{ ok ? 'YES' : 'NO' }}{{ message.split('').reverse().join('') }}<div v-bind:id="'list-' + id"></div>

以下表达式不会生效:

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 MathDate 。你不应该在模板表达式中试图访问用户定义的全局变量。

v-once

通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

<span v-once>这个将不会改变: {{ msg }}</span>

v-html

可以将数据解析成html代码 渲染成html

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:

你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。

v-text

将数据直接按照text格式来进行输出 直接输出

v-text与v-html区别

<body><div id="app"><input type="text" v-model='num'><div v-text='text'></div><div v-html='text'></div></div><script>var sm = new Vue({el: '#app',data: {num: 1,text: "<span>lalal</span>"},// 生命周期及钩子函数  以created为例  必会执行// 这是es6简化写法   原本完整写法  created:function(){}created() {alert('vue实例被创建了')}})</script>
</body>

输出结果: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ESGjx8Ro-1601186966021)(file:///C:\Users\asus\AppData\Roaming\Tencent\Users\504708627\QQ\WinTemp\RichOle\A@[77LFB72XCH]A4BJO4GKE.png)]

二者最开始是用于解决使用{{}}出现的插值闪烁的问题,不过目前使用{{}}也不太会出现插值闪烁问题

注意:此处为单向绑定,数据对象上的值改变,插值会发生变化;但是当插值发生变化并不会影响数据对象的值

v-pre

  • 显示原始信息跳过编译过程
  • 跳过这个元素和它的子元素的编译过程。
  • **一些静态的内容不需要编译加这个指令可以加快渲染
    <span v-pre>{{ this will not be compiled }}</span>    <!--  显示的是{{ this will not be compiled }}  --><span v-pre>{{msg}}</span>  <!--   即使data里面定义了msg这里仍然是显示的{{msg}}  -->
<script>new Vue({el: '#app',data: {msg: 'Hello Vue.js'}});</script>

v-cloak

防止出现闪烁问题

 <style type="text/css">/* 1、通过属性选择器 选择到 带有属性 v-cloak的标签  让他隐藏*/[v-cloak]{/* 元素隐藏    */display: none;}</style>
<body><div id="app"><!-- 2、 让带有插值 语法的   添加 v-cloak 属性 在 数据渲染完场之后,v-cloak 属性会被自动去除,v-cloak一旦移除也就是没有这个属性了  属性选择器就选择不到该标签也就是对应的标签会变为可见--><div  v-cloak  >{{msg}}</div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">var vm = new Vue({//  el   指定元素 id 是 app 的元素  el: '#app',//  data  里面存储的是数据data: {msg: 'Hello Vue'}});
</script>
</body>
</html>

v-model

可以实现双向绑定

限制在 <input>、<select>、<textarea>、components 使用

输入框中改变的时候会双向改变messages的内容

<input v-model='messages'>

绑定在不同的标签的时候,对应的值不同

多个checkbox对应一个model时,model的类型是数组

单个checkbox的值是boolean

radio对应的值是input的value

input和textarea对应的是字符串

seleck单选对应字符串 多选对应数组

修饰符

.lazy

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">

.number

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

<input v-model.number="age" type="number">

.trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<input v-model.trim="msg">

v-bind

动态绑定属性 可以响应式更新

绑定属性 v-bind 指令可以用于响应式地更新 HTML attribute:

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc"><!-- 缩写 -->
<img :src="imageSrc">

注意:v-bind:class指令可以与普通的class特性共存

v-bind 中支持绑定一个对象

​ 如果绑定的是一个对象 则 键为 对应的类名 值 为对应data中的数据

<ul class="box" v-bind:class="{textColor:isColor, textSize:isSize}"><li>学习Vue</li><li>学习Node</li><li>学习React</li>
</ul>

其中 值一般是true false

v-bind支持绑定一个数组

数组中classA和 classB 对应为data中的数据

<ul class="box" :class="[classA, classB]"><li>学习Vue</li><li>学习Node</li><li>学习React</li>
</ul>
<script>
var vm= new Vue({el:'.box',data:{classA:‘textColor‘,classB:‘textSize‘}
})
</script>
<style>.box{border:1px dashed #f0f;}.textColor{color:#f00;background-color:#eef;}.textSize{font-size:30px;font-weight:bold;}
</style>

最终类名绑定为textColor textSize

绑定对象和绑定数组 的区别

  • 绑定对象的时候 对象的属性 即要渲染的类名 对象的属性值对应的是 data 中的数据
  • 绑定数组的时候数组里面存的是data 中的数据

绑定style时的常用操作

用v-bind来绑定style属性的时候 一般使用绑定对象的方法

 <div v-bind:style="styleObject">绑定样式对象</div>'<!-- CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来)    --><div v-bind:style="{ color: activeColor, fontSize: fontSize,background:'red' }">内联样式</div><!--组语法可以将多个样式对象应用到同一个元素 -->
<div v-bind:style="[styleObj1, styleObj2]"></div><script>new Vue({el: '#app',data: {styleObject: {color: 'green',fontSize: '30px',background:'red'},activeColor: 'green',fontSize: "30px"},styleObj1: {color: 'red'},styleObj2: {fontSize: '30px'}</script>

v-on

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ycgDUeGj-1601186966024)(file:///C:\Users\asus\AppData\Roaming\Tencent\Users\504708627\QQ\WinTemp\RichOle[AVTQ8W]{P%CT2QSALJ0[L8.png)]

v-on事件函数中传入参数

如果方法未传入参数 ,则默认只有参数event(事件对象)

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

<body><div id="app"><div>{{num}}</div><div><!-- 如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数 --><button v-on:click='handle1'>点击1</button><!-- 2、如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event --><button v-on:click='handle2(123, 456, $event)'>点击2</button></div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">var vm = new Vue({el: '#app',data: {num: 0},methods: {handle1: function(event) {console.log(event.target.innerHTML)},handle2: function(p, p1, event) {console.log(p, p1)console.log(event.target.innerHTML)this.num++;}}});</script>

事件修饰符

  • 在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。
  • Vue 不推荐我们操作DOM 为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符
  • 修饰符是由点开头的指令后缀来表示的
<!-- 阻止单击事件继续传播  阻止冒泡 -->
<a v-on:click.stop="doThis"></a><!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form><!-- 点击事件将只会触发一次 -->
不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。
<a v-on:click.once="doThis"></a><!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况  可以提升移动端性能-->
<div v-on:scroll.passive="onScroll">...</div><!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a><!-- 只有修饰符 -->
<form v-on:submit.prevent></form><!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div><!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

按键修饰符

  • 在做项目中有时会用到键盘事件,在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit"><!-- -当点击enter 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit"><!--当点击enter或者space时  时调用 `vm.alertMe()`   -->
<input type="text" v-on:keyup.enter.space="alertMe" >常用的按键修饰符
.enter =>    enter键
.tab => tab键
.delete (捕获“删除”和“退格”按键) =>  删除键
.esc => 取消键
.space =>  空格键
.up =>  上
.down =>  下
.left =>  左
.right =>  右<script>var vm = new Vue({el:"#app",methods: {submit:function(){},alertMe:function(){},}})</script>

自定义按键修饰符别名

  • 在Vue中可以通过config.keyCodes自定义按键修饰符别名
  • 你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
<div id="app">预先定义了keycode 116(即F5)的别名为f5,因此在文字输入框中按下F5,会触发prompt方法<input type="text" v-on:keydown.f5="prompt()">
</div><script>Vue.config.keyCodes.f5 = 116;let app = new Vue({el: '#app',methods: {prompt: function() {alert('我是 F5!');}}});
</script>

系统修饰键

  • .ctrl
  • .alt
  • .shift
  • .meta
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear"><!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>
修饰符+keycode   就是二者一起按下才会触发
请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。

.exact修饰符

.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button><!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button><!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>

鼠标按钮修饰符

  • .left
  • .right
  • .middle

为何在html中绑定事件

你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:

  1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
  2. 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
  3. 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们

v-for

写在哪个标签中 循环输出哪个标签

v-for遍历数组

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名

一般情况下,要遍历的数据可以通过钩子函数created发送异步请求获取数据】

<ul id="example-1"><li v-for="item in items" :key="item.message">{{ item.message }}</li>
</ul>
var example1 = new Vue({el: '#example-1',data: {items: [{ message: 'Foo' },{ message: 'Bar' }]}
})

v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。

<ul id="example-2"><li v-for="(item, index) in items">{{ parentMessage }} - {{ index }} - {{ item.message }}</li>
</ul>
var example2 = new Vue({el: '#example-2',data: {parentMessage: 'Parent',items: [{ message: 'Foo' },{ message: 'Bar' }]}
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kbTkkr5W-1601186966026)(file:///C:\Users\asus\AppData\Roaming\Tencent\Users\504708627\QQ\WinTemp\RichOle_LEV@V8@98TVIHF[_QPCE3U.png)]

也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:

<div v-for="item of items"></div>

总结:第一个参数是数组元素 第二个是索引

v-for遍历对象

你也可以用 v-for 来遍历一个对象的 property。

你也可以提供第二个的参数为 property 名称 (也就是键名):

还可以用第三个参数作为索引:

<div v-for="(value, name, index) in object">{{ index }}. {{ name }}: {{ value }}
</div>
new Vue({el: '#v-for-object',data: {object: {title: 'How to do lists in Vue',author: 'Jane Doe',publishedAt: '2016-04-10'}}
})

在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。

维护状态(默认要使用:key)

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:

<div v-for="item in items" v-bind:key="item.id"><!-- 内容 -->
</div>

不要使用对象或数组之类的非基本类型值作为 v-forkey。请用字符串或数值类型的值。

添加key之后 在数据发生改变的时候可以按照期望的顺序重排数据,在遍历完数据又对集合增减的时候有意义

key 的作用

  • key来给每个节点做一个唯一标识 复用时更加便利
  • key的作用主要是为了高效的更新虚拟DOM

vue中列表循环需加:key=“唯一标识” 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM

key的简单解释

说到底,key的作用就是更新组件时判断两个节点是否相同。相同就复用,不相同就删除旧的创建新的。在渲染简单的无状态组件时,如果不添加key组件默认都是就地复用,不会删除添加节点,只是改变列表项中的文本值,要知道节点操作是十分耗费性能的。而添加了key之后,当对比内容不一致时,就会认为是两个节点,会先删除掉旧节点,然后添加新节点。

v-if 与v-for同时使用

  • 不推荐同时使用 v-ifv-for
  • v-ifv-for 一起使用时,v-for 具有比 v-if 更高的优先级。

这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">{{ todo }}
</li>

上面的代码将只渲染未完成的 todo。

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 `) 上。如:

<ul v-if="todos.length"><li v-for="todo in todos">{{ todo }}</li>
</ul>
<p v-else>No todos left!</p>

显示过滤/排序后的结果

有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。

<li v-for="n in evenNumbers">{{ n }}</li>
data: {numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {evenNumbers: function () {return this.numbers.filter(function (number) {return number % 2 === 0})}
}

在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个方法:

<ul v-for="set in sets"><li v-for="n in even(set)">{{ n }}</li>
</ul>
data: {sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
},
methods: {even: function (numbers) {return numbers.filter(function (number) {return number % 2 === 0})}
}

v-for使用值范围

v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。

<div><span v-for="n in 10">{{ n }} </span>
</div>

在template使用v-for

类似于 v-if,你也可以利用带有 v-for 的 ` 来循环渲染一段包含多个元素的内容。比如:

<ul><template v-for="item in items"><li>{{ item.msg }}</li><li class="divider" role="presentation"></li></template>
</ul>

在组件里使用

在自定义组件上,你可以像在任何普通元素上一样使用 v-for

<my-component v-for="item in items" :key="item.id"></my-component>

2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。

然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop:

<my-componentv-for="(item, index) in items"v-bind:item="item"v-bind:index="index"v-bind:key="item.id"
></my-component>

分支结构

v-if 使用场景

  • 1- 多个元素 通过条件判断展示或者隐藏某个元素。或者多个元素
  • 2- 进行两个视图之间的切换
<div id="app"><!--  判断是否加载,如果为真,就加载,否则不加载--><span v-if="flag">如果flag为true则显示,false不显示!</span>
</div><script>var vm = new Vue({el:"#app",data:{flag:true}})
</script>----------------------------------------------------------<div v-if="type === 'A'">A</div><!-- v-else-if紧跟在v-if或v-else-if之后   表示v-if条件不成立时执行--><div v-else-if="type === 'B'">B</div><div v-else-if="type === 'C'">C</div><!-- v-else紧跟在v-if或v-else-if之后--><div v-else>Not A/B/C</div><script>new Vue({el: '#app',data: {type: 'C'}})
</script>

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 元素当做不可见的包裹元素,并在上面使用v-if。最终的渲染结果将不包含 元素。

<template v-if="ok"><h1>Title</h1><p>Paragraph 1</p><p>Paragraph 2</p>
</template>

v-else

你可以使用 v-else 指令来表示 v-if 的“else 块”

<div v-if="Math.random() > 0.5">Now you see me
</div>
<div v-else>Now you don't
</div>

v-else-if

顾名思义,充当 v-if 的“else-if 块”,可以连续使用:

<div v-if="type === 'A'">A
</div>
<div v-else-if="type === 'B'">B
</div>
<div v-else-if="type === 'C'">C
</div>
<div v-else>Not A/B/C
</div>

使用key来避免复用

<template v-if="loginType === 'username'"><label>Username</label><input placeholder="Enter your username" key="username-input">
</template>
<template v-else><label>Email</label><input placeholder="Enter your email address" key="email-input">
</template>

这样每次切换的时候都会重新渲染

v-show

v-show='true’其实就是设置了display:none

v-show 和 v-if的区别

  • v-show本质就是标签display设置为none,控制隐藏
    • v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
  • v-if是动态的向DOM树内添加或者删除DOM元素
    • v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

v-if在条件不满足的时候直接不渲染并且原本渲染的从DOM中移除,v-show在不满足情况的时候只是进行隐藏而已

计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:

<div id="example">{{ message.split('').reverse().join('') }}
</div>

在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中多包含此处的翻转字符串时,就会更加难以处理。

所以,对于任何复杂逻辑,你都应当使用计算属性

  • 模板中放入太多的逻辑会让模板过重且难以维护 使用计算属性可以让模板更加的简洁
  • 计算属性是基于它们的响应式依赖进行缓存的
  • computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
  • 计算属性要有一个返回值
  • 最终就是经过计算 可以当作data中的属性来使用 使得页面简洁
<div id="example"><p>Original message: "{{ message }}"</p><p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({el: '#example',data: {message: 'Hello'},computed: {// 计算属性的 getterreversedMessage: function () {// `this` 指向 vm 实例return this.message.split('').reverse().join('')}}
})

计算属性与方法的区别

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {now: function () {return Date.now()}
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

总结:如果未发生响应式依赖,计算属性在第二次使用到的时候会直接 调用上一次得到的值,也就是说计算好的值会放在缓存里面,而方法却在每次调用的时候都再次执行函数

<div id="app"><!--  当多次调用 reverseString  的时候 只要里面的 num 值不改变 他会把第一次计算的结果直接返回直到data 中的num值改变 计算属性才会重新发生计算--><div>{{reverseString}}</div><div>{{reverseString}}</div><!-- 调用methods中的方法的时候  他每次会重新调用 --><div>{{reverseMessage()}}</div><div>{{reverseMessage()}}</div></div><script type="text/javascript">/*计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不缓存*/var vm = new Vue({el: '#app',data: {msg: 'Nihao',num: 100},methods: {reverseMessage: function(){console.log('methods')return this.msg.split('').reverse().join('');}},//computed  属性 定义 和 data 已经 methods 平级 computed: {//  reverseString   这个是我们自己定义的名字 reverseString: function(){console.log('computed')var total = 0;//  当data 中的 num 的值改变的时候  reverseString  会自动发生计算  for(var i=0;i<=this.num;i++){total += i;}// 这里一定要有return 否则 调用 reverseString 的 时候无法拿到结果    return total;}}});</script>

计算属性vs侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:

<div id="demo">{{ fullName }}</div>
var vm = new Vue({el: '#demo',data: {firstName: 'Foo',lastName: 'Bar',fullName: 'Foo Bar'},watch: {firstName: function (val) {this.fullName = val + ' ' + this.lastName},lastName: function (val) {this.fullName = this.firstName + ' ' + val}}
})

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({el: '#demo',data: {firstName: 'Foo',lastName: 'Bar'},computed: {fullName: function () {return this.firstName + ' ' + this.lastName}}
})

显而易见 计算属性版本的代码更加简洁

计算属性的setter

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

// ...
computed: {fullName: {// getterget: function () {return this.firstName + ' ' + this.lastName},// setterset: function (newValue) {var names = newValue.split(' ')this.firstName = names[0]this.lastName = names[names.length - 1]}}
}
// ...

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

侦听器

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

  • 使用watch来响应数据的变化

  • 一般用于异步或者开销较大的操作

  • watch 中的属性 一定是data 中 已经存在的数据

  • 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要设置deep属性为true对对象进行深度监听 开启深度监控来修改对象,在深度监控中回调函数为handler

     // 深度监控写法watch:{person:{deep :true,handler(obj){console.log(obj.name)}}}
    

    ,,

例如:

<div id="watch-example"><p>Ask a yes/no question:<input v-model="question"></p><p>{{ answer }}</p>
</div>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({el: '#watch-example',data: {question: '',answer: 'I cannot give you an answer until you ask a question!'},watch: {// 如果 `question` 发生改变,这个函数就会运行question: function (newQuestion, oldQuestion) {this.answer = 'Waiting for you to stop typing...'this.debouncedGetAnswer()}},created: function () {// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,// 请参考:https://lodash.com/docs#debouncethis.debouncedGetAnswer = _.debounce(this.getAnswer, 500)},methods: {getAnswer: function () {if (this.question.indexOf('?') === -1) {this.answer = 'Questions usually contain a question mark. ;-)'return}this.answer = 'Thinking...'var vm = thisaxios.get('https://yesno.wtf/api').then(function (response) {vm.answer = _.capitalize(response.data.answer)}).catch(function (error) {vm.answer = 'Error! Could not reach the API. ' + error})}}
})
</script>

setter

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

// ...
computed: {fullName: {// getterget: function () {return this.firstName + ' ' + this.lastName},// setterset: function (newValue) {var names = newValue.split(' ')this.firstName = names[0]this.lastName = names[names.length - 1]}}
}
// ...

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

过滤器

  • Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。
  • 过滤器可以用在两个地方:双花括号插值和v-bind表达式。
  • 过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示
  • 支持级联操作 {{ message | filterA | filterB }}
  • 过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本
  • 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的
 <div id="app"><input type="text" v-model='msg'><!-- upper 被定义为接收单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中 --><div>{{msg | upper}}</div><!--  支持级联操作upper  被定义为接收单个参数的过滤器函数,表达式msg 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器 lower ,将upper 的结果传递到lower中--><div>{{msg | upper | lower}}</div><div :abc='msg | upper'>测试数据</div></div><script type="text/javascript">//  lower  为全局过滤器     Vue.filter('lower', function(val) {return val.charAt(0).toLowerCase() + val.slice(1);});var vm = new Vue({el: '#app',data: {msg: ''},//filters  属性 定义 和 data 已经 methods 平级 //  定义filters 中的过滤器为局部过滤器 filters: {//   upper  自定义的过滤器名字 //    upper 被定义为接收单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中upper: function(val) {//  过滤器中一定要有返回值 这样外界使用过滤器的时候才能拿到结果return val.charAt(0).toUpperCase() + val.slice(1);}}});</script>

过滤器函数总接收表达式的值 (之前的操作链的结果) 作为第一个参数

过滤器中传递参数

 <div id="box"><!--filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。-->{{ message | filterA('arg1', 'arg2') }}</div><script>// 在过滤器中 第一个参数 对应的是  管道符前面的数据   n  此时对应 message// 第2个参数  a 对应 实参  arg1 字符串// 第3个参数  b 对应 实参  arg2 字符串Vue.filter('filterA',function(n,a,b){if(n<10){return n+a;}else{return n+b;}});new Vue({el:"#box",data:{message: "哈哈哈"}})</script>

组件

组件定义

组件的定义有一点要牢记,与vue实例不同,组件中data必须是一个函数,在函数中return一个对象,这样做的好处是 每个实例可以维护一份被返回对象的独立的拷贝,也就是说如果引入三个相同的组件,她们之间的数据是独立的。

//1.定义组件let counter = {template: '<button @click="nums++">你一共点击了{{nums}}次</button>',data: function() {return {nums: 0}}};

组件注册(全局 局部)

全局注册

  • Vue.component(‘组件名称’, { }) 第1个参数是标签名称,第2个参数是一个选项对象
  • 全局组件注册后,任何vue实例都可以用
  • 组件注册要在创建根实例之前, 全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
Vue.component('buttondel', {template: '<button @click="nums--">你一共点击了{{nums}}次</button>',data: function() {return {nums: 100}}});

组件注意事项

  • 组件参数的data值必须是函数同时这个函数要求返回一个对象
  • 组件模板必须是单个根元素
  • 组件模板的内容可以是模板字符串 反引号``
  • 在html中及时你定义组件使用的是驼峰方式命名,你也只能通过-方式来引入组件

// 如果组件使用驼峰式命名  只有在template模板中可以使用驼峰式命名 在html中引入的时候只能转换为A-B的类型Vue.component('buttonDel', {template: '<button @click="nums--">你一共点击了{{nums}}次</button>',data: function() {return {nums: 100}}});
<!-- 有效引入 -->
<button-del></button-del>
<!-- 无效引入 -->
<buttonDel></buttonDel>

局部注册

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。 所以需要用到局部注册

只能在当前注册它的vue实例中使用

在该vue实例中添加components属性】

  <div id="app"><my-component></my-component></div><script>// 定义组件的模板var Child = {template: '<div>A custom component!</div>'}new Vue({//局部注册组件  components: {// <my-component> 将只在父模板可用  一定要在实例上注册了才能在html文件中使用'my-component': Child}})</script>

局部注册注意事项

注意局部注册的组件在其子组件中*不可用*。例如,如果你希望 ComponentAComponentB 中可用,则你需要这样写:

var ComponentA = { /* ... */ }var ComponentB = {components: {'component-a': ComponentA},// ...
}

或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

import ComponentA from './ComponentA.vue'export default {components: {ComponentA},// ...
}

注意在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

  • 用在模板中的自定义元素的名称
  • 包含了这个组件选项的变量名

组件名大小写

定义组件名的方式有两种:

使用 kebab-case

Vue.component('my-component-name', { /* ... */ })

当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 ``。

使用 PascalCase

Vue.component('MyComponentName', { /* ... */ })

当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

也就是说 如果采用驼峰命名法,在模板中两种写法都可以接收,但是在html的body中(也就是直接在DOM中)只能使用kebab-case这一模式来引入

在模块系统中的组件全局化注册

一般做项目时会使用模块系统

同时讲组件写在各自的vue文件中,统一放在components文件夹中

示例代码如下:

import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'export default {components: {BaseButton,BaseIcon,BaseInput}
}

也可以将一些组件在vue-router的index,js中进行全局化注册

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/login.vue'
import Home from '../components/home.vue'
import welcome from '../components/welcome.vue'
import Users from '../components/user/Users.vue'Vue.use(VueRouter)const router = new VueRouter({routes: [{path: '/',redirect: '/login'},{path: '/login',component: Login},{path: '/home',component: Home,// 在Home下挂载一个子路由组件redirect: '/welcome',children: [{ path: '/welcome', component: welcome },{ path: '/users', component: Users }]}]
});

局部注册原理差不多 就是在某一个组件的vue文件中进行Import,然后进行局部注册

记住全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生

组件之间传值

父组件向子组件传值(prop)

  • 父组件发送的形式是以属性的形式绑定值到子组件身上。
  • 然后子组件用属性props接收
  • 在props中使用驼峰形式,DOM模板中需要使用短横线的形式,在字符串形式的模板中没有这个限制(详细解释见之后)
  <div id="app"><div>{{pmsg}}</div><!--1、menu-item  在 APP中嵌套着 故 menu-item   为  子组件      --><!-- 给子组件传入一个静态的值 --><menu-item title='来自父组件的值'></menu-item><!-- 2、 需要动态的数据的时候 需要属性绑定的形式设置 此时 ptitle  来自父组件data 中的数据 . 传的值可以是数字、对象、数组等等--><menu-item :title='ptitle' content='hello'></menu-item></div><script type="text/javascript">Vue.component('menu-item', {// 3、 子组件用属性props接收父组件传递过来的数据  props: ['title', 'content'],data: function() {return {msg: '子组件本身的数据'}},template: '<div>{{msg + "----" + title + "-----" + content}}</div>'});var vm = new Vue({el: '#app',data: {pmsg: '父组件中内容',ptitle: '动态绑定属性'}});</script>

prop的大小写

HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:

Vue.component('blog-post', {// 在 JavaScript 中是 camelCase 的props: ['postTitle'],template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>

重申一次,如果你使用字符串模板,那么这个限制就不存在了。

prop 类型

到这里,我们只看到了以字符串数组形式列出的 prop:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

但是,通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型:

props: {title: String,likes: Number,isPublished: Boolean,commentIds: Array,author: Object,callback: Function,contactsPromise: Promise // or any other constructor
}

这不仅为你的组件提供了文档,还会在它们遇到错误的类型时从浏览器的 JavaScript 控制台提示用户。你会在这个页面接下来的部分看到类型检查和其它 prop 验证。

prop验证

我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

Vue.component('my-component', {props: {// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)propA: Number,// 多个可能的类型propB: [String, Number],// 必填的字符串propC: {type: String,required: true},// 带有默认值的数字propD: {type: Number,default: 100},// 带有默认值的对象propE: {type: Object,// 对象或数组默认值必须从一个工厂函数获取default: function () {return { message: 'hello' }}},// 自定义验证函数propF: {validator: function (value) {// 这个值必须匹配下列字符串中的一个return ['success', 'warning', 'danger'].indexOf(value) !== -1}}}
})

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 datacomputed 等) 在 defaultvalidator 函数中是不可用的。

类型检查 (没太看懂)

type 可以是下列原生构造函数中的一个:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

额外的,type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。例如,给定下列现成的构造函数:

function Person (firstName, lastName) {this.firstName = firstNamethis.lastName = lastName
}

你可以使用:

Vue.component('blog-post', {props: {author: Person}
})

来验证 author prop 的值是否是通过 new Person 创建的。

prop传入值的类型

字符串

像这样,你已经知道了可以像这样给 prop 传入一个静态的值:

<blog-post title="My journey with Vue"></blog-post>

你也知道 prop 可以通过 v-bind 动态赋值,例如:

<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post><!-- 动态赋予一个复杂表达式的值 -->
<blog-postv-bind:title="post.title + ' by ' + post.author.name"
></blog-post>

在上述两个示例中,我们传入的值都是字符串类型的,但实际上任何类型的值都可以传给一个 prop。

数字
<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="42"></blog-post><!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:likes="post.likes"></blog-post>

注意:在传入的不是字符串的时候要用v-bind来动态赋值 因为数字布尔值等等都是一个js表达式

布尔值
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post><!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post><!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>
数组
<!-- 即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post><!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:comment-ids="post.commentIds"></blog-post>
对象
<!-- 即便对象是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-postv-bind:author="{name: 'Veronica',company: 'Veridian Dynamics'}"
></blog-post><!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:author="post.author"></blog-post>
传入方法

可以通过prop把父元素的方法传入到子组件中,不过要注意的是如果在方法中包含this,this指向的仍然是父元素

传入一个对象的所有属性

如果你想要将一个对象的所有 property 都作为 prop 传入,你可以使用不带参数的 v-bind (取代 v-bind:prop-name)。例如,对于一个给定的对象 post

post: {id: 1,title: 'My Journey with Vue'
}

下面的模板:

<blog-post v-bind="post"></blog-post>

等价于:

<blog-postv-bind:id="post.id"v-bind:title="post.title"
></blog-post>

prop是一个单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

这里有两种常见的试图变更一个 prop 的情形:

  1. **这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。**在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:

    props: ['initialCounter'],
    data: function () {return {counter: this.initialCounter}
    }
    
  2. **这个 prop 以一种原始的值传入且需要进行转换。**在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

    props: ['size'],
    computed: {normalizedSize: function () {return this.size.trim().toLowerCase()}
    }
    

注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态,因为改变的是源地址所存储的值

替换/合并已有的属性

想象一下 `` 的模板是这样的:

<input type="date" class="form-control">

为了给我们的日期选择器插件定制一个主题,我们可能需要像这样添加一个特别的类名:

<bootstrap-date-inputdata-date-picker="activated"class="date-picker-theme-dark"
></bootstrap-date-input>

在这种情况下,我们定义了两个不同的 class 的值:

  • form-control,这是在组件的模板内设置好的
  • date-picker-theme-dark,这是从组件的父级传入的

对于绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text" 就会替换掉 type="date" 并把它破坏!庆幸的是,classstyle attribute 会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:form-control date-picker-theme-dark

禁用属性继承

如果你希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false。例如:

Vue.component('my-component', {inheritAttrs: false,// ...
})

这尤其适合配合实例的 $attrs property 使用,该 property 包含了传递给一个组件的 attribute 名和 attribute 值,例如:

{required: true,placeholder: 'Enter your username'
}

有了 inheritAttrs: false$attrs,你就可以手动决定这些 attribute 会被赋予哪个元素。在撰写基础组件的时候是常会用到的:

Vue.component('base-input', {inheritAttrs: false,props: ['label', 'value'],template: `<label>{{ label }}<inputv-bind="$attrs"v-bind:value="value"v-on:input="$emit('input', $event.target.value)"></label>`
})

注意 inheritAttrs: false 选项不会影响 styleclass 的绑定。

这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素:

<base-inputv-model="username"requiredplaceholder="Enter your username"
></base-input>

单个根元素

当构建一个 `` 组件时,你的模板最终会包含的东西远不止一个标题:

<h3>{{ title }}</h3>

最最起码,你会包含这篇博文的正文:

<h3>{{ title }}</h3>
<div v-html="content"></div>

然而如果你在模板中尝试这样写,Vue 会显示一个错误,并解释道 every component must have a single root element (每个组件必须只有一个根元素)。你可以将模板的内容包裹在一个父元素内,来修复这个问题,例如:

<div class="blog-post"><h3>{{ title }}</h3><div v-html="content"></div>
</div>

看起来当组件变得越来越复杂的时候,我们的博文不只需要标题和内容,还需要发布日期、评论等等。为每个相关的信息定义一个 prop 会变得很麻烦:

<blog-postv-for="post in posts"v-bind:key="post.id"v-bind:title="post.title"v-bind:content="post.content"v-bind:publishedAt="post.publishedAt"v-bind:comments="post.comments"
></blog-post>

所以是时候重构一下这个 `` 组件了,让它变成接受一个单独的 post prop:

<blog-postv-for="post in posts"v-bind:key="post.id"v-bind:post="post"
></blog-post>
Vue.component('blog-post', {props: ['post'],template: `<div class="blog-post"><h3>{{ post.title }}</h3><div v-html="post.content"></div></div>`
})

上述的这个和一些接下来的示例使用了 JavaScript 的模板字符串来让多行的模板更易读。它们在 IE 下并没有被支持,所以如果你需要在不 (经过 Babel 或 TypeScript 之类的工具) 编译的情况下支持 IE,请使用折行转义字符取而代之。

现在,不论何时为 post 对象添加一个新的 property,它都会自动地在 `` 内可用。

也就是可以直接传入post这个对象或者数组,可以使代码更加简洁

子组件向父组件传值

  • 子组件用$emit()触发事件
  • $emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据
  • 父组件用v-on 监听子组件的事件
 <div id="app"><div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div><!-- 2 父组件用v-on 监听子组件的事件这里 enlarge-text  是从 $emit 中的第一个参数对应   handle 为对应的事件处理函数	-->	<menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*子组件向父组件传值-携带参数*/Vue.component('menu-item', {props: ['parr'],template: `<div><ul><li :key='index' v-for='(item,index) in parr'>{{item}}</li></ul>###  1、子组件用$emit()触发事件### 第一个参数为 自定义的事件名称   第二个参数为需要传递的数据  <button @click='$emit("enlarge-text", 5)'>扩大父组件中字体大小</button><button @click='$emit("enlarge-text", 10)'>扩大父组件中字体大小</button></div>`});var vm = new Vue({el: '#app',data: {pmsg: '父组件中内容',parr: ['apple','orange','banana'],fontSize: 10},methods: {handle: function(val){// 扩大字体大小this.fontSize += val;}}});</script>

总结;1.在组件模板上使用$emit()触发事件,第一个参数为自定义的事件名称,第二个参数是需要传递的参数

2.在父组件上用v-on监听 @后加的是组件中的自定义事件名称

3.调用mehods的方法,其中传递的参数作为方法中的第一个形参

注意事项

不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 camelCase 名字的事件:

this.$emit('myEvent')

则监听这个名字的 kebab-case 版本是不会有任何效果的:

<!-- 没有效果 -->
<my-component v-on:my-event="doSomething"></my-component>

监听这个名字的驼峰版本是不会有任何效果的:

<!-- 没有效果 -->
<my-component v-on:myEvent="doSomething"></my-component>

正确监听:

<my-component v-on:myevent="doSomething"></my-component>

不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。

因此,我们推荐你始终使用 kebab-case 的事件名

在组件上绑定原生事件 .native

你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on.native 修饰符:

<base-input v-on:focus.native="onFocus"></base-input>

在有的时候这是很有用的,不过在你尝试监听一个类似 的非常特定的元素时,这并不是个好主意。比如上述 组件可能做了如下重构,所以根元素实际上是一个 label 元素:

<label>{{ label }}<inputv-bind="$attrs"v-bind:value="value"v-on:input="$emit('input', $event.target.value)">
</label>

这时,父级的 .native 监听器将静默失败。它不会产生任何报错,但是 onFocus 处理函数不会如你预期地被调用。

为了解决这个问题,Vue 提供了一个 $listeners property,它是一个对象,里面包含了作用在这个组件上的所有监听器。例如:

{focus: function (event) { /* ... */ }input: function (value) { /* ... */ },
}

有了这个 $listeners property,你就可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。对于类似 `` 的你希望它也可以配合 v-model 工作的组件来说,为这些监听器创建一个类似下述 inputListeners 的计算属性通常是非常有用的:

Vue.component('base-input', {inheritAttrs: false,props: ['label', 'value'],computed: {inputListeners: function () {var vm = this// `Object.assign` 将所有的对象合并为一个新对象return Object.assign({},// 我们从父级添加所有的监听器this.$listeners,// 然后我们添加自定义监听器,// 或覆写一些监听器的行为{// 这里确保组件配合 `v-model` 的工作input: function (event) {vm.$emit('input', event.target.value)}})}},template: `<label>{{ label }}<inputv-bind="$attrs"v-bind:value="value"v-on="inputListeners"></label>`
})

现在 组件是一个**完全透明的包裹器**了,也就是说它可以完全像一个普通的 元素一样使用了:所有跟它相同的 attribute 和监听器都可以工作,不必再使用 .native 监听器。

.sync修饰符

在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件都没有明显的变更来源。

这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:

this.$emit('update:title', newTitle)

然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:

<text-documentv-bind:title="doc.title"v-on:update:title="doc.title = $event"
></text-document>

为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:

<text-document v-bind:title.sync="doc.title"></text-document>

注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model

当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用:

<text-document v-bind.sync="doc"></text-document>

这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器。

v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

在组件上使用v-model

自定义事件也可以用于创建支持 v-model 的自定义输入组件。记住:

<input v-model="searchText">

等价于:

等价于两点  1.value值等于v-model的值 2. input改变的时候 改变v-model的值
<inputv-bind:value="searchText"v-on:input="searchText = $event.target.value"
>

当用在组件上时,v-model 则会这样:

<custom-input v-model="searchText"></custom-input>

等价于

 子组件通过$emit('input', $event.target.value)传值   在这边通过接收来达成子组件向父组件你传值
<custom-inputv-bind:value="searchText"v-on:input="searchText = $event" 这个$event就是传上来的$event.target.value
></custom-input>

为了让它正常工作,这个组件内的 `` 必须:

  • 将其 value attribute 绑定到一个名叫 value 的 prop 上
  • 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出

写成代码之后是这样的:

// 1.绑定value值  2.更新v-model
Vue.component('custom-input', {props: ['value'],template: `<inputv-bind:value="value"v-on:input="$emit('input', $event.target.value)">`
})

现在 v-model 就应该可以在这个组件上完美地工作起来了:

<custom-input v-model="searchText"></custom-input>

个人实现代码

<body><div id="app"><!-- 试一下在组件内使用v-model --><vue-model v-model='msg'></vue-model><div>{{msg}}</div></div><script>let app = new Vue({el: '#app',data: {msg: '123'},components: {'vue-model': {template: `<input type="text" v-bind:value='value' v-on:input='$emit("input",$event.target.value)'>`,props: ['value'],data: function() {return {val: 123}}},}})</script>
</body>

单选复选解决方案 (代码没成功)

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:

Vue.component('base-checkbox', {model: {prop: 'checked',event: 'change'},props: {checked: Boolean},template: `<inputtype="checkbox"v-bind:checked="checked"v-on:change="$emit('change', $event.target.checked)">`
})

现在在这个组件上使用 v-model 的时候:

<base-checkbox v-model="lovingVue"></base-checkbox>

这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 `` 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的 property 将会被更新。

注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。

兄弟之间的传递(不太用)

  • 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据 提供事件中心 var hub = new Vue()
  • 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
  • 接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
  • 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
 <div id="app"><div>父组件</div><div><button @click='handle'>销毁事件</button></div><test-tom></test-tom><test-jerry></test-jerry></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*兄弟组件之间数据传递*///1、 提供事件中心var hub = new Vue();Vue.component('test-tom', {data: function(){return {num: 0}},template: `<div><div>TOM:{{num}}</div><div><button @click='handle'>点击</button></div></div>`,methods: {handle: function(){//2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)   触发兄弟组件的事件hub.$emit('jerry-event', 2);}},mounted: function() {// 3、接收数据方,通过mounted(){} 钩子中  触发hub.$on(方法名hub.$on('tom-event', (val) => {this.num += val;});}});Vue.component('test-jerry', {data: function(){return {num: 0}},template: `<div><div>JERRY:{{num}}</div><div><button @click='handle'>点击</button></div></div>`,methods: {handle: function(){//2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)   触发兄弟组件的事件hub.$emit('tom-event', 1);}},mounted: function() {// 3、接收数据方,通过mounted(){} 钩子中  触发hub.$on()方法名hub.$on('jerry-event', (val) => {this.num += val;});}});var vm = new Vue({el: '#app',data: {},methods: {handle: function(){//4、销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据  hub.$off('tom-event');hub.$off('jerry-event');}}});</script>

动态组件

<!-- 失活的组件将会被缓存!-->
<keep-alive><!-- component 内置的用于加载组件的标签--><component v-bind:is="currentTabComponent"></component>
</keep-alive>

currentTabComponent 组件名

使用标签可以让组件被创建后缓存,可以只请求一次而避免重新请求,如果不使用,在失活后会被删除需要重新创建,可以避免因为反复渲染而导致的性能问题

引用场景 :点击不同的按钮 为is传递不同的组件名 显示不同的组件

<div id="app"><button @click='change'>切换不同组件</button><component :is='component'></component></div><script>let componenta = {template: `<h1> componenta</h1>`,data: function() {return {a: 123}}};let componentb = {template: `<h1> componentb</h1>`,data: function() {return {a: 123}}};let app = new Vue({el: '#app',data: {component: 'componenta'},methods: {change() {if (this.component == 'componenta') {this.component = 'componentb'} else {this.component = 'componenta'}}},components: {componenta,componentb}})</script>

异步组件

加载组件的时候,以异步的形式进行加载

实现方式:在导入的时候 使用()=>来动态导入,从而返回一个promise对象

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。例如:

Vue.component('async-example', function (resolve, reject) {setTimeout(function () {// 向 `resolve` 回调传递组件定义resolve({template: '<div>I am async!</div>'})}, 1000)
})

如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

Vue.component('async-webpack-example', function (resolve) {// 这个特殊的 `require` 语法将会告诉 webpack// 自动将你的构建代码切割成多个包,这些包// 会通过 Ajax 请求加载require(['./my-async-component'], resolve)
})

你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以这样使用动态导入

Vue.component('async-webpack-example',// 这个动态导入会返回一个 `Promise` 对象。() => import('./my-async-component')
)

当使用[局部注册]的时候,你也可以直接提供一个返回 Promise 的函数:

new Vue({// ...components: {'my-component': () => import('./my-async-component')}
})

异步组件加载状态

这里的异步组件工厂函数也可以返回一个如下格式的对象:

const AsyncComponent = () => ({// 需要加载的组件 (应该是一个 `Promise` 对象)component: import('./MyComponent.vue'),// 异步组件加载时使用的组件loading: LoadingComponent,// 加载失败时使用的组件error: ErrorComponent,// 展示加载时组件的延时时间。默认值是 200 (毫秒)delay: 200,// 如果提供了超时时间且组件加载也超时了,// 则使用加载失败时使用的组件。默认值是:`Infinity`timeout: 3000
})

异步组件的用处

当组件比较多或者有的组件耗时比较长的时候 要使用异步组件 可以提高其他同步组件的加载速度,提高用户的使用体验

组件传值的一些技巧 root parent children

除了传统通过poro $emit进行传值之外 还有一些技巧

子元素可以通过调用$parent的方法修改父元素的值

在子元素中 this.$parent 指向的就是父元素的vue实例

methods: {change: function(val) {this.$parent.theprice = '';this.$parent.theprice = val}}

与 prop相比 这是个技巧

$children

父组件通过$children可以找到子组件

例如图中所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tVfPHiC7-1601186966029)(C:%5CUsers%5Casus%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200919183211199.png)]

可以知道这是个数组 可以通过索引找到对应的组件 从而修改

$root

直接找到处于第一层的vue实例

但是不建议这样操作 因为耦合过高

全局变量

通过特定写法来挂载

Vue.prototype.名字='';

为了表明全局变量一般在名字前面加$,一般用于挂载axios,一般只建议读取全局对象而不建议修改,因为其他引用该变量的地方不会动态响应

Vue.prototype.$http=axios

组件插槽(看一下黑马视频 现在还不太懂)

  • 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力

  • Vue 自定义的 <slot> 元素

  • 在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。

  • 插槽内可以包含任何模板代码,包括 HTML ,甚至其他的组件

<navigation-link url="/profile"><!-- 添加一个图标的组件 --><font-awesome-icon name="user"></font-awesome-icon>Your Profile
</navigation-link>
  • 如果 组件 的 template没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。

  • 传递数据的方案 但是传递的是结构

  • 插槽一共就三大类
    1.匿名插槽(也叫默认插槽): 没有命名,有且只有一个
    2.具名插槽: 相对匿名插槽组件slot标签带name命名的
    3.作用域插槽: 子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)

匿名插槽

  <div id="app"><!-- 这里的所有组件标签中嵌套的内容会替换掉slot  如果不传值 则使用 slot 中的默认值  -->  <alert-box>有bug发生</alert-box><alert-box>有一个警告</alert-box><alert-box></alert-box></div><script type="text/javascript">/*组件插槽:父组件向子组件传递内容*/Vue.component('alert-box', {template: `<div><strong>ERROR:</strong># 当组件渲染的时候,这个 <slot> 元素将会被替换为“组件标签中嵌套的内容”。# 插槽内可以包含任何模板代码,包括 HTML<slot>默认内容</slot></div>`});var vm = new Vue({el: '#app',data: {}});</script>
</body>
</html>

具名插槽

与普通插槽相比 就是要在template上使用v-slot给插槽起个名字,然后在组件内部的slot上使用不同的name属性进行接收

<div id="app"><!-- 插槽的用法 --><!-- 匿名插槽 --><!-- 剧名插槽 --><slot-demo><template v-slot:juming><h3>演示剧名插槽用法2</h3></template><!-- v-slot可以缩写为#  但是这样的话如果是default不能省略--><template #juming2><h3>演示剧名插槽用法2</h3></template></slot-demo></div>  <script>let app = new Vue({el: '#app',data: {},methode: {},components: {slotDemo: {template: `<div><slot name="juming"></slot><slot name="juming2"></slot></div>`,}}})</script>

一个不带 name<slot> 会带有隐含的名字“default”。

作用域插槽(目的 在插槽中可以访问到子组件的内容)

插槽中可以传递参数,使得在使用插槽的时候可以访问到子组件中才有的数据

父级模板中的所有内容都是在父级作用域中进行编译

子模版中的内容在子级作用域中进行编译

在下面例子中 User属于子组件的内容

有时让插槽内容能够访问子组件中才有的数据是很有用的。例如,设想一个带有如下模板的 子组件:

<span><slot>{{ user.lastName }}</slot>
</span>

我们可能想在插槽中显示如下:

<current-user>{{ user.firstName }}
</current-user>

然而上述代码不会正常工作,因为只有 子组件可以访问到 user 而我们提供的内容是在父级渲染的。

为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 slot 元素的一个 attribute 绑定上去:

<span><slot v-bind:user="user">{{ user.lastName }}</slot>
</span>

绑定在 slot 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

<current-user><template v-slot:default="slotProps">{{ slotProps.user.firstName }}</template>
</current-user>

在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字。

作用域插槽步骤

总结作用域插槽的步骤:

1.在组件内部定义插槽prop,即添加一个属性,属性内容是你想让父组件使用的数据

2.在插槽中 在template中将所有插槽prop的对象进行一个命名,然后使用

3.在插槽中使用 v-slot进行数据绑定

  我这里直接展示 v-slot的用法
首先在子组件中
Child.vue
<slot :user="user"></slot>
export default {data(){return {user:{name:'小王'}}}
}
//父组件中的用法
Parent.vue
<child><template v-slot="slotProps"><h3>{{slotProps.user.name}}</h3></template>//你也可以使用解构的方式<template v-slot="{ user }"><h3>{{user.name}}</h3></template>
</child>

v-slot的缩写

v-onv-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header

然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

<!-- 这样会触发一个警告  因为这样所写的话default不能省略 -->
<current-user #="{ user }">{{ user.firstName }}
</current-user>

如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:

<current-user #default="{ user }">{{ user.firstName }}
</current-user>

后备内容

即插槽默认值,在子组件的slot中进行定义,如果没有传入插槽内容 则使用这个默认值,如果传入则使用传入的值

<button type="submit"><slot>Submit</slot>
</button>

进入离开列表过度

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。 也就是进入时所要进行的过度操作

    /* 进来的时候的位置  消失后点击   从1500px出现  一直移动到最开始  如果想移动到特定的位置可以使用enter-to   不过怕最后还是会返回到起始点*/.slide-enter {transform: translateX(1500px);opacity: .5;}
    
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。 也就是在进入这个阶段的状态

  3. v-enter-to2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。 定义进入时走到哪 但是完成后会被移除

    走到500px处  然后返回原点
    .slide-enter-to {transform: translateX(500px);}
    
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。 参考v-enter 不过一般不设置

  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。 参考v-enter-active

  6. v-leave-to2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。一般情况下与v-enter一起使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qKnkKjYZ-1601186966031)(file:///C:\Users\asus\AppData\Roaming\Tencent\Users\504708627\QQ\WinTemp\RichOle\LM]`B%LO2ISP29VAS~GQM90.png)]

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter

v-enter-activev-leave-active 可以控制进入/离开过渡的不同的缓和曲线,在下面章节会有个示例说明。

css过度

eg:

<div id="example-1"><button @click="show = !show">Toggle render</button><transition name="slide-fade"><p v-if="show">hello</p></transition>
</div>
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {transition: all .3s ease;
}
.slide-fade-leave-active {transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8  点击移动10px  再点击从10px处回来*/ {transform: translateX(10px);opacity: 0;
}
new Vue({el: '#example-1',data: {show: true}
})

原理:自动识别name 然后自动追加相对应的类名 比如进入时追加 name-enter-active name-enter

.slide-fade-enter, .slide-fade-leave-to一般一起使用

 /* 进来的时候的位置  消失后点击   从1500px出现  一直移动到最开始  如果想移动到特定的位置可以使用enter-to   不过怕最后还是会返回到起始点*/.slide-enter {transform: translateX(1500px);opacity: .5;}/* 移动的时候  移动到多远  点击button移动500px */.slide-leave-to {transform: translateX(500px);opacity: .5;}

自定义过度的类名

有的时候 我们希望可以调用别人已经写好的类来实现过度效果,这样就需要使用自定义的类名

我们可以通过以下 attribute 来自定义过渡类名:

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)

他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。

<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"><div id="example-3"><button @click="show = !show">Toggle render</button><transitionname="custom-classes-transition"enter-active-class="animated tada"leave-active-class="animated bounceOutRight"><p v-if="show">hello</p></transition>
</div>

通过自定义属性的方式来添加类名

这样也就是 v-enter-active就相当于 animated tada这个类

与一些第三方库一起使用比较方便

css 动画

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。

.bounce-enter-active {animation: bounce-in .5s;
}
.bounce-leave-active {animation: bounce-in .5s reverse;
}
@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.5);}100% {transform: scale(1);}
}

列表过度

比如有的时候我们需要使用v-for来渲染一个列表,给整个列表添加过渡效果

使用 transition-grou 其余用法与transition相同

 <transition-group name="list" tag="p"><span v-for="item in items" v-bind:key="item" class="list-item">{{ item }}</span></transition-group>

同时使用过度与动画

Vue 为了知道过渡的完成,必须设置相应的事件监听器。它可以是 transitionendanimationend,这取决于给元素应用的 CSS 规则。如果你使用其中任何一种,Vue 能自动识别类型并设置监听。

但是,在一些场景中,你需要给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,你就需要使用 type attribute 并设置 animationtransition 来明确声明你需要 Vue 监听的类型。

显性的过度持续时间

在很多情况下,Vue 可以自动得出过渡效果的完成时机。默认情况下,Vue 会等待其在过渡效果的根元素的第一个 transitionendanimationend 事件。然而也可以不这样设定——比如,我们可以拥有一个精心编排的一系列过渡效果,其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。

在这种情况下你可以用 <transition> 组件上的 duration prop 定制一个显性的过渡持续时间 (以毫秒计):

<transition :duration="1000">...</transition>

你也可以定制进入和移出的持续时间:

<transition :duration="{ enter: 500, leave: 800 }">...</transition>

动态过度

在 Vue 中即使是过渡也是数据驱动的!动态过渡最基本的例子是通过 name attribute 来绑定动态值。

<transition v-bind:name="transitionName"><!-- ... -->
</transition>

当你想用 Vue 的过渡系统来定义的 CSS 过渡/动画在不同过渡间切换会非常有用。

渲染函数&&JSX

Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。也就是render

可以用render来代替template,二者必有其一

<script>let app = new Vue({el: '#app',data: {msg: 123},components: {renderDemo: {render: (h, params) => {return h('div', {style: {width: '100px',height: '100px',background: '#ccc'}}, '地方')}},}})</script>
}
/* 移动的时候  移动到多远  点击button移动500px */.slide-leave-to {transform: translateX(500px);opacity: .5;
}

### 自定义过度的类名有的时候 我们希望可以调用别人已经写好的类来实现过度效果,这样就需要使用自定义的类名我们可以通过以下 attribute 来自定义过渡类名:- `enter-class`
- `enter-active-class`
- `enter-to-class` (2.1.8+)
- `leave-class`
- `leave-active-class`
- `leave-to-class` (2.1.8+)他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 [Animate.css](https://daneden.github.io/animate.css/) 结合使用十分有用。```html
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"><div id="example-3"><button @click="show = !show">Toggle render</button><transitionname="custom-classes-transition"enter-active-class="animated tada"leave-active-class="animated bounceOutRight"><p v-if="show">hello</p></transition>
</div>

通过自定义属性的方式来添加类名

这样也就是 v-enter-active就相当于 animated tada这个类

与一些第三方库一起使用比较方便

css 动画

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。

.bounce-enter-active {animation: bounce-in .5s;
}
.bounce-leave-active {animation: bounce-in .5s reverse;
}
@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.5);}100% {transform: scale(1);}
}

列表过度

比如有的时候我们需要使用v-for来渲染一个列表,给整个列表添加过渡效果

使用 transition-grou 其余用法与transition相同

 <transition-group name="list" tag="p"><span v-for="item in items" v-bind:key="item" class="list-item">{{ item }}</span></transition-group>

同时使用过度与动画

Vue 为了知道过渡的完成,必须设置相应的事件监听器。它可以是 transitionendanimationend,这取决于给元素应用的 CSS 规则。如果你使用其中任何一种,Vue 能自动识别类型并设置监听。

但是,在一些场景中,你需要给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,你就需要使用 type attribute 并设置 animationtransition 来明确声明你需要 Vue 监听的类型。

显性的过度持续时间

在很多情况下,Vue 可以自动得出过渡效果的完成时机。默认情况下,Vue 会等待其在过渡效果的根元素的第一个 transitionendanimationend 事件。然而也可以不这样设定——比如,我们可以拥有一个精心编排的一系列过渡效果,其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。

在这种情况下你可以用 <transition> 组件上的 duration prop 定制一个显性的过渡持续时间 (以毫秒计):

<transition :duration="1000">...</transition>

你也可以定制进入和移出的持续时间:

<transition :duration="{ enter: 500, leave: 800 }">...</transition>

动态过度

在 Vue 中即使是过渡也是数据驱动的!动态过渡最基本的例子是通过 name attribute 来绑定动态值。

<transition v-bind:name="transitionName"><!-- ... -->
</transition>

当你想用 Vue 的过渡系统来定义的 CSS 过渡/动画在不同过渡间切换会非常有用。

渲染函数&&JSX

Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。也就是render

可以用render来代替template,二者必有其一

<script>let app = new Vue({el: '#app',data: {msg: 123},components: {renderDemo: {render: (h, params) => {return h('div', {style: {width: '100px',height: '100px',background: '#ccc'}}, '地方')}},}})</script>
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 达梦数据库的学习

    一、部署环境 虚拟机VMware15 操作系统redhat7.5 达梦数据库DM8 二、安装前的检查 1.网络环境检查 数据库服务器都建议关闭防火墙&#xff0c;如果不关闭的话建议将相应的数据库端口开放&#xff08;如数据库对外服务默认端口5236&…...

    2024/5/4 16:58:55
  2. 第十二课、计算器的核心解析算法(上)------------------狄泰软件学院

    一、后缀表达式 1、人类习惯的数学表达式叫中缀表达式 2、另外&#xff0c;还有一种将运算符放在数字后面的表达式叫后缀表达式 2、中缀 or 后缀 &#xff08;1&#xff09;、中缀表达式符合人类的阅读和思维习惯 &#xff08;2&#xff09;、后缀表达式符合计算机的运算方…...

    2024/4/18 20:20:27
  3. chrome浏览器默认非安全端口列表带来的坑

    以下为Google Chrome 默认非安全端口列表: 访问会直接被拦截 1, // tcpmux7, // echo9, // discard11, // systat13, // daytime15, // netstat17, // qotd19, // chargen20, // ftp data21, // ftp access22, // ssh23, // telnet25, // smtp37, // time42, // name43, // n…...

    2024/4/30 7:18:09
  4. 剑指Offer——面试题18题目二:删除链表中重复的节点(C++)

    题目分析 要全面考虑重复节点所处的位置&#xff08;链表头部/中间/尾部&#xff09;&#xff0c;以及删除重复节点之后的结果。 实现代码 class Solution { public:ListNode* deleteDuplication(ListNode* pHead) {if (pHead nullptr) return nullptr;ListNode *pPreNode …...

    2024/5/1 19:47:29
  5. 递归求最大公约数

    No.3 递归求最大公约数 原理是辗转相除法 #include<iostream> using namespace std;int gcd(int x,int y) {if (y 0) {return x;}return gcd(y, x%y); }int main() {int x, y;while (cin >> x >> y) {cout << gcd(x, y) << endl;}return …...

    2024/4/8 10:39:29
  6. Zookeeper的PHP实践

    Apache Zookeeper是我最近遇到的最酷的技术&#xff0c;我是在研究Solr Cloud功能的时候发现的。Solr的分布式计算让我印象深刻。你只要开启一个新的实例就能自动在Solr Cloud中找到。它会将自己分派到某个分片中&#xff0c;并确定出自己是一个Leader&#xff08;源&#xff0…...

    2024/4/4 5:35:53
  7. STM32f103学习笔记——跑马灯

    Stm32f103学习笔记&#xff08;1&#xff09; 开发板&#xff1a;正点原子战舰V3 任务&#xff1a;点亮LED 引脚&#xff1a;led0:GPIOB_5,led1:GPIOE_5; ①库函数版本&#xff1a; 程序1 自建led.c库 #include"LED.h" #include"stm32f10x.h"void LED_…...

    2024/4/21 8:40:37
  8. Python使用xlwt推荐

    推荐...

    2024/4/28 14:42:38
  9. 解决chrome控制台查不到请求头的cookie

    原文链接&#xff1a;https://blog.csdn.net/qq_36838406/article/details/101943872 在做一个小项目的时候需要需要将token写如cookie中&#xff0c;然鹅&#xff0c;写完之后却没有在chrome浏览器的Response Headers中看到cookie&#xff0c;以为是代码写错&#xff0c;尝试…...

    2024/4/27 14:23:19
  10. Opencv之canny算子有关的知识

    相关知识 相关程序 cpp #include "stdafx.h"//本节讲述 图像处理之 canny边缘检测&#xff1b; #include <opencv2/opencv.hpp> #include <iostream> #include <math.h>using namespace std; using namespace cv;Mat src, dst, dst1, dst2, ds…...

    2024/5/4 14:29:07
  11. 概率论与数理统计

    ...

    2024/4/18 11:25:29
  12. RK3399-新老MIPI屏兼容问题

    RK3399-新老MIPI屏兼容问题&#xff1a; https://notes.z-dd.net/2020/09/06/RK3399-%E6%96%B0%E8%80%81MIPI%E5%B1%8F%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98/...

    2024/4/19 3:29:51
  13. 公共关系与人际交往能力答案

    本文转自公–仲--号【握手题库】【杨梅速查】 放假在家葛优躺大家可都还​满意吗&#xff1f;但不要忘记学习呦。毕竟现在要努力学习&#xff0c;在相对的年纪要做相对的事情。网课在身&#xff0c;还有一堆的习题困扰是不是有点头疼呢。 这里就教给大家一种快捷高效地查题方法…...

    2024/4/18 17:21:56
  14. numpy找出数组最大值

    def getPositon(data, genre): a np.mat(data) raw, column a.shape # 获取行和列 if genre ax:positon np.argmax(a) # 最大值的下标 else:positon np.argmin(a) # 最小值的下标m, n divmod(positon, column) # 找出行和列 return a[m, n]...

    2024/4/27 6:38:05
  15. 易飞打印报表报错不知道问题在哪

    易飞打印时报错&#xff0c;格式混乱&#xff0c;当时在服务器上设置的&#xff0c;服务器上打印&#xff0c;预览全没问题&#xff0c;百度半天没有解决方案 易飞V8停支持&#xff0c;我这没交维护费&#xff0c;老实复制一份重新设置打印格式&#xff0c;还有在用易飞的同仁…...

    2024/4/22 7:25:07
  16. 大讲堂:Oracle DataGuard备份恢复最佳实践(同时在线723人)

    《Oracle DataGuard 备份恢复最佳实践》&#xff0c;该课已被收录进「2020恩墨大讲堂」课程第25章&#xff09; PPT课件 直播预告 录像回看 视频回放 姚远2018CSDN认证博客专家10G OCM12C OCMOracle10g,12c OCM; MySQL 5.6,5.7,8.0 OCP;CCNA; EMC Certified; IBM P Certified…...

    2024/5/3 3:02:09
  17. 组合总和3

    找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数&#xff0c;并且每种组合中不存在重复的数字。 class Solution:def combinationSum3(self, k, n):res []def backtrack(path, index, n, k):if n 0 and k 0: #单次结束并添加的条件&#xff…...

    2024/4/17 10:29:49
  18. 【金融风控-贷款违约预测】数据挖掘学习:5.模型融合

    学习目标 将之前建模调参的结果进行模型融合。 内容介绍 模型融合是比赛后期上分的重要手段&#xff0c;特别是多人组队学习的比赛中&#xff0c;将不同队友的模型进行融合&#xff0c;可能会收获意想不到的效果哦&#xff0c;往往模型相差越大且模型表现都不错的前提下&am…...

    2024/4/4 11:25:56
  19. 创新思维与方法期末考试答案

    本文转自公–众--号【握手题库】【杨梅速查】 放假在家的童鞋们好呀&#xff0c;今年线上上课都有没有好好听呐&#xff1f;课后作业都做完了没有呐&#xff1f;什么&#xff0c;你的大物、高数题目找不到答案&#xff1f;那接下来就看我的吧。 输入题目即可找到答案。支持语…...

    2024/5/2 22:12:20
  20. 【软件】常用开发软件集合

    前言 常用的开发软件集合&#xff0c;保存在一些不限速的网盘 开发工具 中间件 rabbitmq&#xff1a;rabbitmq-server-3.8.5.exe https://cowtransfer.com/s/9afc25d2d42944 6k4r5f 服务器 tomcat8 数据库 redis客户端&#xff1a;RedisDesktopClient Setup 1.3.2.exe https://…...

    2024/5/3 5:04:37

最新文章

  1. 抖音小店怎么运营操作,无货源正确做店方式,新手就看这一篇

    大家好&#xff0c;我是电商笨笨熊 当前抖店还能做无货源模式吗&#xff1f; 当然可以。 近两年由于平台对于无货源的打击&#xff0c;很多人开始怀疑&#xff0c;无货源模式在抖店还能行得通吗&#xff1f; 抖店这个项目我们做了四年多的时间&#xff0c;无货源模式也是&a…...

    2024/5/4 22:05:26
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Python读取文件里内容

    如果要读取一个文件里的内容是 # 文件名&#xff1a;db.txt 1 2 3 4代码如下 import requests f open("db.txt", mode"rb") content f.read() f.close()data content.decode(utf-8)# 存到 list 里 data_list data.split(\r\n) print(data_list)# 结果…...

    2024/5/3 15:30:08
  4. [C++/Linux] UDP编程

    一. UDP函数 UDP&#xff08;用户数据报协议&#xff0c;User Datagram Protocol&#xff09;是一种无连接的网络协议&#xff0c;用于在互联网上交换数据。它允许应用程序发送数据报给另一端的应用程序&#xff0c;但不保证数据报能成功到达&#xff0c;也就是说&#xff0c;它…...

    2024/5/3 8:59:07
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/4 12:05:22
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/4 11:23:32
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/4 14:46:16
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/3 16:00:51
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/4 12:10:13
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/3 21:22:01
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/3 23:17:01
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/4 14:46:12
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/4 14:46:11
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/4 14:46:11
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/4 2:14:16
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/4 21:24:42
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/4 12:39:12
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/4 13:16:06
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/4 16:48:41
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/4 14:46:05
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/4 2:00:16
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/3 22:03:11
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/4 9:07:39
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/4 14:46:02
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57