Vue快速使用上手指南
一个最简单的vue入门demo
1.新建一个html网页,并且引入vue的js文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue单文件例子</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
</body>
</html>
- 创建要绑定的div
<div id="box">
</div>
- 初始化 vue,并且绑定到 box
<script type="text/javascript">
new Vue({
el:"#box"
})
</script>
测试vue是否 引入成功,我们通过vue的插值运算符的结果来 测试,Vue会自动帮你运算渲染成30.
<div id="box">
{{10+ 20}}
</div>
其他语法
{{10 > 20 ? 'aaa':'bbb'}}//等价于 if 10 > 20 return 'aaa' else return'bbb'
~注意: 如果 aaa 不加单引号,那么 就会被当作一个变量,所以需要加单引号.
Vue定义变量
<script type="text/javascript">
new Vue({
el:"#box"
var1:20,
var2:2,
var:'<br>mytext'
})
</script>
Mustache语法 {{}} 渲染文本变量
需求:后台数据 直接 渲染到表格、列表等。
分2不
- 使用{{}}写入表达式
- 如果表达式内有变量,提前在VUe中声明
<div id="box">
{{var1}}
{{var1 + var2}}
{{var1 > var2 ? 'yes':'no'}}
</div>
v-html 渲染html内容
需求:有时候某些文章包含Html内容我们需要将这些数据返回给页面变成前端页面的一部分,最典型的是有些富文本编辑器文章是含html代码的,Vue为了安全 不支持通过{{}} 直接渲染内容,而是通过v-html = “变量” 来渲染html文本。
分2步
- 不支持 直接{{var}}渲染,首先需要一个标签,在标签内添加 v-html
- Vue中声明绑定的变量
<div v-html="var">
</div>
v-model 绑定变量
需求:需要获取表单数据输入框的值。
分两步
1.设置标签绑定变量
2.Vue中声明绑定的变量
<input type="text" v-model="blindvar" /> //绑定input
<textarea type="text" v-model="blindvar" ></textarea>//绑定多行文本
<label>{{blindvar}}</label>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
blindvar:'',
}
})
</script>
- 绑定checkBox
需求:我们需要直到表单里面check组件是否选中。
<input type="checkbox" v-model="isChecked" /> //绑定checkbox
<script type="text/javascript">
new Vue({
el:"#box",
data:{
isChecked:true,
}
})
</script>
-
绑定多个checkBox
<input type="checkbox" v-model="isCheckedList" value="Music" /> Music <input type="checkbox" v-model="isCheckedList" value="Running" /> Running <input type="checkbox" v-model="isCheckedList" value="Walk" /> Walk <input type="checkbox" v-model="isCheckedList" value="Swimming" /> Swimming <script type="text/javascript"> new Vue({ el:"#box", data:{ isCheckedList:[], } }) </script>
对于 多个 check 我们通过数组存储,为了区别每一个选项 我们需要加一个value 来代表每一个checkbox。
-
绑定单选框
<input type="radio" v-model="picked" value="Music" /> Music <input type="radio" v-model="picked" value="Running" /> Running <input type="radio" v-model="picked" value="Walk" /> Walk <input type="radio" v-model="picked" value="Swimming" /> Swimming <script type="text/javascript"> new Vue({ el:"#box", data:{ picked:'', } }) </script>
v-show 标签的显示隐藏
需求:需要根据后台返回数据显示隐藏某些元素、比如后台管理系统的菜单、按钮等或者通过某些点击事件,控制某些元素的隐藏显示。
分两步
1.设置标签绑定变量
2.Vue中声明绑定的变量
<div v-show="!isshow" > //isshow = false 显示 div 第一步
display false
</div>
<div v-show="isshow" >//isshow = true 显示 div
display true
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
isshow:false, //定义布尔值变量 第二步
}
})
</script>
v-if 标签的创建与删除
需求:与v-show 不同的是,v-if 会真正操作DOM并且删除一些元素,但是v-show 节点并没有被删除,只是display变成none了,所以某些情况下,可以通过v-if 经行不同视图的切换。
分两步
1.设置标签绑定变量
2.Vue中声明绑定的变量
<div v-if="iscreated" >//第一步
be created
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
iscreated:true,//第二步
}
})
v-else-if|v-else 标签的创建与删除
需求:需要根据多种情况判断变量的值,来执行不同的分支,与v-if 合用,可以用于想购物车判断是否有数据展示不同的页面逻辑。
分两步
1.设置标签绑定变量
2.Vue中声明绑定的变量
<div v-if="select === 1">
branch 1
</div>
<div v-else-if="select === 2">
branch 2
</div>
<div v-else="select === 3">
branch 3
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
select:1,
}
})
</script>
:class 动态绑定标签class
需求:根据变量值,动态的修改标签的样式。
分2步
- 设置标签绑定变量
- Vue中声明绑定的变量
//css样式
<style>
.green{
background: #50f470;
}
.blue{
background:blue;
}
</style>
//第一步
<div :class="isActivate?'green':'blue'">
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
isActivate:true,//第二步
}
})
</script>
需求2:上面只是简单的三目运算符,只能 非A 即 B 但显示场景 可能要绑定多个class。
- map绑定多个:class
分2步
- 还是老样子绑定变量
- 我们要绑定的 不是单个变量 而是一个map(K/V),key为class的名字,value为boolean 用来设定是否绑定在标签上。
<div :class="classobj">//第一步
test clss blind
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
var1:1,
isActivate:false,
classobj:{class1:true,class2:true,class3:true}//第二步 都设置为true那么 class1 class2 class3 都会 绑定在div上
},
methods:{
classtransfer(){
this.isActivate = !this.isActivate
}
}
})
</script>
- 通过数组绑定多个:class
<div :class="classarray">
test clss blind
</div>
classarray:['css1','css2']
~注意:通过map 和数组 的区别是,数组 可以在渲染后再进行添加class操作,但是通过Map 如果通过 xx.classobj['classn] =true 再往里A面添加一个
k/v vue不会再次生成getsetter方法 修改了 也不会有什么效果,而数组是可以通过push 往里面添加元素的。
@click 绑定Click点击事件
需求:点击按钮触发指定了方法.
分2步
- 首先标签 绑定@click 和要触发的函数
- Vue中添加触发的函数
<button @click="classtransfer()" >Click Me</button>//第一步 绑定按钮点击事件
<script type="text/javascript">
new Vue({
el:"#box",
data:{
var1:1,
isActivate:false,
},
methods:{
classtransfer(){//第二步:在vue声明绑定的函数
this.isActivate = !this.isActivate//这里是对上一个方法:class 的修改通过按钮click 来动态修改 标签的类
}
}
})
</script>
:style 动态修改标签css样式
需求:根据数据动态的修改css样式
- 绑定的数据直接变量
分2步
- 将:style绑定好标签后,设置css 属性,css属性可以使变量、三目运算符返回。
- Vue中添加变量
<div :style="'background:' + color">
dynamic style
</div>
<div :style="'background:' + (isActivate?'red':'yellow')">
dynamic style
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
isActivate:true,
color:"red"
}
})
</script>
- 绑定的数据通过VueMap对象
分2步
- 将:style绑定好标签后,把Map对象作为数据源
- Vue中添加Map键值对,css属性以键值存储在Map中,如果是xx-xx形式的css属性就改写成 驼峰形式xxXx形式。
<div :style="styleobj">
dynamic styleobj
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
styleobj:{
"backgroundColor":"blue",//注意background-color 这种 x-x 形式的属性 改成驼峰写法
}
},
}
})
</script>
上面的方式缺点是,可以修改已有的样式但是没法在已有的样式上添加新的样式。 而下面一种方法 可以完美解决这个问题。
- 绑定的数据通过数组的形式
<div :style="stylearr">
dynamic stylearr
</div>
<button @click="pushstyle()" >Push Style</button> //压入样式
<button @click="deletestyle()" >Pop Style</button>//弹出样式
<script type="text/javascript">
new Vue({
el:"#box",
data:{
stylearr:[]
},
methods:{
pushstyle(){
this.stylearr.push({"background":"red"})
},
deletestyle(){
this.stylearr.pop("background");
}
}
}
})
</script>
v-for 循环渲染数据
- 遍历对象生成li列表
<ul>
<li v-for="(val,key) in|of dataobj"> //of 和 in 作用相同
{{key+' '+val}}
</li>
</ul>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
dataobj:{
'name':"caomao",
'age':"1",
'sex':"xx",
'favor':"sleep",
},
},
}
})
</script>
- 遍历数组生成li列表
<label>v-for循环列表</label>
<ul>
<li v-for="(data,index) in datalist">
{{data,index}} //数组的值和数组索引
</li>
</ul>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
datalist:["content1","content2","content3","content4"]
},
}
})
</script>
修改方法
//通过数组形式生成列表的增删改
this.datalist.push(this.lidata);//添加
this.datalist.pop(this.lidata);//弹出顶部
this.datalist.splice(this.datalist.indexOf(this.lidata), 1)//删除数据
//通过Vue提供的方法 用索引给 vue修改值
Vue.set(this.datalist,0,'caomao')
this.datalist.splice(this.couponSelected, 1,this.lidata )
其他相关方法
push() pop() shift() unshift() splice() sort() reverse() 直接改变原数组
filter(),contact()和slice(),map() 返回新数组
~注意:通过Vue.set 我们可以对map进行属性的增加 Vue.set(this.dataobj,‘caomao’,true)
~注意: 对于更新数据时,我们可以通过设置一个不重复的id,来作为一句来跟新数据而不是覆盖掉原有的所有数据,这样可以减少dom的操作
<ul>
<li v-for="(data,index) in datalist" key="data"> //把数组索引作为 依据 如果原来 [0,1] 跟新后 是[1,0] 那么 那会比较索引 再去修改,如果是对象 可以设置为 每条数据的id,每次修改时 按照id去比较。
{{data}}
</li>
</ul>
@input 绑定input改变触发事件
需求:根据输入框输入的值,去触发后台请求,如搜索引擎会有搜索提示,另外可以对网页表格里面的值进行匹配筛选。
分2步:
- input标签绑定@input和出发函数
- 在methods声明要出发的函数
<input type="text" v-model="myevent" @input="myinput">
<label>{{inputevent}}</label>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
myevent:'',
inputevent:'',
},
methods:{
myinput(){
this.inputevent = this.myevent;
console.log(this.myevent);
}
}
}
})
</script>
@change 绑定input焦点离开触发事件
事件修饰符
@click.stop阻止事件冒泡
在Dom中点击时间,会向上冒泡 也就是说 你点击 一个按钮 他会把这个点击时间不停往上的传递,最终他父元素和更上面的元素都得到所以有时候我们需要阻止这种默认的传递,我们需要 代码阻止向上传递.
<button @click="handler($event)"> Click Me</button>
new Vue().....
....
handler(e) {
console.log(e);
//阻止事件向上冒泡
e.stopPropagation();
}
....
在Vue中可以使用它提供@click.stop的方法来阻止事件冒泡的行为.
<button @click.stop="handler($event)"> Click Me</button>
@click.prevent 阻止事件默认行为
需求:在某些情况下,比如提交表单 点击链接 我们 想先对数据进行校验 不让行为立马触发。
<a href="http://www.baidu.com/" @click="defaulthandler($event)"> Default Action</a>
<a href="http://www.baidu.com/" @click.prevent="defaulthandler($event)">Prevent Default Action</a>
@click.self 不响应 Child事件
需求:某些情况下,我们不希望Sub的节点向上冒泡而导致自己事件被响应。
<ul @click.self="justhandlermyevent($event)">
<li @click="handlerevent($event)"> 123</li>
</ul>
....
handlerevent(e){
alert(e);
},justhandlermyevent(e){
alert(e);
}
....
@click.once 只响应一次事件
需求:某个抽奖页面,只能点击一次之后就不会有事件再去响应了。
<ul @click.self="justhandlermyevent($event)">
<li @click.once="handlerevent($event)" >once click event</li>
</ul>
....
handlerevent(e){
alert(e);
},justhandlermyevent(e){
alert(e);
}
....
小结:实现一个文本跑马灯
1.首先我们初始化一个空的Vue项目。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue单文件例子</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="paoma">
</div>
</body>
<script type="text/javascript">
new Vue({
el:"#paoma"
})
</script>
</html>
2.定义一个加速,减速按钮,然后需要用到 @click 点击事件, {{}}mustache 语法,v-model 绑定变量.
<div id="paoma">
<input type="text" v-model="content">
<button @click="speedup()">speed up</button>
<button @click="slowdown()">slow down</button>
<hr>
<label>{{content}}</label>
</div>
</body>
<script type="text/javascript">
new Vue({
el:"#paoma",
data:{
content:'(#^.^#)|-> ...Vue',
},
methods:{
speedup() {
//思路 把第一个字符截掉 追加到字符串后面 循环就能实现跑马灯效果
var start = this.content.substring(0,1);
//裁掉1以后所有字符
var end = this.content.substring(1)
//将第一个字符拼接到后面
this.content = end + start;
},
slowdown() {
}
}
})
</script>
-
现在做到了,点一次就跑一次 如果想让它自己动起来我们还需要定义一个计时器,现在Vue声明一个变量存放计时器,当我们 加速的时候要把 原来的定时器 清除 然后创建一个新的定时器。
.... data:{ content:'(#^.^#)|-> ...Vue', MyInterval:null, }, ... //声明一个定时器 this.MyInterval = setInterval(() =>{ },400)//设置间隔ms //清除定时器 clearInterval(this.MyInterval);
完整实现
跑马demo: https://github.com/qiaojinxia/vue-study/blob/master/paoma.html
按键修饰符
@keyup.enter 响应回车键事件
<input type="text" @keyup.enter="handlerenter($event)" />
....
handlerenter(e){
alert(e);
}
....
@keyup.[keynum] 按键弹起响应时间
<input type="text" @keyup.13="handlerenter($event)" />
....
handlerenter(e){
alert(e);
}
....
小结: 用Vue 实现一个购物车
- 首先我们初始化一个空的Vue项目。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue单文件例子</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="cart">
</div>
</body>
<script type="text/javascript">
new Vue({
el:"#cart"
})
</script>
</html>
- 准备好数据。
datalist:[
{
id:1,
name:"Good1",
price:10,
number:1,
},{
id:2,
name:"Good2",
price:23,
number:1,
},{
id:3,
name:"Good3",
price:43,
number:1,
},{
id:4,
name:"Good4",
price:15,
number:1,
},{
id:5,
name:"Good5",
price:17,
number:1,
},{
id:6,
name:"Good6",
price:41,
number:1,
},{
id:7,
name:"Good7",
price:32,
number:1,
},
]
- 数据用列表方式展示,我们用v-for 生成购物车列表,购物车都是多选框选中的,所以我们还需要再放一个多选框,在列表里.
<ul>
<li v-for="good in datalist">
<input type="checkbox" >
{{good}}
</li>
</ul>
4.我们需要 获取选中的check来计算价格 用v-model 绑定一个数组来记录选中的商品。
<div id="cart">
<ul>
<li v-for="good in datalist">
<input type="checkbox" v-model="checkarr" >
{{good}}
</li>
</ul>
{{checkarr}}
<p>总金额:</p>
</div>
- 绑定后我们用:value=“xxx” 动态绑定 也就是xxx解析为变量,而不是文本。然后我们给checkbox赋值,为 数量 * 价格
<div id="cart">
<ul>
<li v-for="good in datalist">
<input type="checkbox" v-model="checkarr" :value="good.price * good.number" >
{{good}}
</li>
</ul>
{{checkarr}}
<p>总金额:{{getsummary()}}</p>
</div>
- 如果我们需要每次勾选后就计算一次,其中一个思路每次勾选触发一次计算,另一种做法是 在{{ }}中写一个函数 每次 如果函数中的某些变量被改变了Vue 会自动把相关的函数执行一遍。
//计算所有金额
getsummary(){
var sum = 0;
for(var i in this.checkarr){
sum+= this.checkarr[i];
}
return sum;
}
- 在购物车中经常有 全选这样的功能,如果全选 就把数据 更新为 [] 或者 [价格1,价格2]
<input type="checkbox" v-model="selectall" @change="selecta()" >
selecta(){
if(!this.selectall){
this.checkarr =[];
}else{
var arr =[];
for(var i in this.datalist){
arr[i] = this.datalist[i].price * this.datalist[i].number;
}
console.log(arr);
this.checkarr =arr;
}
-
为了更好的用户体验,当我们 一个个去选 都选中时,那个全选按钮应该也会被选中,反之 如果所有按钮都没全中全选按钮就不会选中,我们要实现这种动态联动的效果。那么其实最简单的就是判断数组的长度 如果全选中那么长度和列表的长度一样否则 如果全不选长度就是0,为此我们需要为checkbox绑定一个@click事件。
<input type="checkbox" v-model="checkarr" @change="checkselect()" :value="good.price * good.number" >//绑定 checkselect 事件 checkselect(){ if(this.checkarr.length === this.datalist.length){ this.selectall = true; }else if(this.checkarr.length === 0){ this.selectall = false; } }
-
购物车 还需要实现对商品 添加和 减少 为此 我们需要增加2个按钮,绑定@click和相应的事件并且我们需要修改当前对象所以 需要传入要修改的对象,当然 在做减商品逻辑时当数量为 1时 在去减就要出发删除操作了,吧对象从列表里删除,所以我们要用this.datalist.splice(this.datalist.indexOf(good), 1)//删除数据 我们传入的时候也要把这个对象在list里面索引也传递给处理方法以便于删除.
<button @click="makeadd(good)" >+</button>
{{good.number}}
<button @click="makesub(good,index)" >-</button>
makeadd(good){
good.number ++;
},
makesub(good){
if(good.number == 1){
this.datalist.splice(this.datalist.indexOf(good), 1)//删除数据
}
good.number --;
}
购物车完整实现:
https://github.com/qiaojinxia/vue-study/blob/master/cart.html
Vue生命周期
Vue组件
组建的思路是将,某个功能单独写成一个模块,这样同一组件可以被多次被复用,同时组件化思想 能把一个大的复杂的页面功能分解解成一个个小的功能。
- vue组件的使用
- 创建组件构造器
- 注册组件
- 使用组件
组件化开发入门
- 首先我们还是先 准备一个基本的Vue初始结构。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue单文件例子</title>
</head>
<body>
<div id="app">
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
const app = new Vue({
el:"#app"
})
</script>
</html>
创建 组件分3步
- 创建组件构造器
const vueC = Vue.extend({
template:
`<div><h2>title</h2></div>`
})
使用Vue的extend方法 创建组件构造器。template 代表我们自定义的组件模板,就是我们要显示的html代码。
- 注册组件(全局组件 可以在多个new Vue 里面使用)
Vue.component('my-comp',vueC);
在Vue中注册组件的标签 和对应组件template。
2.1 局部注册方式
const app = new Vue({
el:"#app",
components:{
cpn:vueC, //以局部组件方式 其他new Vue 无法使用 标签<cpn></cpn>
}
})
- 使用组件
当我们注册了组建后,我们就可以直接在div引用内部使用注意必须在new Vue 所初始化的div内部使用注册的组件标签。
<my-comp></my-comp> //就是上面Vue.component('my-comp',。。。。);的注册标签
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue单文件例子</title>
</head>
<body>
<div id="app">
<!--3.使用组件标签 !-->
<my-comp></my-comp>
<cpn></cpn>
</div>
<div id="app1">
<!--3.使用组件标签 !-->
<my-comp></my-comp>
<cpn></cpn> <!--被app以 局部方式注册 这里就无法使用了 !-->
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
//1.创建组件构造器
const vueC = Vue.extend({
template:
`<div><h2>title</h2></div>`
})
//2.注册组件
Vue.component('my-comp',vueC); //全局组件注册方式 能被所有new Vue 使用
const app = new Vue({
el:"#app",
components:{
cpn:vueC, //以局部组件方式 注册 app1 就无法使用
}
})
const app1 = new Vue({
el:"#app1",
})
</script>
</html>
父组件子组件
组件 内部还可以嵌套组件,形成父子组件。
- 先构造要被嵌套的子组件
const VueComp2 = Vue.extend({
template:
`<div>
<h2>second title</h2>
<p>content</p>
<cpn1></cpn1>
</div>`
})
- 再构造父组件,并且将子组件注册进父组件components中,然后就可以直接使用Html标签来引用子组建了
const VueComp1 = Vue.extend({
template:
`<div>
<h2>first title</h2>
<p>content</p>
<vcpn2></vcpn2> //2. 使用子组件
</div>`,
components:{ //!注意 模板构造器通过 components可以注册 子组件
vcpn2:VueComp2,//1. 注册子组件
}
})
3.最后在 Vue 中注册组件,其实可以把new Vue 看成是根组件。
const app = new Vue({
el:"#app",
data:{
},components:{
vcpn1:VueComp1, //1.注册有子组件的父组件
}
})
-
总结:父子 组件 简单的说 就是 a组件 里面可以注册 b组件 b组件 里面可以注册 c组件,形成嵌套。
- 注意:Vue寻找组件先是从自己的components中查找,如果找不到 会再去全局组件中查找,如果找不到 会报错。
使用语法糖注册组件
const app = new Vue({
el:"#app",
data:{
},components:{
vcpn1:{//通过语法糖 直接省去了使用 Vue.extend
template:
`<div>
<h2>first title</h2>
<p>content</p>
<vcpn2></vcpn2>
</div>`,components:{
vcpn2:VueComp2,
}
}
}
})
~注意:使用语法糖 可以直接省去 使用Vue.extend 而是直接使用一个对象Map代替。
更加简洁友好的分离template代码
上面的例子,可以看到 template 下面一大堆 html代码 ,如果 html比较复杂 看的非常难受修改起来容易出错,我们可以把 这些html代码 抽离出来 七个名字,直接引用名字就好。
<script type="text/x-template" id="mytemp">
//分离出来的内容
</script>
const app = new Vue({
el:"#app",
data:{
},components:{
vcpn1:{
template:mytemp //通过名字 来索引上面的div内容
,components:{
vcpn2:VueComp2,
}
}
}
})
可以看到 ,分离后代码看起来更友好,更简洁,下面我们介绍另一种一样但是用的更多的方法。
<template id="mytemp1">
<div>
MYTEMP
</div>
</template>
const app = new Vue({
el:"#app",
data:{
},components:{
vcpn1:{
template:'#mytemp1'//通过template的id指定
,components:{
vcpn2:VueComp2,
}
}
}
})
~注意 : template 模班一般必须要有一个div 包裹。
组件内通过data()存放数据
不推荐组件内部数据存放在Vue实例中,我们可以将组件数据 存放在组件内部,可以更好的方便维护。
组件内部,可以用data() 方法 存放数据
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>组件不能访问Vue实例数据</title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="mytemps">
<div>
components {{title}}
</div>
</template>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script type="text/javascript">
const app = new Vue({
el:"#app",
data:{
title:"12",
},
components:{
'cpn':{
template: '#mytemps',
data(){ //通过data方法 而不是 data 的 对象来定义组件内数据
return { //这个函数会在栈上分配 多个组件数据可以独立
title:'title'
}
}
}
}
})
</script>
</body>
~注意: 这里 为什么通过 data()方法而不是data对象,主要是由于 当组件被多个应用的时候,通过 data()方法 分配在独立栈空间中,而如果直接使用 对象数据 可能会指向同一块内存,同一个组件之间数据会产生脏读。
父子组件之间通信
需求:使用Vue 编写一个网页 往往会有很多组件拼接起来,那么 如果我们需要请求数据再交给这些组件取渲染,应该选择最外面根组件页面取获得数据,然后把他交给所有子组件,那么组件之间怎么传递数据就是一个问题了。
![image-20200513140531098](/Users/qiao/Library/Application%20Support/typora-user-images/image-20200513140531098.png)
![image-20200513140943846](/Users/qiao/Library/Application%20Support/typora-user-images/image-20200513140943846.png)
- 通过props向子组件传递数据
定义一个 父组件 包含子组件的结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue父子组件之间的通信</title>
</head>
<body>
<div id="app">
<aparent></aparent>
</div>
</body>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<template id="myparent">
<asub></asub>
</template>
<template id="mysub">
<div>
is sub {{movies}}
</div>
</template>
<script type="text/javascript">
// const VueComp1 = Vue.extend({
// template:mytemp,
// components:{
// vcpn2:VueComp2,//在 组件里面注册 第二个组件
// }
// })
const app = new Vue({
el:"#app",
data:{
},components:{
'aparent' :{//通过语法糖 直接省去了使用 Vue.extend
template:'#myparent'
,components:{
asub :{//通过语法糖 直接省去了使用 Vue.extend
template:'#mysub'
// }
}
},data(){
return {
movies:['复仇者4','钢铁侠3','蜘蛛侠2','黑寡妇3','美国队长'],
}
}
}
}})
</script>
</html>
我们要把 movies 传递给 mysub 首先得在 mysub 组件内部定义一个 props用来声明传递的变量props:[‘cmovies’] ,同时 我们需要在 父调用子组件的 地方 设置传递的映射
<template id="myparent">
<asub v-bind:cmovies ="movies"></asub> //使用v-bind 将 movies -> 传给子组件的 prop里的cmovies 变量
</template>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue父子组件之间的通信</title>
</head>
<body>
<div id="app">
<aparent></aparent>
</div>
</body>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<template id="myparent">
<asub v-bind:cmovies ="movies"></asub> //2.绑定 传递和被传递之间的关系 如果追加多个参数传递 <asub v-bind:cmovies ="movies" v-bind:xx ="xxx"></asub> v-bind:xx="xxx"可以简写为 :xx="xxx"
</template>
<template id="mysub">
<div>
is sub {{cmovies}}
</div>
</template>
<script type="text/javascript">
// const VueComp1 = Vue.extend({
// template:mytemp,
// components:{
// vcpn2:VueComp2,//在 组件里面注册 第二个组件
// }
// })
const app = new Vue({
el:"#app",
data:{
},components:{
'aparent' :{//通过语法糖 直接省去了使用 Vue.extend
template:'#myparent'
,components:{
asub :{//通过语法糖 直接省去了使用 Vue.extend
template:'#mysub'
,props:['cmovies'] //1.设置子组件被传递的变量
// }
}
},data(){
return {
movies:['复仇者4','钢铁侠3','蜘蛛侠2','黑寡妇3','美国队长'],
}
}
}
}})
</script>
</html>
此时 我们想要 父组件的movies 变量,但是在子组件是访问不到的,所以需要通过
props 不仅支持数据 还支持对象 props:{content1:String,content2:Number,content2:Array} 这样书写方式 可以对传入的变量值
左校验数据类型,支持以下的几种数据类型。
![image-20200513144242039](/Users/qiao/Library/Application%20Support/typora-user-images/image-20200513144242039.png)
其他形式写法:
props:{content1:{
type:String, //传入类型为String
default:‘xxxxx’’ //没传使用默认值
required:true, //boolean值 必须传入 否则报错
}}
-
如果传入的是对象 default:{xx:xx} 不能是对象 要返回 default(){ return {xx:xx} } 方法里面的对象。
- 注意:props里面如果是驼峰格式的 myPro 在 使用v-bind 时 要变成 my-pro,
- 通过事件向父组件发送消息