学习基础语法可以用HBuilder快捷,学习到了路由什么的话就用idea(修改规范为ES6)或者使用其他的软件
vue的一些指令
- v-show (展示)
- v-if (判断)
- v-else-if (判断)
- v-else (判断)
- v-for (for循环遍历输出)
- v-on (绑定事件,简写@)
- v-model (数据双向绑定)
- v-bind (给组件绑定参数,简写:)
vue常用的7个属性
- el属性
用来指示vue编译器从上面地方开始解析,可以说是一个占位符 - data属性
用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在打他中 - template属性
用来设置模板,会替换页面元素,包括占位符 - methods属性
放置页面中的业务逻辑,js方法一般都放在methods中 - render属性
创建真正的Virtual Dom - computed属性
用来计算属性 - watch属性
watch:function(new,old){}
监听data中数据的变化
两个参数,一个返回新值,一个返回旧值
vue第一个程序
首先得有那个node.js环境(在cmd里面输入node -v 出现版本信息就代表有安装环境)如果有条件的话安装还可以安装一个git
1.首先创建一个存放vue文件的文件夹
2.通过cmd打开(管理员权限)
3.执行vue init webpack myvue
4.然后就会创建一个名字为myvue的文件
创建的时候会有一些选择(按照提示和自己的需求来)
5.cd myvue(进入vue文件夹)
6.再执行npm install(类似于java创建maven工程(自动导包的操作))
7.npm run dev(相对于java启动tomcat) 然后ctrl+c可以停止运行
v-show和v-if
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="box">
<div v-show="isShow">我是动态显示和隐藏1号</div>
<div v-if="isActive">我是动态创建和删除2号</div>
<input @click="showAndDisplay()" type="submit" value="点击1号隐藏或显示">
<input @click="showAndDisplayTwo()" type="submit" value="点击2号隐藏或显示">
</div>
<script type="text/javascript">
let vm = new Vue({
el:"#box",
data:{
isShow:true,
isActive:true
},
methods:{
showAndDisplay:function(){
this.isShow=!this.isShow//方法可以通过this.data里面的值获取
},
showAndDisplayTwo:function () {
this.isActive=!this.isActive
}
}
});
</script>
</body>
</html>
- v-if是动态的创建,和动态的删除
- v-show是动态的显示和隐藏(display属性)
- 共同点是值都是boolean类型的(true,false)
动态绑定style
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<style>
.one{
width: 200px;
height: 100px;
border: 1px solid;
}
</style>
<body>
<div id="app">
<div class="one" :style="'background:rgb('+r+','+g+','+b+')'">
我的会变色的DIV
</div>
<input type="submit" @click="change()" value="点击切换div背景颜色"/>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data:{
r:'',
g:'',
b:''
},
methods:{
change(){
this.r=Math.floor((Math.random()*256));
this.g=Math.floor((Math.random()*256));
this.b=Math.floor((Math.random()*256));
console.log(this.r,this.g,this.b)
}
}
});
</script>
</body>
</html>
v-if and v-else-if and v-else
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="box">
<button @click="isList">click</button>
<div v-if="isCreate">动态创建和删除--11111111111111111111111</div>
<div v-else>动态创建和删除--22222222222222222222222</div>
<div v-if="isCreate">
<ul v-for="islist in isLists">
<li>{{islist}}</li>
</ul>
</div>
<div v-else>
空空如也
</div>
<h3>----------------------------------------------------------</h3>
<div v-if="type===1">1</div>
<div v-else-if="type===2">2</div>
<div v-else>5</div>
</div>
<script type="text/javascript">
let vm = new Vue({
el: "#box",
data:{
isCreate:false,
isLists:[],
type:1
},
methods:{
isList:function(){
this.isCreate=!this.isCreate;
this.isLists=['123','456','789']
}
}
});
</script>
</body>
</html>
列表渲染
- v-for(特殊v-for=”n in 10”)
- a.in
- b.of
- key:
- 跟踪每一个节点的身份,从而重用和重新排序现有元素
- 理想的key值是每一项都有一个唯一的id,data.id
数组更新检测
- 使用一下方法操作数组,可以检测变动
- push() pop() shift() unshift(0 splice() sort reverse()
- filter(),concat() 和slice(),map(),新数组替换旧数组
- 不能检测以下变动的数组
- vm.items[indexOfitem]=newValue
- 解决(1) Vue.set(example1.items,indexOfItem,newValue)
- splice
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="box">
<input type="text" @input="handleList" v-model="txt"/>
<div v-for="list in datalist">
{{list}}
</div>
</div>
<script type="text/javascript">
let vm = new Vue({
el: "#box",
data:{
txt:'',
lists:['aaa','aba','bbb','ccc','acc','abb','add','aff'],
datalist:['aaa','aba','bbb','ccc','acc','abb','add','aff']
},
methods:{
handleList(){
console.log(this.txt)
var newlist=this.lists.filter(item=>item.indexOf(this.txt)>-1)
this.datalist=newlist
}
}
});
</script>
</body>
</html>
使用计算属性做模糊查询
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="txt"/>
<div v-for="list in getMyDatalist">
{{list}}
</div>
</div>
<script type="text/javascript">
let vm = new Vue({
el: "#box",
data:{
txt:'',
datalist:['aaa','aba','bbb','ccc','acc','abb','add','aff']
},
computed:{
getMyDatalist(){
return this.datalist.filter(item=>item.indexOf(this.txt)>-1)
}
},
});
</script>
</body>
</html>
事件修饰符
- @click.self点击自己触发,点击子类不会触发
- @click.stop阻止冒泡事件
- @click.once只触发一次
- @keyup.13 按键修饰符
购物车小案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="checkbox" @change="handleChange" v-model="isAllChecked">全选
<div v-for="(data,index) in datalist">
<input :index="index" type="checkbox" v-model="checkgroup" :value="data" @change="handleLiChange" />
{{data}}
<button @click="handleDelClick(data)">-</button>
{{data.number}}
<button @click="handleAddClick(data)">+</button>
</div>
<!-- {{checkgroup}} -->
<p>总金额计算:{{getSum}}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
isAllChecked: false,
checkgroup: [],
datalist: [{
name: "商品1",
price: 10,
number: 1,
id: "1",
},
{
name: "商品2",
price: 20,
number: 1,
id: "2",
},
{
name: "商品3",
price: 30,
number: 2,
id: "3",
},
{
name: "商品4",
price: 40,
number: 1,
id: "4",
}
]
},
//计算属性性能更好一点
computed:{
getSum() {
//计算总金额
/* var sum = 0
for (var i in this.checkgroup) {
sum+=this.checkgroup[i].price*this.checkgroup[i].number
}
return sum */
//计算总金额
var sum = 0;
for (var i = 0; i < this.checkgroup.length; i++) {
sum += this.checkgroup[i].price * this.checkgroup[i].number
}
return sum
}
},
methods: {
/* getSum() {
//计算总金额
/* var sum = 0
for (var i in this.checkgroup) {
sum+=this.checkgroup[i].price*this.checkgroup[i].number
}
return sum
//计算总金额
var sum = 0;
for (var i = 0; i < this.checkgroup.length; i++) {
sum += this.checkgroup[i].price * this.checkgroup[i].number
}
return sum
}, */
//全选的按钮
handleChange() {
if (this.isAllChecked) {
this.checkgroup = this.datalist
} else {
this.checkgroup = []
}
},
//只要有一个没有被选中就取消全选
handleLiChange() {
if (this.checkgroup.length === this.datalist.length) {
this.isAllChecked = true
} else {
this.isAllChecked = false
}
},
//删除商品和减到一的时候不能出现负数
handleDelClick(data, index) {
var number = data.number--;
if (number === 1) {
/* alert("是否删除商品"); */
this.datalist.splice(index, 1);
data.number = 1;
}
},
//设置限购数
handleAddClick(data) {
var number = data.number++;
if (number === 5) {
alert("限购5件");
data.number = 5
}
}
}
});
</script>
</body>
</html>
双向数据绑定的一些特性
<input type="text" v-model.lazy="text" /><!-- 失去焦点加载一次,不会一直加载 -->
<input type="number" v-model.number="text" /><!-- 只显示数字类型的 没有什么用,直接输入字母就会失效,建议修改type属性为number -->
<input type="text" v-model.trim="text" /><!-- 去除首位空格 -->
没有捷径,多敲多练
fetch
fetch("./json/test.json").then(res=>res.json()).then(res=>{
console.log(res)
})
Axios
用来做通信(类似于ajax)
起步
- 安装环境 npm install axios 或者你也可以引入js文件
- 然后就可以使用mounted来进行数据初始化,钩子函数,mounted在整体实例中只执行一次
- 然后就可以通过data()来返回一些数据注意是data方法不是data属性
- 然后就可以获取到一些后台传递过来的数据了
上代码
<div id="vue">
<div>{{info.name}}</div>
<div>{{info.address}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
let vm= new Vue({
el:"#vue",
data() {
return {
info:{
name:null,
address:{
street:null,
city:null,
country:null
}
}
}
},
mounted(){
axios.get('./data.json').then(response=>(this.info=response.data));
}
});
</script>
小结
- 首先是环境必须要有axios的环境,用idea来编写的话记得换成ES6,因为这个是ES6的新特性
- 注意区分data和data()
计算属性
上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<p>计算属性:{{getMyName}}</p>
<p>普通方法:{{getMyNameMethod()}}</p>
<div>
也需要计算结果
<p>计算属性:{{getMyName}}</p>
<p>普通方法:{{getMyNameMethod()}}</p>
</div>
</div>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data: {
myname: "xiaoming"
},
methods: {
getMyNameMethod() {
console.log("getMyNameMethod-方法调用")
return this.myname.substring(0, 1).toUpperCase() + this.myname.substring(1)
}
},
computed: {
getMyName() {
console.log("getMyName-计算属性调用")
return this.myname.substring(0, 1).toUpperCase() + this.myname.substring(1)
}
}
});
</script>
</body>
</html>
**计算属性只会运行一次,而计算方法会运行两次
自定义主键
为什么要使用自定义组件
- 扩展html元素,封装可重用的代码
- 减少代码复用,提高代码的灵活性
- 谁用谁知道,就和玩乐高积木一样
组件编写方式与vue实例的区别
- 自定义组件需要一个root element(根组件)
- 父子组件的data是无法共享的
- 组件可以有data、methods、computed…,但是data必须是一个函数(data())
案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<navbar></navbar>
<sidebar></sidebar>
</div>
<script type="text/javascript">
//1.全局定义组件(作用域隔离)
Vue.component("navbar",{//navbar为组件名字,template为组件模板
//组件模板必须要有一个根节点
template:`
<div style="background:yellow">
<button @click="handleback()">返回</button>
navbar----{{navbarname}}
<button>主页</button>
<child></child>
<navbarchild></navbarchild>
</div>`,
methods:{
handleback(){
console.log("啊!我被点击了")
}
},
data(){
return{
navbarname:"我是名字"
}
},
//局部定义组件
components:{
navbarchild:{
template:`<div>navbarchild-只能再navbar组件中使用</div>`
}
}
})
Vue.component("child",{
template:`
<div>child组件-全局定义</div>
`
})
Vue.component("sidebar",{
template:`
<div>
sider组件
<child></child>
<navbarchild></navbarchild>/* 无法显示 */
</div>`
})
new Vue({
el:"#app",
})//root 根组件(component)
</script>
</body>
</html>
父传子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<!-- 父传子 通过属性向下传递 如果要传父组件的状态别忘了动态绑定 -->
<div id="app">
<navbar myname="home" :myshow="false"></navbar>
<navbar myname="list" :myshow="true"></navbar>
<navbar :myname="parentname" :myshow="true"></navbar>
</div>
<script type="text/javascript">
Vue.component("navbar",{
template:`
<div>
<button>返回</button>
navbar---{{myname}}
<button v-show="myshow">首页</button>
</div>
`,
//props:["myname","myshow"]//接收父组件传来的属性
//属性验证(不限制类型,null)
props:{
myname:String,
myshow:Boolean
}
})
let vm=new Vue({
el:"#app",
data:{
parentname:"父组件的状态"
}
})
</script>
</body>
</html>
父传子 通过属性传递 如果要传父组件的状态给子组件别忘了动态绑定
子传父
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<!-- 子传父 事件 向上传 -->
<div id="app">
父组件
<child @myevent="handleEvent"></child>
</div>
<script type="text/javascript">
Vue.component("child", {
template: `
<div>
child组件
<button @click="payMoney()">click</button>
</div>`,
data() {
return {
childname: "子组件状态"
}
},
methods: {
payMoney() {
this.$emit("myevent",1000) //分发事件
}
}
})
let vm = new Vue({
el: "#app",
methods: {
handleEvent(ev) {
console.log("父组件收到钱了",ev)
}
}
})
</script>
</body>
</html>
案例2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<!-- <button @click="isShow=!isShow">click</button> -->
<navbar @myevent="handleEvent"></navbar>
<sideba v-show="isShow"></sideba>
</div>
<script type="text/javascript">
//子组件
Vue.component("navbar",{
template:`
<div>
navbar
<button @click="handleClick">navbar-button</button>
</div>
`,
methods:{
handleClick(){
this.$emit("myevent")
}
}
})
Vue.component("sideba",{
template:`
<div style="background:yellow">
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
</ul>
</div>
`
})
let vm=new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
handleEvent(){
this.isShow=!this.isShow
}
}
})
</script>
</body>
</html>
ref父子通信
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" ref="mytext">
<button @click="handleAdd">add</button>
<child ref="mychild"></child>
</div>
<script type="text/javascript">
Vue.component("child",{
template:`<div>child</div>`,
data(){
return{
childname:"子组件的状态"
}
},
methods:{
add(data){
console.log("子组件的方法",data)
}
}
})
let vm=new Vue({
el:"#app",
methods:{
handleAdd(){
console.log(this.$refs.mychild.childname)
this.$refs.mychild.add("孩子听话")
console.log(this.$refs.mytext.value)
}
}
})
/**
* 1.ref放在标签上,拿到的是原生的节点
* 2.ref放到组件上,拿到的是组件对象
*/
</script>
</body>
</html>
非父子通信
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<weixinauthor></weixinauthor>
<weixinuser></weixinuser>
</div>
<script type="text/javascript">
var bus=new Vue();
Vue.component("weixinauthor",{
template:`
<div style="background:pink">
我是一个微信公众号作者
<input type="text" ref="mytext"/>
<button @click="handleClick()">发布</button>
</div>
`,
methods:{
handleClick(){
bus.$emit("weixinmassage",this.$refs.mytext.value)
}
}
})
Vue.component("weixinuser",{
template:`
<div style="background:yellow">
我是一个微信用户
</div>
`,
mounted(){
bus.$on("weixinmassage",(data)=>{
console.log("收到推送",data)
})
console.log("生命周期函数-当前组件的dom 创建完成以后 就会调用")
}
})
let vm=new Vue({
el:"#app",
})
</script>
</body>
</html>
动态组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<kepp-alive><!-- 保留状态避免重新渲染 -->
<component :is="who"></component>
</kepp-alive>
<footer>
<ul>
<li><a @click="who='home'">首页</a></li>
<li><a @click="who='list'">列表页</a></li>
<li><a @click="who='shopcar'">购物车页</a></li>
</ul>
</footer>
</div>
<script type="text/javascript">
let vm=new Vue({
el:"#app",
data:{
who:'home'
},
components:{
"home":{
template:`<div>home</div>`
},
"list":{
template:`<div>list</div>`
},
"shopcar":{
template:`<div>shopcar</div>`
}
}
})
</script>
</body>
</html>
插槽
上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
</todo>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
Vue.component("todo",{//定义插槽的名字和一些内容
template:`<div>
<slot name="todo-title"></slot>
<ul>
<slot name="todo-items"></slot>
</ul>
</div>`
});
Vue.component("todo-title",{
props:['title'],
template:`<div>{{title}}</div>`
});
Vue.component("todo-items",{
props:['item'],
template:`<li>{{item}}</li>`
});
var vm=new Vue({
el:"#app",
data:{//存储数据
title: "biaoqian",
todoItems:['java','前端','linux']
}
});
</script>
</body>
</html>
自定义事件分发
上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
:item="item" :index="index" v-on:remove="removeItems(index)"></todo-items>
</todo>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
Vue.component("todo",{
template:`<div>
<slot name="todo-title"></slot>
<ul>
<slot name="todo-items"></slot>
</ul>
</div>`
});
Vue.component("todo-title",{
props:['title'],
template:`<div>{{title}}</div>`//模板
});
Vue.component("todo-items",{
props:['item','index'],
//只能绑定当前主键的方法
template:`<li>{{item}}<button v-on:click="remove">删除</button></li>`,
methods:{
remove:function(index){
//自定义事件
this.$emit('remove',index);
}
}
});
var vm=new Vue({
el:"#app",
data:{
title: "wenbiao",
todoItems:['java','前端','linux']
},
methods:{
removeItems:function(index){
this.todoItems.splice(index,1);//一次只删除一个元素
}
}
});
</script>
</body>
</html>
以上的一些案例就Axios需要一个data.json文件,其他的都是单个文件就直接用HBuilder来写的
由于现在浏览器的版本差不多都可以使用那个ES6了,我这边就没有写webpack,到时候要是出现就是浏览器无法识别的问题,建议更新一下浏览器的版本(ie不在考虑范围之类)