Vue笔记
let
定义变量, const
定义常量
var
是JS的一个设计错误,用var
定义的变量出了代码块依然能访问
{
var a = 10;
}
console.log(a);
而let不行
{
let a = 10;
}
console.log(a);
const
定义的常量不能被第二次赋值
Vue基本格式
<body>
<div id="vue_det">
<p>{{site}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
site: "hello"
}
})
</script>
el
绑定元素,#
为ID选择器,同理,可以使用.
类选择器和div
标签选择器等
vue生命周期
v-once
在标签中加上这个的时候,值只改变一次
v-pre
原封不动的显示出来
v-cloak
斗篷,没啥用
v-text
<body>
<div id="vue_det">
<p v-text="aaa"></p>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
aaa: "你好"
}
})
</script>
aaa
对应的值会显示在v-text
属性为aaa
的标签中
v-html
设置元素的innerHTML
<body>
<div id="vue_det">
<p v-html="aaa"></p>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
aaa: "<a href=''#'>这是测试的HTML</a>"
}
})
</script>
aaa
对应的HTML值,会被解析后显示在v-html
属性为aaa
的标签中
v-on
为元素绑定事件
<body>
<div id="vue_det">
<button v-on:click="bbb">{{msg}}</button>
<button @click="ccc()">{{msg}}</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
msg:"点我"
},
methods:{
bbb:function(){
alert("bbb");
},
ccc:function(){
alert("ccc");
}
}
})
</script>
使用v-click
或@click
均可绑定事件
实时改变值
<body>
<div id="vue_det">
<div id="vue_det">{{msg}}</div>
<button @click="aaa">{{btn}}</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
btn:"点击后改变值",
msg:"要被改变的"
},
methods:{
aaa:function(){
this.msg = "这是改变后的"
}
}
})
</script>
一个计数器
<body>
<div id="vue_det">
<button @click="add()">{{btn1}}</button>
<div>{{num}}</div>
<button @click="sub()">{{btn2}}</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
btn1:"sub",
btn2:"add",
num:1
},
methods:{
add:function(){
this.num--;
},
sub:function(){
this.num++;
}
}
})
</script>
v-show
显示和隐藏元素
<body> <div id="vue_det"> <div v-show="flg">这是文字</div> <button @click="show()">{{btn1}}</button> <button @click="hide()">{{btn2}}</button> </div></body><script> var app = new Vue({ el:"#vue_det", data:{ btn1:"显示", btn2:"隐藏", flg:true }, methods:{ show:function(){ this.flg = true; }, hide:function(){ this.flg = false; } } })</script>
- 原理是修改元素的display,实现显示隐藏
- 指令后面的内容最终都会解析成布尔类型
- 数据改变之后,对应元素的显示状态会同步跟新
v-if
根据表达式的真假,切换元素的显示和隐藏
<body> <div id="app"> <button @click="showOrHide">{{msg}}</button> <p v-show="isShow">文字文字文字</p> </div> </body> <script> var app = new Vue({ el:"#app", data:{ msg:"显示或隐藏", isShow:false }, methods:{ showOrHide:function(){ this.isShow = ! this.isShow; } } }) </script>
和v-show
相比,v-if
是直接操作DOM树
v-if
中也可以写表达式
v-show
对资源消耗小
v-bind
使用动态的值
<img v-bind:src="变量">
<body> <div id="app"> <p v-bind:style="bg">文字文字文字</p> </div> </body> <script> var app = new Vue({ el:"#app", data:{ bg:"background:red" } }) </script>
其中v-bind
可以简写为:
<body> <div id="app"> <img :src="imgSrc" :title="imgTitle"> </div> </body> <script> var app = new Vue({ el:"#app", data:{ imgSrc:"https://model-1253780623.cos.ap-guangzhou.myqcloud.com/live2d/model/rem/remu2048/texture_00.png", imgTitle:"衣服贴图" } }) </script>
使用两种方法来判断是否应用样式
<body> <style> .active{ border: 1px solid red; } </style> <div id="app"> <img :src="imgSrc" :title="imgTitle +'!!!'" :class="isAcitve?'active':''"> <img :src="imgSrc" :title="imgTitle +'!!!'" :class="{active:isAcitve}"> </div> </body> <script> var app = new Vue({ el:"#app", data:{ imgSrc:"https://model-1253780623.cos.ap-guangzhou.myqcloud.com/live2d/model/rem/remu2048/texture_00.png", imgTitle:"衣服贴图", isAcitve:false } }) </script>
其中isAcitve?'active':''
为三元运算符号
{active:isAcitve}
表示,active
是否有效,取决于isAcitve
为真或假(推荐)
Vue图片切换效果
<body> <div id="app"> <img :src="imgSrcList[imgIndex]" width="500px"> <button @click="lastImgFun" v-show="imgIndex>0">{{lastImg}}</button> <button @click="nextImgFun" v-show="imgIndex<imgSrcList.length-1">{{nextImg}}</button> </div> </body> <script> var app = new Vue({ el:"#app", data:{ nextImg:"下一张", lastImg:"上一张", imgSrcList:[ 'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0044.jpg', 'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0045.jpg', 'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0039_1613799292227_88.jpg', 'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0062_1614511056097_10.jpg', 'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0058_1614511054295_12.jpg' ], imgIndex:0 }, methods:{ lastImgFun:function(){ this.imgIndex-- }, nextImgFun:function(){ this.imgIndex++ } } }) </script>
v-for
<body> <div id="app"> <ul> <li v-for="(item,index) in list" :title="item"> {{index}}--{{item}} </li> </ul> <button @click="add">添加</button> <button @click="del">移除</button> </div> </body> <script> var app = new Vue({ el:"#app", data:{ list :[1,2,3,4,5] }, methods:{ add: function(){ this.list.push("添加一个"); }, del:function(){ this.list.shift(); //移除 this.list.splice(i,j) //移除从i开始的j个 } } }) </script>
item
代表list
中的值index
代表编号
<body> <div id="app"> <ul> <li v-for="(item,index) in list" :title="item"> {{index}}--{{item}} </li> </ul> <input type="text" @keyup.enter="add(txt)" v-model="txt" value="txt">回车添加 </div> </body> <script> var app = new Vue({ el:"#app", data:{ list :[1,2,3,4,5], txt:"" }, methods:{ add:function(p1){ this.list.push(p1); console.log(p1) } } }) </script>
其中p1
为形参可以接收传递进来的实参
v-model
可以实现双向绑定
axios
功能强大的网络请求库
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>axios.get(地址?查询字符串).then(function(response){},function(err){});axios.post(地址,{key:value,key2:value2}).then(function(response)(),function(err){});
天气查询小工具
<body> <div id="app"> <input type="text" @keyup.enter="add(txt)" v-model="txt" value="txt">回车查询 <ul> <li v-for="item in list" :title="item"> {{item}} </li> </ul> </div> </body> <script> var app = new Vue({ el:"#app", data:{ list :[], txt:"" }, methods:{ add:function(p1){ that = this this.list = []; axios.get("https://restapi.amap.com/v3/weather/weatherInfo?key=5d2d3e6c0d5188bec134fc4fc1b139e0&city=" + this.txt +"&extensions=base").then(function(response){ var dateJson = response.data.lives[0]; console.log(response.data.lives[0]); that.list.push("时间:" + dateJson['reporttime']); that.list.push("城市:" + dateJson['province'] + dateJson['city']); that.list.push("湿度:" + dateJson['humidity']); that.list.push("气温:" + dateJson['temperature']); that.list.push("天气:" + dateJson['weather']); that.list.push("风向:" + dateJson['winddirection']); that.list.push("风力:" + dateJson['windpower']); },function(err){ }); } } }) </script>
使用多个class
<style> .c1{ color: red; } .c2{ background-color: blue; } </style> <div id="app"> <div :class="{c1:true,c2:false}">今天的天气很好</div> </div>
在网页上应用了c1的class,c2没有应用
computed 计算函数
<body> <div id="app"> <div>{{aaaAndBbb}}</div> </div></body><script> const vm = new Vue({ el:"#app", data:{ a:'aaa', b:'bbb' }, computed:{ aaaAndBbb:function (){ return this.a + this.b; } } })</script>
直接调用aaaAndBbb
就可以返回aaabbb
ES6增强写法
const a = { aaa(){ console.log("aaa"); }, bbb(){ console.log("bbb"); } }
调用event变量
<body> <div id="app"> <button @click="clickGo('123',$event)">123456</button> </div></body><script> const vm = new Vue({ el:"#app", data:{ }, methods:{ clickGo:function (a,b){ console.log(a, b); } } })</script>
sopt 阻止冒泡
<body> <div id="app"> <div @click="divClick"> <button @click.stop="butClick">点我</button> </div> </div></body><script> const vm = new Vue({ el:"#app", data:{ }, methods:{ divClick:function (){ console.log("div事件冒泡"); }, butClick:function (){ console.log("按钮事件冒泡,我阻止了div事件冒泡"); } } })</script>
点击按钮,只有按钮事件被执行
prevent 阻止默认事件
<body> <div id="app"> <form action="#"> <input type="submit" value="提交" @click.prevent="butClick"> </form> </div></body><script> const vm = new Vue({ el:"#app", data:{ }, methods:{ butClick:function (){ console.log("按钮事件冒泡,我阻止了原来的提交事件"); } } })</script>
点击提交后<input>
默认的提交事件会被阻止
一些数组方法
push 在最后添加一个元素
pop 删除数组最后一个元素
shift 删除数组中的第一个元素
unshift 在数组的最前面添加元素
splice 在某个位置插入元素
JavaScript 可变参数 …
function aaa(...num){ console.log(num); }
该函数可接受任意个参数。
点击哪个哪个变红
<body> <div id="app"> <ul> <li v-for="(item,index) in a" :class="{rrr:isRed == index}" v-on:click="toRed(index)">{{index + " . " + item}}</li> </ul> </div></body><script> const vm = new Vue({ el:"#app", data:{ a:["aaa","bbb","ccc","ddd"], isRed:-1 }, methods:{ toRed:function (a){ this.isRed = a; } } })</script>
key
splice
插入替换元素
过滤器
<div id="app"> {{jg_one | addOne}}</div></body><script> const vm = new Vue({ el:"#app", data:{ jg_one:50 }, filters:{ addOne(jg){ return jg + 100; } } })
在filters
中定义过滤器,在变量后,使用|
来使用过滤器,过滤器自动把前面的变量当做参数传入
in
<body><div id="app"> <ul v-for="i in t"> <li>{{i}}</li> </ul></div></body><script> const vm = new Vue({ el:"#app", data:{ t:["aaa","bbb","ccc"] } })</script>
使用in
来遍历t
列表
filter()
list.filter()
let a = [1,2,3,4,5,6]; let b = a.filter(function (n){ return n > 3 })console.log(b)
filter
类似于过滤器,本示例中输出 [4,5,6]
map()
let a = [1,2,3,4,5,6];let b = a.map(function (n){ return n * 2})console.log(b)
map
返回函数中操作的结果,本示例中输出[2, 4, 6, 8, 10, 12]
reduce()
let a = [1,2,3,4,5,6];let b = a.reduce(function (pre,n){ return pre += n},0)console.log(b)
reduce
有三个参数,reduce(function(初始数,正在取出的数),初始数的初始值)
本示例中输出21
以上三个函数均可以用箭头函数来执行
let a = [1,2,3,4,5,6];let b = a.reduce((pre,n) => pie + n)console.log(b)
v-model在checkbox中的使用
<body><div id="app"> <input type="checkbox" value="111" v-model="a">111 <input type="checkbox" value="222" v-model="a">222 <input type="checkbox" value="333" v-model="a">333 {{a}}</div></body><script> const vm = new Vue({ el:"#app", data:{ a:[] } })</script>
在选中复选框后,{{a}}
处会实时渲染出a数组本示例全选中后显示的是:[ "111", "222", "333" ]
v-model的一些操作
v-model.lazy
用于在鼠标失去焦点或者按下回车的时候同步值
v-model.number
用于把用户输入的数字转换为数字形式
v-model.trim
用于将用户输入的内容两边的空格去除
组件
<body><div id="app"> <mya></mya></div><script> // 注册 Vue.component('mya', { template: '<h1>自定义组件!</h1>' }) // 创建根实例 new Vue({ el: '#app' })</script></body>
局部组件和全局组件
局部组件
只可以在声明的vue中使用
全局组件
声明了之后,可以在任意位置使用
父子组件的通信
- 注意子组件中的data必须是一个函数
props
<body> <div id="app"> <cpn v-bind:cmsg="msg"></cpn> </div> <template id="mb"> <div>{{cmsg}}</div> </template></body><script> const mb = { template:"#mb", props:["cmsg"] } const vm = new Vue({ el:"#app", data:{ msg:"Hello" }, components:{ cpn:mb } })</script>
如代码中所示,在父组件vue中定义了一个msg
,又定义了一个子组件 mb
,我们的目的是在app
节点之外,访问到msg
这个变量的值,首先我们要做的是在根节点中使用cpn:mb
绑定这个模板mb
,然后在模板对象中使用props:['cmsg']
设置父节点映射到子节点中的变量名。然后,在根节点中创建一个模板<cpn>
,使用 v-bind:cmsg=:"msg"
来绑定子节点中的cmsg
和父节点中的msg
,这样就可以在子节点中访问到父节点中的内容了。
类型限定
props:{ cmsg:String}//或者这样props:{ cmsg:{ type:String, default:'123', //默认值,类型是对象或者数组时,对象要是一个函数 required:true //使用时必传该参数 }}
子传父
<body> <div id="app"> <cpn @btnclick="cpnClick"></cpn> </div> <template id="mb"> <button @click="btnClick(msg)">{{msg}}</button> </template></body><script> const mb = { template:"#mb", data(){ return{ msg:"Hello" } }, methods:{ btnClick:function (msg){ this.$emit('btnclick',msg) } } } const vm = new Vue({ el:"#app", data:{ }, methods: { cpnClick:function (msg){ console.log(msg) } }, components:{ cpn:mb } })</script>
我们的目的是把子组件中的msg
传给父组件,首先,我们要在子组件中定义一个方法btnClick
其中this.$emit('btnclick',msg)
用来传递参数,this.$emit('btnclick')
用于把event
对象发送到父组件中,后面跟着的msg
表示只发送msg参数,在父组件中,我们要创建一个cpnClick
函数来接收参数,接下来,我们要用<cpn @btnclick="cpnClick"></cpn>
把btnclick
和cpnClick
绑定在一起。
当子组件中的按钮被点击时,调用子组件中的btnClick
函数,该函数使用$emit
通过绑定的函数把数据传送到父节点。
父访问子
<body> <div id="app"> <button @click="btnClick">Click</button> <cpn1></cpn1> </div><template id="mb1"></template></body><script> const vm = new Vue({ el:"#app", methods:{ btnClick(){ console.log(this.$children); } }, components :{ 'cpn1':{ template:"#mb1", } } })</script>
slot
Vue插槽
<div id="app"> <cpn1> <div>你好</div> </cpn1></div><template id="mb1"> <div> hello <slot></slot> </div></template></body><script> const vm = new Vue({ el:"#app", components:{ 'cpn1':{ template:"#mb1" } } })</script>
使用<slot>
来定义插槽
插槽类似于接口,在模板定义了里面的内容之后,使用<slot>
来放置一个插槽接口,这操作后,我们就可以在使用这个模板的时候,使用类似于<div>你好</div>
的操作往模板里放进任意元素。
具名插槽使用
在使用插槽的时候,如果我们定义了多个插槽,那么在使用的时候,在一个插槽中放入东西,所有插槽就会跟着改变,所以,我们可以给插槽定义一个名字
<div id="app"> <cpn1> <div slot="a1">你好1</div> <!--使用a1插槽--> </cpn1> <cpn1> <div slot="a2">你好2</div><!--使用a2插槽--> </cpn1> <cpn1> <div slot="a3">你好3</div><!--使用a3插槽--> </cpn1></div><template id="mb1"> <div> <slot name="a1"></slot><!--定义a1插槽--> <slot name="a2"></slot><!--定义a2插槽--> <slot name="a3"></slot><!--定义a3插槽--> </div></template></body><script> const vm = new Vue({ el:"#app", components:{ 'cpn1':{ template:"#mb1" } } })</script>
编译作用域
<body><div id="app"> <cpn1> <div v-show="isShow">你好</div> </cpn1></div><template id="mb1"> <div> <slot></slot> <div v-show="isShow">今天的天气很好</div> </div></template></body><script> const vm = new Vue({ el:"#app", data:{ isShow:true }, components:{ 'cpn1':{ template:"#mb1", data(){ return{ isShow:false } } } } })</script>
如本示例:
我们在模板中定义了一个div
他的v-show=isSwho
,我们在使用该模板的时候,在插槽中定义了一个div
他的v-show=isShow
,但是在浏览器中渲染的时候,今天天气很好
不会被渲染出来,你好
会被渲染出来,这是因为,在模板中定义的isShow
使用的是模板中定义的值,而在根节点app
中定义的isSwho
使用的是根节点data
中的值。
插槽总结:父组件替换插槽标签,但是内容由子组件来提供
需要在多个界面进行展示
内容在子组件,希望父组件告诉我们如何展示
在插槽中使用组件中定义的变量
<body> <div id="app"> <cpn1></cpn1> <cpn1> <template slot-scope="slot"> <ul> <li v-for="item in slot.data">{{item}}</li> </ul> </template> </cpn1> </div> <template id="mb1"> <slot :data="Name"></slot> <div>hello</div> </template></body><script> const vm = new Vue({ el:"#app", data:{ }, components:{ "cpn1":{ template:"#mb1", data(){ return{ "Name":["111","222","333"] } } } } })</script>
如代码所示:我们在子组件中第定义了一个变量Name
,并且子组件中有一个插槽,我们的目的是在自定义插槽中的内容的时候,可以调用在组件中定义的变量。
首先在定义插槽的slot
标签中,使用:data="Name"
来创建一个data
变量,这里的data
可以是任意名称。
接下来我们在使用的时候
<cpn1> <template slot-scope="slot"> <ul> <li v-for="item in slot.data">{{item}}</li> </ul> </template> </cpn1>
要先在模板插槽中定义一个 template
或其他的节点,slot-scope="slot"
使用slot
或其他变量名来定义接收到的变量,然后使用slot.data
来调用变量