一、Vue实例配置选项

选项 说明
data Vue实例数据对象
methods 定义Vue中的方法
components 定义子组件
computed 计算属性
filters 过滤器
el 唯一根标签
watch 监听数据变化

1.el唯一根标签

在创建Vue实例时,el表示唯一根标签,class或id选择器可以用来将页面结构与Vue实例对象中的el绑定。

<div id="app">{{name}}</div>
<script>var vm=new Vue({el:"#app",data:{name:"Vue实例创建成功!"}})
</script>

2.data初始数据

Vue实例的数据对象为data,Vue会将data的属性转换为getter,setter,从而让data的属性都能够响应数据变化。

Vue实例创建后,可以通过**vm.data∗∗访问原始数据对象。Vue实例也代理了data对象上所有的属性,因此访问vm.name相当于访问vm.data**访问原始数据对象。Vue实例也代理了data对象上所有的属性,因此访问vm.name相当于访问vm.data∗∗访问原始数据对象。Vue实例也代理了data对象上所有的属性,因此访问vm.name相当于访问vm.data.name。

2.1 data赋值方式一

<div id="app"><p>{{name}}</p>
</div>
<script>var vm=new Vue({el:'#app',data:{name:'定义初始数据'}})console.log(vm.$data.name);console.log(vm.name);
</script>

2.2 data赋值方式二

<div id="vue_data"><h3>{{site}}</h3><h3>{{url}}</h3><h3>{{student}}</h3>
</div>
<script>// 字典var data = {site: "菜鸟教程",url: "https://www.baidu.com",student: "Tom"};var vm = new Vue({el: "#vue_data",data: data});var h3 = document.querySelector('h3');h3.addEventListener('click', function () {data.site = '百度';});console.log(vm.site === data.site);console.log(vm.$data.site === data.site);console.log(vm.$data === data);
</script>

3.methods定义方法

methods属性用来定义方法,通过Vue实例可以访问这些方法。在定义的方法中,this指向Vue实例本身。定义在methods属性中的方法可以作为页面中的事件处理方法使用,当事件被触发后,执行相应的事件处理方法。

<div id="app"><button @click="showInfo">请单击</button><p>{{msg}}</p>
</div>
<script>var vm=new Vue({el:'#app',data:{msg:''},mehods:{//定义时间处理方法showInfoshowInfo(){this.msg='触发单击事件'}}})
</script>

4.computed计算属性

Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动,当有一些数据需要随着其他数据而变动时,就需要使用computed计算属性

在事件处理方法中,this指向的Vue实例的计算属性结果会被缓存起来,只有依赖的响应式属性变化时,才会重新计算,返回最终结果。

4.1 案例:增加数量计算总价

<div id="app"><p> 总价格:{{totalPrice}}</p><p> 单价:{{price}}</p><p> 数量:{{num}}</p><div><button @click="num == 0?0:num--">减少数量</button><button @click="num++">增加数量</button></div>
</div>
<script>var vm = new Vue({el: "#app",data: {price: 20,num: 0},methods: {//整个页面重新渲染的时候才会执行sum: function () {return this.price * this.num;}},computed: {//依赖的缓存被更改的时候就会执行,在有依赖的情况下执行效率要高一点//总价格计算totalPrice: function () {return this.price * this.num;}}});
</script>

5.watch状态监听

Vue提供了watch状态监听功能,只需监听当前Vue实例中的数据变化,就会调用数据所绑定的事件处理方法

5.1 基础使用

<div id="app"><input type="text" v-model="cityName">
</div>
<script>var vm=new Vue({el:'#app',data:{cityName:'shanghai'},// 使用watch监听cityName变化watch:{cityName(newName,oldName){// 打印新数据和旧数据console.log(newName,oldName);}}})
</script>

5.2 计算总价

<div id="app"><p> 总价格:{{sum}}</p><p> 单价:{{price}}</p>数量:<input type="number" v-model="num"/><div><button @click="num == 0?0:num--">减少数量</button><button @click="num++">增加数量</button></div>
</div>
<script>var vm = new Vue({el: "#app",data: {sum: 0,price: 20,num: 0},watch: {num(newData, oldData) {if (newData < 0) {this.num = 0;}this.sum = newData * this.price;}}});
</script>

5.3 距离转换km<=>m

<h2>距离转换</h2>
<div id="km_m"><input type="number" v-model="km"/>千米<br/><input type="number" v-model="m"/>米<br/>
</div>
<div id="info"></div>
<script>var vm1 = new Vue({el: "#km_m",data: {km: 0,m: 0},watch: {km: function (newData, oldData) {this.m = newData * 1000;},m: function (newData, oldData) {this.km = newData / 1000;}}});vm1.$watch('km', function (newValue, oldValue) {var info = document.querySelector('#info');info.innerHTML = '修改前的值是' + oldValue + ',修改后的值是' + newValue;})
</script>

3-4-5.methods、computed、watch区别

<h2>三个属性的区别</h2>
<div id="name">姓:<input type="text" v-model="firstName"/>名:<input type="text" v-model="lastName"/><h4>用methods形式打印全名{{methodFullName()}},年龄{{age}}</h4><h4>用computed形式打印全名{{computedFullName}},年龄{{age}}</h4><h4>用watch形式打印全名{{watchFullName}},年龄{{age}}</h4>
</div>
<script>var vm2 = new Vue({el: '#name',data: {firstName: '张',lastName: '三',age: 18,watchFullName: '张三'},methods: {methodFullName: function () {console.log("这是方法返回的全名");return this.firstName + this.lastName;}},computed: {computedFullName: function () {console.log("这是计算返回的全名");return this.firstName + this.lastName;}},watch: {firstName: function (newValue) {console.log('这是监听属性firstName的返回');this.watchFullName = newValue + this.lastName;},lastName: function (newValue) {console.log('这是监听属性lastName的返回');this.watchFullName = this.firstName + newValue;}}})
</script>

6.filters过滤器

数据变化除了在Vue逻辑层进行操作外,还可以通过过滤器来实现。

6.1在插值表达式中使用过滤器

通过"{{data}}“语法,可以将data中的数据插入页面中,该语法就是插值表达式,插值表达式中还可以使用过滤器来对数据进行处理,语法为”{{data | filter}}"

<div id="app">{{message|toUpcase|toLowcase}}
</div>
<script>var vm = new Vue({el: '#app',data: {message: "abcdefg"},filters: {// 参数value表示传到过滤器中的数据toUpcase: function (value) {// 将abcdefg转换为ABCDEFGreturn value ? value.toUpperCase() : '';},toLowcase: function (value) {// 将ABCDEFG转换为abcdefgreturn value ? value.toLowerCase() : '';}}})
</script>

6.2在v-bind属性绑定中使用过滤器

v-bind用于属性绑定,如"v-bind:id=”data““表示绑定id属性,值为data。在data后面可以加过滤器,语法为"data|filter”。

<div id="app"><div v-bind:id="dataId | formatId">helloworld</div>
</div>
<script>var vm=new Vue({el:'#app',data:{dataId:'dff1'},filters:{//字符串处理return value?vlaue.charAt(1)+value.indexOf('d'):'';}})
</script>

二、Vue数据绑定

1.绑定样式

1.1 绑定内联样式

在Vue实例中定义的初始数据data,可以通过v-bind将样式数据绑定给DOM元素

<div id="app"><!--绑定样式属性值--><div v-bind:style="{backgroundColor:pink,width:width,height:height}"><div v-bind:style="myDiv"></div></div>
</div>
<script>var vm = new Vue({el: '#app',data: {myDiv: {backgroundColor: 'red', width: '100px', height: '100px'},pink: 'pink',width: '100%',height: '200px',}});
</script>

1.2绑定样式类

样式类即以类名定义元素的样式

<div id="app"><div v-bind:class="{box}">我是box<div v-bind:class="{inner}">我是inner</div><div v-bind:class="{inner,text}">我是inner</div></div>
</div>
<script>var vm = new Vue({el: '#app',data: {box: 'box',inner: 'inner',text: 'text'}});
</script>

1.3样式数组

<!--绑定的是数组-->
<div id="myArr"><div v-bind:style="[baseStyle,myStyle]">今天是周四</div>
</div>
<script>var myvm = new Vue({el: '#myArr',data: {baseStyle: {color: 'red',fontSzie: '30px',},myStyle: {'font-weight': 'bold'}}})
</script>

1.4是否加载样式

<!--是否加载类样式-->
<div id="flag_css"><div v-bind:class="{inner,active:isActive}"></div>
</div>
<script>var flag_css = new Vue({el: "#flag_css",data: {inner: 'inner',isActive: true,active: 'active'}})
</script>

1.5样式绑定综合

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>内联样式属性</title><script src="js/vue.js"></script><style>.active {width: 100px;height: 100px;background-color: blue;}.mytext {background-color: red;}</style>
</head>
<body>
<div id="app"><div v-bind:class="{'active':isActive,'mytext':hasError}"></div><button @click="upIsActive">isActive</button><button @click="upHasError">hasError</button>
</div>
<script>var vm = new Vue({el: '#app',data: {isActive: true,hasError: true},methods: {upIsActive: function () {this.isActive = !this.isActive;},upHasError: function () {this.hasError = !this.hasError;}}})
</script>
<!-- 对象表示形式 -->
<div id="app1"><div v-bind:class="obj"></div><button @click="upIsActive">isActive</button><button @click="upHasError">hasError</button>
</div>
<script>var vm1 = new Vue({el: '#app1',data: {obj: {active: true,mytext: true}},methods: {upIsActive: function () {this.obj.active = !this.obj.active;},upHasError: function () {this.obj.mytext = !this.obj.mytext;}}})
</script>
<!-- 计算属性绑定 -->
<div id="app2"><div v-bind:class="comNum"></div><button @click="upIsActive">isActive</button>
</div>
<script>var vm2 = new Vue({el: '#app2',data: {isActive: true,num: 100},methods: {upIsActive: function () {this.isActive = !this.isActive;}},computed: {comNum: function () {return {active: this.isActive && this.num >= 100,hasError: this.isActive && this.num < 100}}}})
</script>
</body>
</html>

2.内置指令

指令 说明
v-model 双向数据绑定,页面修改同步
v-on 监听事件,可简写为“@”
v-bind 单向数据绑定,页面修改不同步,可简写为“:”
v-text 插入文本内容
v-html 插入包含HTML的内容
v-for 列表渲染
v-if 条件渲染
v-show 显示隐藏

2.1 v-model 双向数据绑定

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>内置指令</title><script src="js/vue.js"></script>
</head>
<body>
<!-- v-model双向数据绑定 -->
<div id="app"><label>姓名<input type="text" v-model="name"/></label><label>年龄<input type="number" v-model="age"/></label><label>性别<input type="text" v-model="sex"/></label><hr/><p>姓名:{{name}}<br/>年龄:{{age}}<br/>性别:{{sex}}</p>
</div>
<script>var vm = new Vue({el: '#app',data: {name: '张三',age: 18,sex: '男'}})
</script>
</script>
</body>
</html>

2.2 v-bind 单向数据绑定

数据仅可从model端view端,详细请看绑定样式

2.3 v-text 文本填充

向DOM中添加文本内容

<!-- v-text插入文本内容 -->
<div id="app1"><p v-text="msg"></p>
</div>
<script>var vm = new Vue({el: '#app1',data: {msg: '我是v-text'}})
</script>

2.4 v-html HTML标签填充

<!-- v-html HTML标签填充 -->
<div id="app2"><div v-html="h"></div>
</div>
<script>var vm = new Vue({el: '#app2',data: {h: '<h1>我是v-html</h1>'}})
</script>

2.5 v-on 事件监听指令

<!-- v-on 事件监听 -->
<div id="app3"><button @click="showAlert">v-on</button><input type="text" @keyup.enter="submit"/>
</div>
<script>var vm = new Vue({el: '#app3',methods: {showAlert: function () {alert('v-on')},submit: function () {alert('登录成功!')}}})
</script>

2.6 v-for 列表循环

v-for 可以实现页面列表的渲染,常用来循环数组。

<!-- v-for 列表渲染-->
<div id="app4"><div v-for="(item,key) in list" data-id="key">索引是:{{key}},元素内容是:{{item}}</div>
</div>
<script>var vm = new Vue({el: '#app4',data: {list: ['a', 'b', 'c', 'd']}})
</script>

2.7 v-if 或v-show

控制元素显示隐藏,属性为布尔值。

v-if真正的条件渲染,会触发一些绑定的事件,惰性的,如果初始条件是false原始元素就不会进行渲染。条件不经常切换使用这个

v-show:简单进行css样式切换,初始条件为false也会进行渲染,初始渲染开销大。条件经常改变的话常用这个

<!-- v-if 和 v-show -->
<div id="app5"><div v-if="isShow" style="background-color: #ccc;">我是v-if</div><div v-show="isShow" style="background-color: #ccc;">我是v-show</div><button @click="isShow=!isShow">显示/隐藏</button>
</div>
<script>var vm = new Vue({el: '#app5',data: {isShow: true}})
</script>

3.事件修饰符

修饰符 说明
.stop 阻止事件冒泡
.prevent 阻止默认事件行为
.capture 事件捕获
.self 将事件绑定到自身,只有自身才能触发
.once 事件只触发一次

3.1 stop 阻止事件冒泡

<!-- 阻止事件冒泡 -->
<div id="app1" @click="doParent" style="width: 100px;border: solid red 1px;"><button @click="doThis">事件冒泡</button><br/><button @click.stop="doThis">阻止事件冒泡</button>
</div>
<script>var vm = new Vue({el: '#app1',methods: {doThis: function () {alert('this');},doParent: function () {alert('parent');}}})
</script>

3.2 prevent 阻止默认行为

<!-- 阻止默认事件 -->
<div id="app2"><a href="https://www.baidu.com">不阻止默认事件</a><br/><a href="https://www.baidu.com" @click.prevent>阻止默认事件</a>
</div>
<script>var vm = new Vue({el: '#app2'})
</script>

3.3 capture 事件捕获

<!-- 改变冒泡顺序,事件由外向内 -->
<div id="app3" @click.capture="doParent" style="width: 100px;border: solid red 1px;"><button @click="doThis">事件捕获</button>
</div>
<script>var vm = new Vue({el: '#app3',methods: {doThis: function () {alert('this');},doParent: function () {alert('parent');}}})
</script>

3.4 self 自身触发

<!-- self 只有自身会触发时间,不会被冒泡触发 -->
<div id="app4" @click.self="doParents" style="width: 100px;height: 100px;background-color: #aaaa;">a<div @click="doSub" style="width: 70px;height: 70px;background-color: #5555;">b</div>
</div>
<script>var vm = new Vue({el: '#app4',methods: {doParents: function () {console.log('调用了doParent');},doSub: function () {console.log('调用了doSub');}}})
</script>

3.5 once 只触发一次

<!-- once 事件只触发一次 -->
<div id="app5"><button @click.once="doThis">只触发一次</button>
</div>
<script>var vm = new Vue({el: '#app5',methods: {doThis: function () {console.log('只触发一次')}}})
</script>

三、Vue组件

在Vue中,组件是构成页面中的独立结构单元,能够减少重复代码的编写,提高开发效率,降低代码之间的耦合程度,使项目更易维护和管理。

举例:如果页面中常常要有公司logo那么可以将logo定义为组件。

1.全局组件

在js内部使用**Vue.component(‘组件名’,{template:‘标签’})**可以定义全局组件

<div id="app"><my-component></my-component><my-component></my-component><my-component></my-component>
</div>
<div id="app1"><myComponent>aaa</myComponent>
</div>
<script>// 全局组件Vue.component('myComponent',//组件名称,命名的时候可以用驼峰命名法,引用的时候不能使用驼峰命名法,只能使用连接法{template: "<h2>这是一个全局组件</h2>"//模板就是组件的内容});Vue.component('my-abc',{// data是方法,该方法必须要有返回值,通常该返回值是给模板使用的data() {return {count: 0}},template: "<button v-on:click='count++'>被单击了{{count}}次</button>"});new Vue({el: '#app'});new Vue({el: '#app1'})
</script>

2.局部组件

Vue()内部使用components关键字定义自定义组件

<!-- 局部组件 -->
<div id="app2"><my-abc></my-abc>
</div>
<script>new Vue({el: "#app2",components: {myAbc: {template: "<p>这是一个局部组件</p>"}}})
</script>

3.模板变量

将template模板使用变量装起来,使用的时候直接调用该变量即可。

<div id="app3"><my-aaa></my-aaa>
</div>
<script>//模板变量var mytemp = {template: '<h3>这是第二个局部组件</h3>'};new Vue({el: '#app3',components: {myAaa: mytemp}});
</script>

4.template模板

template内的内容是使用字符串保存的很容易出错,所以我们可以使用template标签html内部定义自定义组件的内容。

注意:template标签下只能有一个子标签

<!-- template 模板 -->
<div id="app4"><my-comp></my-comp>
</div>
<template id="temp1"><div><h1>这是一个标题</h1><p>这是一个段落:{{title}}</p><button v-on:click="show">单击我</button></div>
</template>
<script>Vue.component('my-comp', {template: '#temp1',data() {return {title: '我是组件内的title'}},methods: {show: function () {alert(this.title)}}});new Vue({el: '#app4'})
</script>

5.数据使用规则

vue定义的标签下面使用的自身data内的变量

template下自定义标签使用的变量是data()函数返回来的数据变量

注意:data()函数必须要有返回值

<div id="app5"><p>{{title}}</p><my-comp2></my-comp2>
</div>
<template id="temp2"><p>{{title}}</p>
</template>
<script>Vue.component('my-comp2',{template: '#temp2',data() {return {title: '这是组件中的data'}}});new Vue({el: '#app5',data: {title: '我是vm实例的title'}})
</script>

6.组件传值

在Vue中,组件实例具有局部作用域。组件之间的数据传递需要借助一些工具。

6.1 props传值

props即道具,用来接受父组件中定义的数据,其值为数组,数组中是父组件传递的数据信息。

在调用**自定义组件(父组件)的时候使用“ 自定义属性=‘值’ ”的形式想模板中传递数据,子组件中使用“props:[‘name’]”**形式读取到父组件中的自定义属性值。

<!-- props 传值 -->
<div id="app"><my-comp name="Tom"></my-comp>
</div>
<script>Vue.component("my-comp",{props: ['name'],template: '<h2>从组件中传递的值是:{{name}}</h2>'});new Vue({el: '#app'});
</script>
<div id="app1"><my-comp1 props-message="父组件的数据"></my-comp1>
</div>
<template id="temp1"><div><h3>父组件传给子组件</h3><p>通过props传递的,用props设置的值是组件(自定义标签)的属性名称</p><h4>父组件传递了:{{propsMessage}}</h4><h4>子组件自生的值:{{dataMessage}}</h4></div>
</template>
<script>Vue.component('my-comp1',{template: '#temp1',data() {return {dataMessage: '子组件中的数据'}},props: ['propsMessage']});new Vue({el: '#app1'})
</script>

6.2 父组件用循环传值

案例一:通过循环创建网站列表

<div id="app"><ol><todo-item v-for="item in sites" v-bind:todo="item"></todo-item></ol>
</div>
<script>Vue.component('todo-item', {template: "<li>{{todo.text}}</li>",props: ['todo']});new Vue({el: '#app',data: {sites: [{text: 'www.taobao.com'},{text: 'www.jingdong.com'},{text: 'www.baidu.com'},]}})
</script>

案例二:通过循环创建子组件表格

<div id="app1"><table><!--此处使用的是标题类--><student-list v-bind:stu="title"></student-list><!--此处使用的是遍历学生信息列表类--><student-list v-for="item in students" v-bind:stu="item"></student-list></table>
</div>
<template id="temp1"><!--每一个模板为一行,行内有四个列:ID NAME AGE SEX--><tr><td style="border: 1px solid #000">{{stu.id}}</td><td style="border: 1px solid #000">{{stu.name}}</td><td style="border: 1px solid #000">{{stu.age}}</td><td style="border: 1px solid #000">{{stu.sex}}</td></tr>
</template>
<script>Vue.component('student-list', {template: '#temp1',props: ['stu']});new Vue({el: '#app1',data: {title: {id: 'ID',name: 'NAME',age: 'AGE',sex: 'SEX'},students: [{id: '0001', name: '张三', age: 18, sex: '男'},{id: '0002', name: '田媛媛', age: 18, sex: '女'},{id: '0003', name: '陈雨', age: 20, sex: '男'},]}})
</script>

6.3 组件多个属性传值

案例一:v-bind 基本多属性传值

<div id="app"><p>第一个值<input type="text" v-model="s1"/></p><p>第二个值<input type="text" v-model="s2"/></p><p>第三个值<input type="text" v-model="s3"/></p><hr/><!--通过设置多个绑定来像子组件传递多个单值--><my-comp v-bind:attr1="s1" v-bind:attr2="s2" v-bind:attr3="s3"></my-comp>
</div>
<template id="my-temp"><div><h3>多个属性的传值</h3><p>值1:{{attr1}}</p><p>值2:{{attr2}}</p><p>值3:{{attr3}}</p></div>
</template>
<script>Vue.component('my-comp', {template: '#my-temp',props: ["attr1", "attr2", "attr3"]});new Vue({el: '#app',data: {s1: '',s2: '',s3: ''}})
</script>

案例二:多个属性传值双向绑定

<div id="app"><p>第一个值<input type="text" v-model="s1"/></p><p>第二个值<input type="text" v-model="s2"/></p><p>第三个值<input type="text" v-model="s3"/></p><hr/><my-comp v-bind:attr1="s1" v-bind:attr2="s2" v-bind:attr3="s3"></my-comp>
</div>
<template id="my-temp"><div><h3>多个属性的传值</h3><p>值1:{{attr1}}</p><p>值2:{{attr2}}</p><p>值3:{{attr3}}</p><p>点击按钮后得到的值:{{content1}}</p><p>及时得到的值:{{content2}}</p><p>计算得到的值:{{contentx}}</p><button @click="show">按钮</button></div>
</template>
<script>Vue.component('my-comp', {template: '#my-temp',props: ["attr1", "attr2", "attr3"],data: function () {return {content1: "",content2: ""}},methods: {//方法:按钮触发show() {this.content1 = this.attr1 + this.attr2 + this.attr3;}},watch: {//数据监听attr1: function () {this.content2 = this.attr1 + this.attr2 + this.attr3;},attr2: function () {this.content2 = this.attr1 + this.attr2 + this.attr3;},attr3: function () {this.content2 = this.attr1 + this.attr2 + this.attr3;},},computed:{//数据计算contentx:function () {return this.attr1 + this.attr2 + this.attr3;}}});new Vue({el: '#app',data: {s1: '',s2: '',s3: ''}})
</script>

6.4 $emit方法 子组件像父组件传值

语法

this.$emit('处理方法', 数据);

案例

<div id="app"><!--父组件--><parent></parent>
</div>
<template id="child"><!--子组件模板--><div><button @click="click">传值</button><!--绑定了子组件中的message属性--><input type="text" v-model="message"/></div>
</template>
<script>//父组件Vue.component('parent', {//父组件模板,子组件通过@childFn绑定了一个父组件事件处理方法,子组件可以通过该方法改变父组件中message的值template: '<div><child @childFn="transContent"></child>子组件传来的值:{{message}}</div>',data: function () {return {// 父组件中的messagemessage: ''}},methods: {//通过该事件处理方法可以修改父组件中message的值transContent: function (payload) {this.message = payload;}}});//子组件Vue.component('child', {template: '#child',data: function () {return {//子组件中的message属性message: '子组件的消息'}},methods: {click() {//激活调用父组件中childFn绑定的事件,传的值是messagethis.$emit('childFn', this.message);//有点像java里面的super?}}});new Vue({el: '#app'})
</script>

7.组件切换

7.1 v-if v-else形式切换

<div id="app"><label>第一个页面内容<input type="text" v-model="titleLogin"/></label><label>第二个页面内容<input type="text" v-model="titleRegister"/></label><br/><!--通过点击事件修改flag属性--><a href="#" @click.prevent="flag=true">登录页面</a><a href="#" @click.prevent="flag=false">注册页面</a><!--v-if v-else 配个标志属性进行简单的隐藏切换--><login v-if="flag" :title-name="titleLogin"></login><register v-else="flag" :title-name="titleRegister"></register>
</div>
<script>// div的基本样式Vue.component('login', {props: ['title-name'],template: '<div style="width: 100px;height: 100px;background-color: #00ff00;color: red">{{titleName}}</div>'});Vue.component('register', {props: ['title-name'],template: '<div style="width: 100px;height: 100px;background-color: #007ff0;color: yellow">{{titleName}}</div>'});new Vue({el: '#app',data: {flag: true,titleLogin: '登录',titleRegister: '注册'}})
</script>

7.2 is属性组件切换

<div id="app"><!-- 通过is属性修改模板的名字 --><a href="#" @click.prevent="comName='login'">登录页面</a><a href="#" @click.prevent="comName='register'">注册页面</a><!-- is绑定模板名字,被绑定的名字被修改则显示的模板也会被修改 --><component :is="comName"></component>
</div>
<script>Vue.component('login', {props: ['title-name'],template: '<div style="width: 100px;height: 100px;background-color: #00ff00;color: red">{{登录页面}}</div>'});Vue.component('register', {props: ['title-name'],template: '<div style="width: 100px;height: 100px;background-color: #007ff0;color: yellow">{{注册页面}}</div>'});new Vue({el: '#app',data: {comName: 'login',}})
</script>

四、Vue的生命周期

1.钩子函数

钩子函数用来描述Vue实例从创建到销毁的的整个生命周期

钩子 说明
beforeCreate 创建实例对象之前执行
created 创建实例对象之后执行
beforeMount 页面挂在成功之前执行
mounted 页面挂在成功之后执行
beforeUpdate 组件更新之前执行
updated 组件更新之后执行
beforeDestroy 实例销毁之前执行
destroyed 实例销毁之后执行

1.1实施创建

<div id="app">{{msg}}</div>
<script>new Vue({el: '#app',data: {msg: '张三'},beforeCreate() {console.log('实例创建之前');// console.log(this.$data.msg);},created() {console.log('实例创建之后');console.log(this.$data.msg);}})
</script>

1.2实施销毁

<div id="app"><!--ref是用来注册引用信息的--><div ref="self">{{msg}}</div>
</div>
<script>new Vue({el: '#app',data: {msg: '张三'},beforeDestroy(){console.log('销毁之前');console.log(this.$refs.self);console.log(this.msg);console.log(vm);},destroyed(){console.log('销毁之后')}})
</script>

1.3实时更新

<div id="app"><!--ref是用来注册引用信息的--><div v-if="isShow" ref="self">test</div><button @click="isShow=!isShow">更新</button>
</div>
<script>new Vue({el: '#app',data: {isShow: false},beforeUpdate() {console.log('更新之前');console.log(this.$refs.self);},updated() {console.log('更新之后');console.log(this.$refs.self);}})
</script>

1.4页面挂载

<div id="app">{{msg}}</div>
<script>new Vue({el: '#app',data: {msg: '张三'},beforeMount() {//Vue与DOM关联之前console.log('页面挂载之前');console.log(this.$el.innerHTML);},mounted() {//Vue与DOM关联之后console.log('页面挂载之后');console.log(this.$el.innerHTML);},beforeCreate() {console.log('实例创建之前');// console.log(this.$data.msg);},created() {console.log('实例创建之后');console.log(this.$data.msg);}})
</script>

1.5案例:实时显示时间

<div id="app"><p id="time"></p><h3>格式化时间</h3><p>{{date|formatTime}}</p><p><button @click="stop">停止时间</button></p>
</div>
<script>var p1 = document.querySelector('#time');p1.innerHTML = new Date();function parseDate(val) {return val < 10 ? '0' + val : val;//小于10的数字,前面加0}var vm = new Vue({el: '#app',data: {date: new Date(),},filters: {formatTime: function (time) {var year = time.getFullYear();var month = parseDate(time.getMonth() + 1);var day = parseDate(time.getDate());var hours = parseDate(time.getHours());var minute = parseDate(time.getMinutes());var seconds = parseDate(time.getSeconds());return year + '-' + month + '-' + day + " " + hours + ':' + minute + ':' + seconds;}},created: function () {var that = this;//保持作用域的一致,此处that就是当前对象this.timmer = setInterval(function () {that.date = new Date();}, 1000);},methods: {stop: function () {clearInterval(this.timmer)}}})
</script>

五、插槽

使用方法为:

  1. 在自定义组件标签中间写上预留内容。
  2. 在模板中使用标签,将预留内容引入。(假如模板中未使用标签,那么自定义标签中间的内容将会被忽略。)

1.插槽简单使用

当组件渲染的时候,将会被插槽预留的内容所替换,如下案例:

<div id="app"><my-comp><h5>这是组件,在组件中写内容</h5></my-comp>
</div>
<template id="temp1"><div><!-- 插槽就是模板预留的接口--><slot></slot><!--会替换为:<h5>这是组件,在组件中写内容</h5>--><p>这是模板内容,段落1</p><p>这是模板内容,段落2</p><p>这是模板内容,段落3</p><slot></slot><p>模板中的数据{{tempData}}</p><slot></slot></div>
</template>
<script>Vue.component('my-comp',{template: '#temp1',data:function () {return{tempData: new Date()}}});new Vue({el: "#app",})
</script>

2.简单使用2

<div id="app"><my-comp1>辣椒炒肉</my-comp1><my-comp1>辣椒炒蛋</my-comp1><my-comp1>空心菜</my-comp1><hr/><!--此处采用v-for循环遍历的形式将foods里面的值引入到自定义标签中--><my-comp1 v-for="item in foods">{{item.name}}</my-comp1><hr/><my-comp1></my-comp1>
</div>
<template id="temp1"><dl><dt><!--通过slot标签将自定义标签中的内容引入进来--><slot>默认值,使用时没有给内容</slot><!--默认值:如果自定义标签内部没有内容将会使用slot标签中间的内容--></dt><dd>中国湘菜,湘菜最强。</dd></dl>
</template>
<script>Vue.component('my-comp1', {template: '#temp1'});new Vue({el: '#app',data: {foods: [{name: '辣椒炒肉'},{name: '辣椒炒蛋'},{name: '辣子鸡'}]}})
</script>

3.具名插槽

在定义自定义标签的预留内容的时候将标签加上slot='名字’属性,那么在标签调用插槽的时候,就需要用name='名字’匹配使用。

<div id="app"><my-compl><!--这个标签只有当slot标签name属性为'girl'的时候才会被匹配使用--><span style="background-color: pink;" slot="girl">漂亮、温柔、贤惠</span><!--这个标签只有当slot标签name属性为'boy'的时候才会被匹配使用--><span style="background-color: #007fff" slot="boy">帅气,高大,富有</span><!--默认的内容,如果没有匹配到的对象就会使用该默认内容--><div>打工仔、干饭人、舔狗</div></my-compl>
</div>
<template id="templ"><div><h4>这个世界有男人和女人</h4><p>女人:<!--匹配引入了自定义标签中,slot属性为‘girl'的标签--><slot name="girl"></slot></p><p>男人:<!--匹配调用了自定义标签中,slot属性为‘boy'的标签--><slot name="boy"></slot></p><!--调用了自定义标签中的默认内容--><slot></slot></div>
</template>
<script>Vue.component('my-compl', {template: '#templ'});new Vue({el: '#app'})
</script>

4.案例:标题、正文、页脚匹配

此处我们也能看出,采用自定义控件+插槽的形式会使得控件格式更好规范添加。

<div id="app"><my-compl><!--定义了标题、内容、页脚部分,还有默认内容--><h3 slot="headerName">这是我的主页</h3><p slot="mainName">这是我的主页内容</p><h4 slot="footerName">这是页脚部分</h4><p>今天是2021年的4月25日</p></my-compl>
</div>
<template id="templ"><div><header><!--匹配标题部分--><slot name="headerName">页面标题</slot></header><mian><!--匹配正文部分--><slot name="mainName">正文部分</slot><slot>默认插槽</slot></mian><footer><!--匹配页脚部分--><slot name="footerName">页脚部分</slot></footer></div>
</template>
<script>Vue.component('my-compl', {template: '#templ'});new Vue({el: '#app'})
</script>

5.插槽作用域

通过slot-scope(插槽作用域)刻印进行一些数据的传递。slot-scope返回的是一个数据集合,里面有调用者的自定义属性的key:value集合

<div id="app"><my-compl><template slot-scope="a">{{a}}<!--输出结果为:{ "say": "你好", "n": "我是cy" }--></template></my-compl>
</div>
<script>Vue.component('my-compl', {template: '<div><slot say="你好" n="我是cy"></slot></div>'});new Vue({el: '#app'})
</script>

6.案例:匹配item格式

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>插槽作用域</title><script src="../js/vue.js"></script><style>.current {color: orange;}</style>
</head>
<body>
<div id="app"><!--父组件(在DOM中使用自定义组件)--><!--1.引入flist数组集合--><fruit :list="flist"><!--5.获得调用者的属性集合--><template slot-scope="slotprops"><!--6.内部判断插槽作用域内部元素的id值,并匹配样式--><strong v-if="slotprops.info.id==2" class="current">{{slotprops.info.name}}</strong><span v-else>{{slotprops.info.name}}</span></template></fruit>
</div>
<!--组件部分-->
<template id="temp"><div><ul><!--3.通过循环遍历数组集合--><li :key="item.id" v-for="item in list"><!--4.将item(集合数据)绑定到插槽作用域里面去,格式为info:{id:'',name:''}--><slot :info="item"></slot></li></ul></div>
</template>
<script>Vue.component('fruit', {template: '#temp',props: ['list'],//2.将父组件的属性list传到子组件});new Vue({el: "#app",data: {//数据集合flist: [{id: 1, name: 'apple'},{id: 2, name: 'banana'},{id: 3, name: 'orange'},]}})
</script>
</body>
</html>

7.具名插槽结合使用

<div id="app"><!--1.获得vue里面的data--><my-comp :items="items"><!--4.引用具名插槽,填入数据--><template slot="item" scope="pro"><li>{{pro.text}}--{{pro}}<!--输出结果:示例1--{ "text": "示例1" }示例2--{ "text": "示例2" }示例3--{ "text": "示例3" }--></li></template></my-comp>
</div>
<template id="temp"><div><ul><!--3.得到数据列表items,并遍历items,绑定text属性--><slot name="item" v-for="item in items" :text="item.text"></slot></ul></div>
</template>
<script>Vue.component('my-comp', {template: '#temp',//2.数据传递,传递到子组件props: ['items']});new Vue({el: '#app',data: {items: [{text: '示例1'},{text: '示例2'},{text: '示例3'},],}})
</script>

8.具名插槽默认内容

<div id="app"><my-comp><!--为空的时候不执行slot内的--></my-comp><my-comp><!--有调用的时候启用slot,slot内部的则不启用--><template slot-scope="myslot"><span>{{myslot.datail.join("-")}}</span></template></my-comp>
</div>
<template id="temp"><div><slot :datail="books"><!--slot被调用的时候,这里面的默认内容就不会显示--><ul><li v-for="item in books">{{item}}</li></ul></slot></div>
</template>
<script>Vue.component('my-comp', {template: '#temp',data() {return {books: ['唐诗三百首','宋词','元曲','小说',]}}});new Vue({el: '#app',data: {books: '父组件数据'}})
</script>

Vue学习笔记02——Vue路由

Vue学习笔记01——Vue开发基础相关推荐

  1. Vue学习笔记02——Vue路由

    Vue学习笔记01--Vue开发基础 一.初识路由 1.路由的作用 Vue的路由是前端路由,可以让组件之间互相切换. 2.vue-router.js文件 Vue的路由使用需要引入vue-router. ...

  2. XML学习笔记01【xml_基础、xml_约束】

    Java后端 学习路线 笔记汇总表[黑马程序员] XML学习笔记01[xml_基础.xml_约束][day01] XML学习笔记02[xml_解析][day01] 目录 01 xml_基础 今日内容 ...

  3. Vue学习笔记01:准备开发与调试环境

    文章目录 一.安装Vue.js (一)使用独立版本 1.开发版本 2.生产版本 3.案例演示 (二)使用CDN方式 1.采用 Staticfile CDN 2.案例演示 (三)使用NPM方式 1.安装 ...

  4. vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍

    这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...

  5. 阿瑶的vue学习笔记(1)Vue核心

    1. Vue核心 1.1. Vue简介 1.1.1. 官网 英文官网 中文官网 1.1.2. 介绍与描述 动态构建用户界面的渐进式JavaScript框架 作者:尤雨溪 1.1.3. Vue的特点 遵 ...

  6. Vue学习笔记(九) Vue CLI

    1.简介 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,它包括三个独立的部分: CLI:一个全局安装的 npm 包,提供在终端里使用的命令 CLI 服务:一个局部安装在使用了 @v ...

  7. 【狂神说Java】Vue学习笔记01:前端知识体系

    本文根据B站[狂神说Java]vue系列视频整理,如需观看视频,请点击链接跳转 [狂神说Java]Vue视频 2.前端知识体系 想要成为真正的"互联网Java全栈工程师"还有很长的 ...

  8. vue学习笔记(2)基础语法

    一.vue 实例 var vm = new Vue({// 选项 }) 二.基础语法 官方文档写的挺好 链接: vue官网.

  9. Vue学习笔记:Vue中封装自定义步骤条 实现上下一步

    Vue中封装自定义步骤条 实现上下一步 效果图: 如上图:在VUE中实现效果,VUE+Element,ant都有封装好的UI,直接引用就好了: 这里,觉得样式不符合UI设计,所以自定义封装了一个步骤条 ...

最新文章

  1. c#正则表达式使用详解
  2. wince: Post-deploy error 0x00000001 returned after calling......解决方法
  3. python处理视频动漫化_用Python实现抖音上的“人像动漫化”特效,原来这么简单...
  4. Flex/Flash Builder里实用但被忽略的编译参数
  5. vs2015 ctrl 单击 转到定义
  6. 【考前必知】软考考前注意事项
  7. windows下cmd命令提示符下让程序后台运行命令
  8. javascript两行代码按指定格式输出日期时间
  9. 总有几位老师让你一生感激不尽----老师侯捷
  10. 【旧文章搬运】暴力的查进程方法
  11. 计算机之父童年的故事ppt,24计算机之父童年的故事
  12. 面试常见的26个问题
  13. 智能硬件可能成为网络安全事件新的“爆发点”
  14. 基于SpringBoot监控Java项目,暴漏springboot内置端点
  15. 短信发送接口(短信宝)
  16. 选择时间检定仪应该注意这11点
  17. 震惊,这款控件的速度比姆巴佩还快
  18. 可编程并行通信接口8255A
  19. Python 动态加载并下载梨视频短视频
  20. UnRaid利用iGVT-g插件实现Nas宿主机、虚拟机同时使用intel核显输出或硬解(硬件加速)功能

热门文章

  1. 874.walking-robot-simulation
  2. mac 思科 链路聚合_cisco交换机上的链路聚合
  3. LightOJ 1234 Harmonic Number(调和级数+欧拉常数)
  4. 如何成为有效学习的高手
  5. 10_10_闪迪服务器芯片,闪迪至尊超极速480GB SSD拆解
  6. 软考高级系统架构设计师:数据持久层
  7. 【算法】_013_矩阵乘法
  8. 启动磁盘不能被分区或恢复成单个分区-解决了
  9. Materials Studio构建密勒晶面
  10. vue上下轮播组件简单实现