前言:关于Vue框架里面的打包及打包后生成的文件路径问题
1、打包(npm run build)的配置文件:Vue框架下的config目录下的index.js文件
2、名词注释:
2.1、index: path.resolve(__dirname, '../../templates/index.html'), # 打包后index.html文件存在的路径
2.2、assetsRoot: path.resolve(__dirname, '../../static'), # 打包后static目录存在的根路径(static目录必须先创建)
2.3、assetsSubDirectory: 'dist', # 打包js,css,img等目录存放的根路径(dist目录不需要创建,在打包的过程中会自动创建)
2.4、assetsPublicPath: 'static/', # 打包后生成的index.html文件里面指定访问静态文件的路径
一、VUE入门介绍
一、什么是vue
定义:一个构建数据驱动的web界面的渐进式框架
二、vue优点:
1.以数据驱动,不直接操作DOM,效率高
2.单页面应用,减少请求页面次数,速度快
3.数据的双向绑定,更新快
4.虚拟DOM开发操作数据,数据更新虚拟DOM,虚拟DOM渲染真实DOM
三、vue入门
实例 == 组件
el : 挂载点,一般采用id,vue控制html页面结构的连接点
-- #app
data: 数据,微页面变量提供数据的,一般变量都需要初始化
-- {{}}: 差值表达式,可以包含变量以及表达式
mothods: 方法,为页面提供逻辑的实现体
-- v-on: 事件
computed: 计算,一个变量依赖于多个变量
-- 变量名: function {return 变量的逻辑值}
watch:监听,多个变量依赖于一个变量
-- 变量名: function () {多个变量依赖于此变量的逻辑代码块}
delimiters:修改差值表达式的默认符号
-- delimiters: ['${', '}'] 左侧是"${" ,右侧是"}" 作为分隔符
变量的取值:
var app = new Vue({
el : "#app",
data: {
msg: "message",
},
})
1.console.log(app.msg) // 直接获取msg的值
2.console.log(app.$data.msg) // Vue变量取值(以$开头)
生命周期钩子:
1.表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
2.钩子函数:满足特点条件被回调的方法
3.生命周期钩子的写法:1.先拿到需求 == > 2.确定选取钩子函数 ==> 3.解决需求的逻辑代码块
二、VUE实例方法的使用
2.1、vue实例之v-bind ( v-bind指令绑定的是属性(html标签的全局属性),绑定属性后,属性的值可以由变量来控制) (详细用法见--4.1)
<body>
<div id="app">
<p title="PPPP">AAA</p> <!--这个title是html 标签全局变量标签的全局属性title-->
<!--v-bind属于vue语法:vue指令-->
<p v-bind:title="title">TITLE</p> <!--这个title是vue的一个变量,变量名可以随意组合-->
<!-- vue的变量一般需要进行初始化(赋初值)-->
<!-- "title"这个变量对应的值就是Vue里面title的值,可以通过在页面F12 -> Element 看到 "title"值已经被替换。-->
</div>
<div id="main">
<p v-bind:title="my_title">MY_TITLE</p>
</div>
</body>
<script src="vue-2.5.17.js"></script> <!--在页面中引入vue-->
<script type="text/javascript"> // 拥有vue环境后可以写vue支持的语法逻辑
// new Vue就相当于创建一个vue实例,然后将一个vue实例挂载到页面的一个页面结构
new Vue({
// 将实例与页面结构进行关联,尽量(只允许)用id进行绑定(将唯一的对象与页面唯一的结构进行一一绑定)
// 该实例只操作关联的页面而结构(包含子结构)
el:"#app", // el:固定写法
data:{
title: "测试1",
}
});
// 创建vue实例,然后将一个vue实例挂载到页面的一个页面结构
new Vue({
// 挂载点
el:"#main",
data:{
my_title: "测试2",
}
});
</script>
2.2、vue实例之data (数据,为页面变量提供数据的,一般变量都需要初始化) 及插值表达式
<body>
<div id="app">
<!--插值表达式-->
{{msg}}
{{num}}
{{1 + 2 + 3 * 4}} <!--插值表达式中可以进行运算-->
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
var app = new Vue({
el:"#app",
// data:数据
// 为挂载点内部的vue变量提供值
data:{
msg: "hello world!",
num: 8848,
}
})
</script>
<!--实例对象使用成员属性与方法-->
<script type="text/javascript">
// 普通js代码块,获取msg,num变量的值
// 1.首先接收vue实例
console.log(app); // 拿到的值:Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
// 2.获取app内的值
console.log(app._data); // 打印函数app下的data信息,拿到的值:{__ob__: Observer}
console.log(app._data.msg); // 打印函数app下的data内的msg,拿到的值:hello world!
// 3.直接获取app内的值的方式
console.log(app.msg); // 拿到的值:hello world!
console.log(app.num); // 拿到的值:8848
</script>
2.3、vue实例之methods--为挂载点内部提供方法的实现体
<body>
<div id="app">
<!--v-on:指令,操作事件的(click:点击事件就会得到一个响应值)-->
<p class="box" v-on:click="abcClick">{{abc}}</p> <!-- {{abc}}:插值表达式,对应的值为"这是ABC" -->
<p class="box" v-on:click="defClick">{{def}}</p>
<p class="box" v-on:mouseover="action">8848</p>
<!-- mouseover:鼠标变量(鼠标触碰之后会有返回值)-->
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
abc:"这是ABC",
def:"这是DEF",
},
// 为挂载点内部提供方法的实现体
methods:{
abcClick (ev) {
console.log(ev);
console.log("abc is click");
},
defClick (ev) {
console.log(ev);
console.log("def is click");
}
,
action (){
console.log("被触碰");
}
}
})
</script>
实现效果:
2.4、vue实例之comptuted -- 如果一个变量的值依赖于多个变量,那么采用computed
<body>
<div id="app">
<div>
<!-- v-model vue进行数据双向绑定的指令 -->
<label for="xing">姓:</label><input type="text" name="usr" v-model="first_name">
</div>
<div>
<label for="ming">名:</label><input type="text" name="usr" v-model="last_name">
</div>
<div>
<div>姓名:{{first_name + " " + last_name}}</div> <!--通过差值表达式实现-->
<div>姓名:{{full_name}}</div> <!--通过computed实现-->
<div>姓名:{{full_name_abc()}}</div> <!--通过methodes实现(将methods的方法直接加括号执行)-->
</div>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
first_name: "",
last_name: "",
},
// 如果一个变量的值依赖于多个变量,那么采用computed
computed:{
full_name () {
// full_name 对first_name和last_name两个变量进行监听,两个值只要有一个变化,full_name就会随之变化,并且可以实时渲染到页面
return this.first_name + " " + this.last_name;
}
},
// 通过methods的方式实现:
methods:{
full_name_abc () {
return this.first_name + " " + this.last_name;
}
}
})
</script>
实现效果:
2.5、vue实例之watch(监听器) -- 多个变量依赖于一个变量,对该变量进行监听,多个变量的值随着该变量值的变化而变化
<body>
<div id="app">
<div>
<!-- v-model vue进行数据双向绑定的指令 -->
<label >姓名:</label>
<input type="text" v-model="full_name">
</div>
<p>姓:{{ first_name }}</p>
<p>名:{{ last_name }}</p>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
// 多个变量依赖于一个变量,对该变量进行监听,多个变量的值随着该变量值的变化而变化
new Vue({
el: "#app",
data:{
full_name: "",
first_name: "",
last_name: "",
},
// 监听full_name变量(只要变量"full_name"的值变化,那么"first_name"和"last_name"的值就跟着变化),通过full_name具体修改first_name和last_name
watch: {
full_name () {
// 方法一:
var Full_name = this.full_name;
this.first_name = Full_name.split(" ")[0];
this.last_name = Full_name.split(" ")[1];
// 方法二:
// this.first_name = this.full_name.split(" ")[0];
// this.last_name = this.full_name.split(" ")[1];
}
}
})
</script>
2.6、vue实例之delimiters(分隔符) -- 修改差值表达式的默认符号 (本来插值表达式的符号为"{{ msg }}",修改之后就变成了"${ msg }",此时再使用符号"{{ msg }}"就不能被解析了)
<body>
<dev id="app">
${ msg }
</dev>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
msg: "message",
},
// 修改差值表达式的默认符号(本来插值表达式的符号为"{{ msg }}",修改之后就变成了"${ msg }",此时再使用符号"{{ msg }}"就不能被解析了)
delimiters: ['${', '}'] // 插值表达式的左侧为:"${" ,插值表达式的右侧为"}"
})
</script>
2.7、vue实例之 -- 生命周期钩子
一、什么是生命周期钩子:
1.1、表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
1.2、钩子函数:满足特点条件被回调的方法
二、生命周期钩子的写法:
1.先拿到需求
2.确定选取钩子函数
3.解决需求的逻辑代码块
三、下图展示了实例的生命周期
四、代码实现
<body>
<div id="app">
{{ msg }}
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
msg : "message"
},
// 一、什么是生命周期钩子:
// 表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
// 钩子函数:满足特点条件被回调的方法
// 二、生命周期钩子的写法:1.先拿到需求 == > 2.确定选取钩子函数 ==> 3.解决需求的逻辑代码块
beforeCreate () {
// 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
console.log("实例刚刚创建!");
console.log(this.msg); // 这里无获取值:undefined
},
created (){
// 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
console.log("实例创建成功!");
console.log(this.msg); // 得到:message
},
})
</script>
代码实现效果:
三、VUE实例之 -- 各种指令
3.1、vue实例 -- 文本类指令
1. v-text 相当于 {{}} (插值表达式) JS代码:<p v-text="msg"></p>
2. v-html <p v-text="msg"></p> 显示效果:<b>123</b> 加粗的123
3. v-once <p v-once> {{ msg }} </p> 只能被赋值一次
4. v-model <input type="text" v-model="value"> v-model控制的是表单元素的value值
<body>
<div id="app">
<!--html全局属性语法,全局属性名=="属性值"-->
<p v-bind:title="title" a="a" b="b">文本类指令P</p> <!--v-bind:title="title": 是可以被Vue解析的全局属性-->
<!--v-model也是对文本操作的指令,操作的是表单元素的value文本-->
<input type="text" v-model="msg">
<!--采用文本指令后,页面标签的内容由vue实例控制,原来用于表示标签的文本均会被替换-->
<p>{{msg}}</p>
<p v-text="msg"></p> <!-- v-text:纯文本格式,由vue实例控制具体的内容(原内容会被msg替换)-->
<p v-html="text"></p> <!-- v-html:可以识别html语法,并显示语法渲染之后的值-->
<p v-once> {{ msg }} </p> <!-- v-once:只获取一个初值(之后在有修改不会改动)-->
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
// 指令:出现在html标签中可以被vue解析处理的全局属性
new Vue({
el : "#app",
data: {
title: "这是title",
msg: "message",
text: "<b>文本</b>", // 使用"v-html"时,html语法例子
}
})
</script>
实现效果:
3.2、vue实例 -- v-cloak (避免页面闪烁)
不需要在vue实例里面做操作,只需要在css里面通过属性选择器把"v-cloak"的值设置为"display: none;"
<head>
<meta charset="UTF-8">
<title>避免页面闪烁</title>
<style type="text/css"> /* 通过css控制全局属性"v-cloak"的值 */
[v-cloak] { /* 在CSS里面定义全局属性"v-cloak"的值为:"display: none;" */
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
{{ msg }}
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
msg: "message",
},
})
</script>
四、vue重要指令 -- v-bind指令可以简写为 ":" 冒号
4.1、vue实例之v-bind ( v-bind指令绑定的是属性(html标签的全局属性),绑定属性后,属性的值可以由变量来控制。)
<body>
<div id="app">
<p v-bind:abc="msg"></p>
<!--关于v-bind的定义-->
<!--"v-bind:"固定写法(绑定一个属性),"abc"全局属性,"="赋值,"msg"具体的值(可以为某个变量名)-->
<!--绑定后的属性的值可以由变量控制-->
<!--如果一个属性的值是变量,那么该属性就需要通过"v-bind"去绑定-->
<!-- 绑定后,操作单一变量 -->
<p v-bind:title="t1">p1p1p1p1p1p1p1p1p1p1</p>
<!-- 绑定后,操作普通字符串(里面可以放普通的字符串) -->
<p v-bind:title="'t2'">p2p2p2p2p22p2p2pp2p2</p>
<!-- 多类名,操作单一变量 -->
<p v-bind:class="t3">p3p3p3p3pp3p3p3p3p3p3</p>
<p v-bind:class="[t4,tt4]">p4p4p4p4p4p4pp4p4p4p44p</p>
<!-- 绑定class的"{}"语法,{key: value} 其中"key"就是实际的类名,value就是该类名的显隐(true就是生效[有值(字符串或变量[变量不为空])就表示true],false就是不生效[为空值时]) -->
<p v-bind:class="{abc: false}">p5p5p5p5p5p5p5p5p5p5p5p5</p>
<!-- 例子: 通过设置"value"的值为空false(或不为空true)来改变前端页面的值 -->
<p v-bind:class="{abc: t5 }" v-on:click="fn">p6p6p6p6p6p6p6p6p6p6p6p6p6</p>
<!-- class的[] {} 结合使用 -->
<p v-bind:class="[{p7: t7}, {pp7: tt7}]">p7pp7p7p7p7p7p7p77p77p77pp77p</p>
<!-- v-bind:指令可以简写为 ":" -->
<p :class="'aa'">简写</p>
<!-- 操作style,style一般都是多条样式(with,height,backgroundColor) -->
<div :style="div_style"></div>
<div :style="{ width: '200px', height: '200px', backgroundColor: 'red' }"></div>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
msg: "message",
t1: "p1的title",
t3: "p pp",
t4: "t4",
tt4: "tt4",
t5: true,
t7: true,
tt7: false,
div_style: {
width: "200px",
height: "50px",
backgroundColor: "blue",
}
},
methods: {
fn () {
this.t5 =! this.t5; // 点击一次"等于",点击一次"不等于"
}
}
})
</script>
一个个注释:
1)、v-bind 自定义全局属性例子:<p v-bind:abc="msg"></p>
"v-bind:"固定写法(绑定一个属性),"abc"全局属性,"="赋值,"msg"具体的值(可以为某个变量名)
绑定后的属性的值可以由变量控制
如果一个属性的值是变量,那么该属性就需要通过"v-bind"去绑定
实现效果:
2)、v-bind 操作 title 属性 -- 操作单一变量
<p v-bind:title="t1">p1p1p1p1p1p1p1p1p1p1</p>
实现效果:
2.1)、v-bind 操作 title 属性 -- 操作普通字符串(里面可以放普通的字符串)
<p v-bind:title="'t2'">p2p2p2p2p22p2p2pp2p2</p>
实现效果:
3、v-bind 操作 class 属性 -- 操作单一变量
<p v-bind:class="t3">p3p3p3p3pp3p3p3p3p3p3</p>
实现效果:
3.1、v-bind 操作 class 属性 -- []号内操作变量
<p v-bind:class="[t4,tt4]">p4p4p4p4p4p4pp4p4p4p44p</p>
实现效果:
4、v-bind 操作 class 属性 -- "{}"语法
v-bind操作class属性的"{}"语法,{key: value} 其中"key"就是实际的类名,value就是该类名的显隐(true就是生效[有值(字符串或变量[变量不为空])就表示true],false就是不生效[为空值时])
<p v-bind:class="{abc: false}">p5p5p5p5p5p5p5p5p5p5p5p5</p>
<!-- 例子: 通过设置"value"的值为空false(或不为空true)来改变前端页面的值 -->
<p v-bind:class="{abc: t5 }" v-on:click="fn">p6p6p6p6p6p6p6p6p6p6p6p6p6</p>
实现效果:
5、v-bind 操作 class 属性 -- [] {} 结合使用
<p v-bind:class="[{p7: t7}, {pp7: tt7}]">p7pp7p7p7p7p7p7p77p77p77pp77p</p>
实现效果:
6、v-bind指令可以简写为 ":" 冒号
<p :class="'aa'">简写</p>
实现效果:
7、v-bind操作 style 属性 -- style一般都是多条样式(with,height,backgroundColor)
<div :style="div_style"></div>
<div :style="{ width: '200px', height: '200px', backgroundColor: 'red' }"></div>
实现效果:
4.2、v-on指令 -- 操作事件的指令
指令说明: v-on:click ,简写:@click ,v-on 绑定的是事件,操作的是事件对应的方法名
<body>
<div id="app">
<!--指令说明: v-on:click ,简写:@:click ,v-on 绑定的是事件,操作的是事件对应的方法名-->
<!-- 直接绑定方法名,不会携带自定义参数,但回调时能取到事件变量ev -->
<p @click="fn2"></p>
<!-- 带()的方法绑定,只传自定义参数,回调时只能取到自定义参数,事件参数ev丢失 -->
<p @click="fn3(10)"></p>
<!-- 带()的方法绑定,传入自定义参数的同时,显示传入事件$event,那么在回调时能取到自定义参数,并且能取到事件变量ev -->
<p @click="fn4($event,10,20)"></p>
<!-- 带()的方法绑定,传参顺序改变,回调时不受影响 -->
<p @click="fn5(10,$event,20)"></p>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
methods: {
fn2:function (ev) {
console.log(ev);
},
fn3:function (ev) {
console.log(ev);
},
fn4:function (ev,n1,n2) {
console.log(ev);
console.log(n1);
console.log(n2);
},
fn5:function (n1,ev,n2) {
console.log(n1);
console.log(ev);
console.log(n2);
},
}
})
</script>
一个个注释:
1)、直接绑定方法名,不会携带自定义参数,但回调时能取到事件变量ev
<p @click="fn2"></p>
实现效果:
2)、带()的方法绑定,只传自定义参数,回调时只能取到自定义参数,事件参数ev丢失
<p @click="fn3(10)"></p>
实现效果:
3)、带()的方法绑定,传入自定义参数的同时,显示传入事件$event,那么在回调时能取到自定义参数,并且能取到事件变量ev
<p @click="fn4($event,10,20)"></p>
实现效果:
4)、带()的方法绑定,传参顺序改变,回调时不受影响
<p @click="fn5(10,$event,20)"></p>
实现效果:
4.3、v-model指令 -- v-model指令操作的是表单元素的value值
<body>
<div id="app">
<form action="">
<!-- 数据的双向绑定:修改这个变量的值时,其他引用了这个变量的值也会跟着修改 -->
<!-- v-model绑定的是value,如果设置name="usr",那么key==usr,value=="value1" -->
<input type="text" v-model="value1" name="usr1">
<!-- 单个复选框(根据变量"value2"的值为true|false决定单选框是否选中) -->
<input type="checkbox" v-model="value2" name="usr2">
<!-- 根据"value3"的值为自定义"on"或"off"决定单选框是否选中 -->
<input type="checkbox" v-model="value3" true-value="on" false-value="off" name="usr3">
<!-- 多个复选框:多个复选框的v-model绑定一个变量,该变量为数组类型数据,存放的是复选框的value值(value值必须明确) -->
<!-- 出现在数组中的value值对应的复选框默认为选中状态 -->
<div>
篮球<input type="checkbox" value="lq" v-model="value4" name="usr4">
足球<input type="checkbox" value="zq" v-model="value4" name="usr4">
</div>
<!-- 多个单选框的v-model绑定一个变量 -->
<!-- 变量值为多个单选框中的一个value值,则该单选框为默认选中状态 -->
<div>
男:<input type="radio" value="男" v-model="value5" name="sex">
女:<input type="radio" value="女" v-model="value5" name="sex">
</div>
<button type="submit">提交</button>
</form>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
value1: "",
value2: false,
value3: "on",
value4: ['lq','zq'], // 通过数组进行赋值
value5: "男", // value的值控制的是默认选中"男"
},
})
</script>
一个个注释:
1)、数据的双向绑定 -- 修改这个变量的值时,其他引用了这个变量的值也会跟着修改
<!-- v-model绑定的是value,如果设置name="usr",那么key==usr,value=="value1" -->
<input type="text" v-model="value1" name="usr1">
实现效果:
2)、单个复选框 -- 根据变量"value2"的值为true|false决定单选框是否选中
<!-- 单个复选框(根据变量"value2"的值为true|false决定单选框是否选中) -->
<input type="checkbox" v-model="value2" name="usr2">
实现效果:
2.1)、单个复选框 -- 根据"value3"的值为自定义"on"或"off"决定单选框是否选中
<!-- 根据"value3"的值为自定义"on"或"off"决定单选框是否选中 -->
<input type="checkbox" v-model="value3" true-value="on" false-value="off" name="usr3">
实现效果:
3)、多个复选框 -- 多个复选框的v-model绑定一个变量,该变量为数组类型数据,存放的是复选框的value值(value值必须明确)
<!-- 出现在数组中的value值对应的复选框默认为选中状态 -->
<div>
篮球<input type="checkbox" value="lq" v-model="value4" name="usr4">
足球<input type="checkbox" value="zq" v-model="value4" name="usr4">
</div>
实现效果:
4)、多个单选框的v-model绑定一个变量 -- 变量值为多个单选框中的一个value值,则该单选框为默认选中状态
<!-- 变量值为多个单选框中的一个value值,则该单选框为默认选中状态 -->
<div>
男:<input type="radio" value="男" v-model="value5" name="sex">
女:<input type="radio" value="女" v-model="value5" name="sex">
</div>
实现效果:
4.4、条件渲染相关指令 v-show,v-if,v-else-if,v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>条件渲染相关指令</title>
<script src="vue-2.5.17.js"></script>
<style type="text/css">
.box {
width: 200px;
height: 200px;
}
.r {background-color: red;}
.o {background-color: orange;}
</style>
<style type="text/css">
ul {
margin: 0;
padding: 0;
list-style: none;
}
.wrap, .main {
width: 500px;
height: 240px;
}
li {
float: left;
background-color: #666;
margin-right: 20px;
}
ul:after {
content: "";
display: block;
clear: both;
}
.red { background-color: red; }
.green { background-color: green; }
.blue { background-color: blue; }
</style>
</head>
<body>
<div id="app">
<button @click="toggle">显隐切换</button>
<!-- v-if -->
<div class="box r" v-if="isShow"></div>
<!-- v-show -->
<div class="box o" v-show="isShow"></div>
<!-- 1.条件渲染的值为true|false -->
<!-- 2.true代表:标签显示方式渲染 -->
<!-- 3.false代表:其中v-if表示不渲染到页面,v-show以display:none渲染到页面,但也不会显示内容 -->
<!-- 使用:v-if v-else-if v-else 方法实现 -->
<ul>
<li @mouseover="changeWrap(0)">red</li>
<li @mouseover="changeWrap(1)">green</li>
<li @mouseover="changeWrap(2)">blue</li>
</ul>
<!-- red页面逻辑结构 -->
<div class="wrap red" v-if="tag == 0" key="0">...</div>
<!-- green页面逻辑结构 -->
<div class="wrap green" v-else-if="tag == 1" key="1">...</div>
<!-- blue页面逻辑结构 -->
<div class="wrap blue" v-else key="2">...</div>
<!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 -->
<!-- 通过key全局属性操作后,渲染过的分支会建立key的缓存,提高下一次渲染速度 -->
<!-- 使用:v-show方法实现 -->
<ul>
<li @mouseover="changeMain(0)">red</li>
<li @mouseover="changeMain(1)">green</li>
<li @mouseover="changeMain(2)">blue</li>
</ul>
<!-- red页面逻辑结构 -->
<div class="wrap red" v-show="whoShow(0)">...</div>
<!-- green页面逻辑结构 -->
<div class="wrap green" v-show="whoShow(1)">...</div>
<!-- blue页面逻辑结构 -->
<div class="wrap blue" v-show="whoShow(2)">...</div>
</div>
</body>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
isShow: false,
tag: 0,
flag:0,
},
methods: {
toggle () {
this.isShow = !this.isShow;
},
changeWrap (num) {
this.tag = num;
},
changeMain (num) {
this.flag = num;
},
whoShow (num) {
return this.flag == num;
}
}
})
</script>
</html>
1.v-show
<div v-show="isShow"></div>
// 变量isShow值为true(显示:display:block) | false (隐藏,display:none)
2.v-if
<div v-if="isShow"></div>
// 变量isShow值为true(显示:渲染到页面) | false (隐藏,不渲染到页面)
3.v-if ,v-else-if ,v-else
<div v-if="tag == 0" key = "0"></div>
<div v-else-if="tag == 1" key = "1"></div>
<div v-else="tag == 2" key = "2"></div>
// v-else的逻辑可以省略
// 变量tag取值在0~2之间,可以决定具体渲染哪个div
// 全局属性key是为渲染过的分支建立缓存,加快该分支下一次被渲染的速度,key的值具有唯一性。
4.5、列表渲染的相关指令 v-for
<body>
<div id="app">
<h1>{{msg}}</h1>
<!-- v-for="item in items" -->
<!-- 便利的对象:数组[] 对象(字典) -->
<ul>
<li>{{msg}}</li>
<li>{{list[0]}}</li>
<li>{{list[1]}}</li>
</ul>
<ul>
<!-- 字典取值 -->
<li>{{dic['name']}}</li>
<li>{{dic.age}}</li>
<li>{{dic.gender}}</li>
</ul>
<ul>
<!-- v-for循环一个列表 -->
<li v-for="num in list">{{num}}</li> <!-- num 就是遍历的元素值[1,2,3,4,5] -->
</ul>
<ul>
<!-- 一般列表渲染需要建立缓存 -->
<!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind指令处理(key是vue的全局属性,并且key存放的是变量值,所以需要用v-bind) -->
<!-- v-for循环数组[]时,接收2个值,第一个为变量名,第二个为便利的对象 -->
<li v-for="(n,i) in list" :key="i">value:{{n}} | index:{{i}}</li> <!-- n表示值,i表示索引 -->
</ul>
<ul>
<!-- v-for循环一个字典 -->
<!-- v-for循环字典时,1.先取(字典)的value 2.然后取(字典)的key 3.最后取(字典)的索引 -->
<li v-for="v, k, i in dic" :key="i">value:{{v}} | key:{{k}} | index:{{i}}</li>
</ul>
<!-- for循环内嵌套for循环 -->
<div v-for="(person,index) in persons" :key="index" style="height: 21px">
<div v-for="(v,k) in person" :key="k" style="float: left;"> {{k}} : {{v}} </div>
</div>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue ({
el: "#app",
data: {
msg: "列表渲染",
list : [1,2,3,4,5],
dic:{
name: "sudada",
age: 18,
gender: "男",
},
persons: [
{name: "sudada", age:28},
{name: "wudapao", age:27},
{name: "liuchacha", age:25},
]
}
})
</script>
1.v-for 循环列表 []
<div id="app">
<ul>
<!-- 一般列表渲染(循环)需要建立缓存 -->
<!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind指令处理(key是vue的全局属性,并且key存放的是变量值,所以需要用v-bind) -->
<!-- v-for循环数组[]时,接收2个值,第一个为变量名,第二个为便利的对象 -->
<li v-for="(n,i) in list" :key="i">value:{{n}} | index:{{i}}</li> <!-- n表示值,i表示索引 -->
</ul>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue ({
el: "#app",
data: {
list : [1,2,3,4,5],
}
})
</script>
效果样式:
2.v-for 循环字典 {}
<body>
<div id="app">
<ul>
<!-- v-for循环一个字典 -->
<!-- v-for循环字典时,1.先取(字典)的value 2.然后取(字典)的key 3.最后取(字典)的索引index -->
<li v-for="v, k, i in dic" :key="i"> value:{{v}} | key:{{k}} | index:{{i}}</li>
</ul>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue ({
el: "#app",
data: {
dic:{
name: "sudada",
age: 18,
gender: "男",
}
}
})
</script>
</html>
效果样式:
3.v-for 循环嵌套循环
<body>
<div id="app">
<!-- for循环内嵌套for循环 -->
<!-- 先便利一遍persons,拿到变量person -->
<div v-for="(person,index) in persons" :key="index" style="height: 21px">
<!-- 然后便利person,分别取出key和value -->
<div v-for="(v,k) in person" :key="k" style="float: left;"> {{k}} : {{v}}
<!-- -->
</div>
</div>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue ({
el: "#app",
data: {
persons: [
{ name: "sudada", age:28 },
{ name: "wudapao", age:27 },
{ name: "liuchacha", age:25 },
]
}
})
</script>
</html>
效果样式:
4.6、todolist案例
<body>
<div id="app">
<div>
<input type="text" v-model="val">
<button type="button" @click="submitMsg">提交</button>
</div>
<ul>
<li v-for="(v,i) in list" :key="i" @click="removeMsg(i)"> {{v}} </li>
</ul>
{{list}}
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
val: "",
data: {
list: [],
},
methods: {
submitMsg () {
// 往list中添加input框中的数据
this.list.push(this.val);
this.val= "";
},
removeMsg (index) {
this.list.splice(index,1) // splice() 方法用于添加或删除数组中的元素,例子:splice(2,1)表示对第二个索引进行删除,删除一个值,splice(2,0)表示删除0个值,返回原数组
}
}
})
</script>
实现效果1:输入内容,然后点击提交,生成数据
实现效果2:点击具体的内容,删除对应的数据
五、组件相关
1.每一个组件都是一个vue实例
2.每个组件均具有自身的模板template,跟组件的模板就是挂载点
3.每个组件的模板只能拥有一个根标签
4.子组件的数据具有作用域,以达到组件的复用
5.1、根组件 -- 通过new Vue创建的实例就是根组件
1.通过new Vue创建的实例就是根组件(实例与组件一一对应,一个vue实例就是一个组件)
2.每个组件均拥有模板,template
3.模板:由""(双引号)包裹的html代码块,出现在组件的内部,赋值给组件的$template变量。
4.根组件如果不书写自身模板(template),那么模板就采用挂载点(el: "#app"),如果显示书写模板(template),就会替换挂载点(el: "#app"),但是根组件必须拥有挂载点(没有挂载点,那么模板无法替换)。
<body>
<p>app之上</p>
<div id="app">
<h1>{{msg}}</h1>
</div>
<p>app之下</p>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
// 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个vue实例就是一个组件)
// 每个组件均拥有模板,template
new Vue({ // 根组件的模板就是挂载点(挂载点是根组件独有的)
el: "#app",
data: {
msg: "根组件",
},
// 模板:由""(双引号)包裹的html代码块,出现在组件的内部,赋值给组件的$template变量。
// 根组件如果不书写自身模板(template),那么模板就采用挂载点(el: "#app"),如果显示书写模板(template),就会替换挂载点(el: "#app"),但是根组件必须拥有挂载点(没有挂载点,那么模板无法替换)。
template: "<div>显示模板</div>"
})
</script>
代码显示效果:
5.2、局部组件
1、局部组件的语法规则有哪些?
有自身模板(template),有data/methods/computed/watch等~~
2、为什么要用局部组件?
达到html+css+js代码块的复用
3、如何定义以及使用局部组件?
一个满足vue语法规则的对象(例子:var localTag)就是一个组件。
用一个变量名来接收这个组件,就是创建了一个局部组件(变量名就是局部组件的名称)。
通过组件名就可以使用该组件。
4、局部组件想要在父组件中使用时,必须要在父组件中进行注册(components)
5、局部组件 -- 数据data是采用方法返回值进行处理 data () {return {数据} } ,到达组件复用时,数据的私有化
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>局部组件</title>
<style type="text/css">
.sup {
width: 100px;
height: 100px;
background-color: orange;
}
.sub {
width: 100px;
height: 100px;
background-color: red;
border-radius: 50%;
}
</style>
</head>
<body>
<div id="app">
<!-- 组件的使用及复用如下: -->
<local-tag></local-tag>
<!--例子2:组件复用-->
<btn-tag></btn-tag>
<btn-tag></btn-tag>
<!-- heml组件命名中,提倡"-"的链接语法(2个及以上单词拼接时使用"-") -->
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
var localTag = {
template: "<div class='sup'><div class='sub'></div></div>"
}
// 例子2:组件复用
var btnTag = {
template: "<button @click='btnAction'>点击了{{num}}下</button>",
// data需要绑定方法,数据通过方法返回值进行处理 data () {return {数据} } ,到达组件复用时,数据的私有化
data: function () {
return {
num: 0
}
},
methods: {
btnAction: function () {
this.num++
}
}
}
// 根组件
new Vue({
el: "#app",
// 局部组件想要在父组件中使用时,必须要在父组件中进行注册(components)
components : {
"local-tag": localTag, // 注册子组件 -- 方式1
// localTag, // 注册子组件 -- 方式2(ES6对象语法,当key value写法相同时,可以省略value)
// 例子2:组件复用
"btn-tag": btnTag,
},
})
</script>
</html>
代码实现效果:
5.3、全局组件 -- 全局组件的用法和局部组件基本一样,特殊的地方有2点,如下:
1、全局组件用Vue.component("组件名", {})创建
2、全局组件赋属于Vue实例,不需要注册就能够使用
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<global-tag></global-tag>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
// 全局组件用Vue.component("组件名", {})创建
// 全局组件赋属于Vue实例,不需要注册就能够使用
Vue.component("global-tag", {
template: "<button @click='btnClick'>{{num}}</button>>",
data () {
return {
num: 0,
}
},
methods: {
btnClick () {
this.num++
}
}
})
new Vue({
el: "#app",
})
</script>
</html>
5.4、父、子组件的相互传递
1、父组件向子组件传递数据时,使用属性绑定的方式
父组件与子组件建立联系的关键点:
1).数组由父组件提供
2).在父级模板(挂载点)中出现的子组件名(local-tag)上,为其设置全局属性,属性值就是父级提供的数据变量
3).在子组件内部,通过props拿到标签中的全局属性名(用' '(单引号)括起来的数组)
4).在模板中直接用属性名来访问数据,在方法中通过this.属性名来访问数据
5).组件名拼接时使用"local_tag"(下划线)的方式
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>父子组件的相互传递</title>
</head>
<body>
<div id="app">
<local-tag :num="num" :sup_date="sup_date"></local-tag>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
// 父组件与子组件建立联系的关键点:
// 1.绑定属性进行数据传输
// 2.给在父组件中出现的子组件名定义标签的全局属性
// 3.全局属性的值赋值为父组件的数据变量
// 4.在子组件内部,通过props拿到标签中的全局属性名
//子组件
var localTag = {
props: ['num','sup_date'],
template: "<div @click='divAction'>{{num}}</div>",
methods: {
divAction () {
console.log(this.num)
console.log(this.sup_date)
}
}
}
// 数据属于父组件,子组件来接收使用数据
// 父组件
new Vue({
el: "#app",
components: {
"local-tag": localTag,
},
data: {
num : 10,
sup_date: [1,2,3,4,5]
}
})
</script>
</html>
2、子组件向父组件传递数据时,使用绑定事件的方式
1).数组由子组件提供
2).在子组件中,通过某个事件对外(this.$emit("事件名",...args))发送一个事件
3).在父组件的模板中,子组件 名上,为发送的事件绑定一个回调方法,该回调方法由父组件来完成实现体
<body>
<div id="app">
<global-tag @send_data="receive_data"></global-tag>
</div>
</body>
4).在实现体中就可以拿到回调参数
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>子组件传递给父组件</title>
</head>
<body>
<div id="app">
<global-tag @send_data="receive_data"></global-tag>
{{n}}
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
// 子传父:
// 1.通过发送事件的方式进行数据传输
// 2.数据由子组件提供,父组件通过事件的回调方法获取数据
// 3.发送数据的关键:$emit("事件名,...atgs")
// 全局组件(子组件)
Vue.component ("global-tag", {
template: "<div @click='divAction'>父组件</div>",
data () {
return {
num: 10,
arrList: [1,2,3,4,5]
}
},
methods: {
divAction () {
// 发送事件
// "send_data == 要发送的事件,this.num,this.arrList == 携带的参数"
this.$emit("send_data",this.num,this.arrList)
}
}
});
// 父组件
new Vue ({
el: "#app",
data: {
n: 0,
},
methods: {
receive_data (num,arrList) {
// num,arrList表示接收值变量的名称。
console.log("接收到的数据 ",num,arrList)
this.n = num;
}
}
})
</script>
</html>
实现效果:
5.5、组件式todolist
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>todolist案例</title>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="val">
<button type="button" @click="submitMsg">提交</button>
</div>
<ul>
<todo-list v-for="(v,i) in list" :key="i" :v="v" :i="i" @delete_action="delete_Action"></todo-list>
</ul>
</div>
</body>
<script src="vue-2.5.17.js"></script>
<script type="text/javascript">
Vue.component("todo-list", {
template: "<li @click='delete_action'><span>第{{i+1}}条: </span><span>{{v}}</span></li>",
props: ['v','i'],
methods: {
delete_action () {
this.$emit("delete_action",this.i)
}
}
})
new Vue({
el: "#app",
val: "",
data: {
list: [],
},
methods: {
submitMsg () {
// 往list中添加input框中的数据
if (this.val) {
this.list.push(this.val);
this.val = " ";
}
},
delete_Action (index) {
this.list.splice(index,1) // splice() 方法用于添加或删除数组中的元素,例子:splice(2,1)表示对第二个索引进行删除,删除一个值,splice(2,0)表示删除0个值,返回原数组
}
}
})
</script>
</html>
实现效果:点击数据时会删除索引对应的数据