Vue开发去哪网App
用到的了Vue中的知识点
Axios–Ajax数据的获取
Vue Router–做多页面之间的路由
Vuex–各个组件之间的数据共享
异步组件—代码上线,性能更优
Stylus–编写前端的样式
递归组件–实现组件自身调用自己
slider插件实现轮播图
开始!
Hello Vue
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Vue</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app1">
</div>
<div id="app">
{{content}}
</div>
<script>
var dom = document.getElementById('app1');
dom.innerHTML = "Hello Vue"
setTimeout(function () {
dom.innerHTML = 'Bye Vue'
},2000)
// 创建Vue实例
var app = new Vue({
el:'#app',// Vue实例负责管理的区域,接管id="app"的dom标签所有内容
data:{
content:'Hello Vue'
}
})
setTimeout(function () {
app.$data.content = 'Bye Vue'
},2000)
</script>
</body>
</html>
TodoList
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>TodoList</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-model 双向的数据绑定 -->
<input type="text" v-model="inputValue" />
<!-- v-on 绑定事件 -->
<button v-on:click="handleBtnClick">提交</button>
<ul>
<!--循环list数据,循环的每一项放到item里面-->
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
// list: ['一','二','三']
list: [],
inputValue: ''
},
methods: {
handleBtnClick:function () {
// alert('click')
// alert(this.inputValue)
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html>
数据的双向绑定扩展: v-model="inputValue"
使用组件化的思想修改TodoList 全局组件
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>TodoList</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-model 双向的数据绑定 -->
<input type="text" v-model="inputValue" />
<!-- v-on 绑定事件 -->
<button v-on:click="handleBtnClick">提交</button>
<ul>
<!-- 使用组件TodoItem -->
<!-- 循环list数据,list的值赋值给item,再通过v-bind的形式通过content变量传给todo-item -->
<todo-item
v-bind:content="item"
v-for="item in list">
</todo-item>
</ul>
</div>
<script>
// 创建一个全局组件,名字是TodoItem,内容是<li></li>
Vue.component("TodoItem",{
props: ['content'],// props:父组件通过 props 向下传递数据给子组件
template: "<li>{{content}}</li>"
})
var app = new Vue({
el: '#app',
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick:function () {
// alert(this.inputValue)
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html>
使用组件化的思想修改TodoList 局部组件
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>TodoList</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-model 双向的数据绑定 -->
<input type="text" v-model="inputValue" />
<!-- v-on 绑定事件 -->
<button v-on:click="handleBtnClick">提交</button>
<ul>
<!-- 使用组件TodoItem -->
<!-- 循环list数据,list的值赋值给item,再通过v-bind的形式通过content变量传给todo-item -->
<todo-item
v-bind:content="item"
v-for="item in list">
</todo-item>
</ul>
</div>
<script>
// 定义一个局部组件
var TodoItem = {
props: ['content'],
template: "<li>{{content}}</li>"
}
var app = new Vue({
el: '#app',
// 把局部组件TodoItem注册到Vue实例中,在实例中名字依然是TodoItem
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick:function () {
// alert(this.inputValue)
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html>
字组件向父组件传值 TodoList点击删除案例
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>TodoList</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-model 双向的数据绑定 -->
<input type="text" v-model="inputValue" />
<!-- v-on 绑定事件 -->
<button v-on:click="handleBtnClick">提交</button>
<ul>
<!-- 使用组件TodoItem -->
<!-- 循环list数据,list的值赋值给item,再通过v-bind的形式通过content变量传给todo-item -->
<todo-item
v-bind:content="item"
v-bind:index="index"
v-for="( item , index ) in list"
@delete="handleItemDelete" >
</todo-item>
<!-- 在父组件模板中,创建子组件的同时监听子组件删除的事件,删除事件触发的时候,执行父组件中handleItemDelete方法 -->
<!-- 向子组件中传一个下标值index,子组件中要想用index,要在props里声明index,-----父组件传过来的index就会被子组件接收 -->
<!-- v-bind v-bind:content="item" :content="item" -->
</ul>
</div>
<script>
// 定义一个局部组件
var TodoItem = {
props: ['content','index'],
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: {
handleItemClick:function () {
// alert("click")
// 数据放在父组件中,删除子组件时,点击子组件,子组件把对应的内容传给父组件,父组件去改变数据,父组件的数据改变后--->子组件改变
// 子组件向父组件传值,通过$emit方式向外触发事件
this.$emit("delete",this.index);
// 点击子组件的时候,子组件向外触发delete事件,
// 在父组件中创建子组件的同时,监听delete事件,v-on:delete @delete
// 子组件被点击的时候,1:触发delete事件,2:同时把this.index作为参数带给父组件
}
}
}
var app = new Vue({
el: '#app',
// 把局部组件TodoItem注册到Vue实例中,在实例中名字依然是TodoItem
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick:function () {
// alert(this.inputValue)
this.list.push(this.inputValue)
this.inputValue = ''
},
// 在父组件中定义handleItemDelete方法
handleItemDelete: function (index) {
// alert("delete");
// this.list = []
// 为了防止点击一下清空list,父组件向子组件传值的时候,v-band传一个index
// alert(index)
this.list.splice(index,1) // 从传过来的下标开始删除一项
}
}
})
// 父组件向子组件传值:通过v-bind的方式进行数据的传递,父组件向子组件传值的时候,子组件要接收(props)
// 子组件向父组件传值:通过$emit方式,通过向上一层触发事件,子组件触发的事件,父组件在监听,监听过后,获取到子组件带的内容,实现子组件向父组件传值
</script>
</body>
</html>
Vue实例理解
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Vue实例</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="root">
<div @click="handleClick">
{{message}}
</div>
<item></item>
</div>
<script>
// 一个Vue项目中有很多Vue实例组成,每个组件也是一个Vue实例
// 创建一个组件
Vue.component('item',{
template: '<div>Hello item</div>'
})
var vm = new Vue({
el: '#root',
data: {
message: 'Hello Vue'
},
methods: {
handleClick: function () {
alert("click")
}
}
})
</script>
</body>
</html>
Vue实例生命周期函数
到了Init Event & Lifecycle结束之后的时间点,beforeCreate就会自动的被执行
调用完beforeCreate函数,Vue会继续处理外部的注入包括双向的绑定的内容,在这部分初始化完成的时候,Vue实例的初始化基本完成
在这个时间点,created函数自动执行
判断Vue实例中是否有el:选项
判断Vue实例中是否有template:选项,
如果有 使用模板进行渲染,
如果没有 把el外层的HTML当做模板进行渲染
在页面渲染之前自动执行beforeMount生命周期函数,(模板和数据相结合,挂载到页面之前执行)
页面挂载之后,mounted函数被执行,mounted函数执行之后,页面被渲染完毕(用console.log(this.$el)验证)
当数据发生改变时,页面还没重新渲染之前,会执行beforeUpdate函数,渲染之后updated函数会被执行
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Vue实例生命周期函数</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
// Vue生命周期函数就是vue实例在某个时间点会自动执行的函数
var vm = new Vue({
el: '#app',
template:"<div>{{message}}</div>",
data: {
message: "Hello World"
},
// Vue实例生命周期函数并不放在methods对象里,单独放在Vue实例中
beforeCreate: function () {
console.log("beforeCreate")
},
created: function () {
console.log("created")
},
beforeMount: function () {
console.log(this.$el)
console.log("beforeMount")
},
mounted: function () {
console.log(this.$el)
console.log("mounted")
},
bedoreDestory: function () {
console.log("bedoreDestory")
},
destoryed: function () {
console.log("destoryed")
},
beforeUpdate: function () {
console.log("beforeUpdate")
},
updated: function () {
console.log("updated")
}
})
</script>
</body>
</html>
beforeUpdate updated函数,数据发生改变时执行
Vue模板语法
<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<title>Vue模板语法</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div>{{name + '----后面可以加js语法'}}</div>
<div v-text="name2 + '----后面可以加js语法'"></div>
<div v-html="name3 + '----后面可以加js语法'"></div>
</div>
<!-- 差值表达式和v-text作用一样,v-text输出时会进行转义,v-html不解析内容 -->
<script>
var vm = new Vue({
el: '#app',
data: {
name: "插值表达式",
name2: "v-text",
name3: "<B>v-html</B>",
}
})
</script>
</body>
</html>
Vue中的计算属性,方法和侦听器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
{{fullName}}
{{fullName1()}}
{{fullName2}}
{{age}}
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
firstName: "名字",
lastName: "姓氏",
age: 28,
fullName2: "xxx",
},
// 计算属性
computed: {
fullName: function () {
console.log("计算了一次----computed");
return this.lastName + this.firstName
}
},
// 计算属性内置缓存,
// 这个计算属性fullName有两个依赖变量,依赖的变量不发生改变时,计算属性不重新计算,使用上一次计算的结果。
// 比如修改vm.age = "27" 重新渲染页面,fullName没有重新计算,修改lastName或irstName,计算属性重新计算一次。
// 使用方法编写代码不如计算属性有效
// 修改vm.age = "27" 重新渲染页面,fullName1方法重新执行一次,内部没有缓存机制
methods: {
fullName1: function () {
console.log("计算了一次----methods");
return this.lastName + this.firstName;
},
},
// watch侦听器实现
watch: {
//侦听lastName和firstName的改变
firstName: function () {
console.log("计算了一次----watch");
this.fullName2 = this.lastName + this.firstName;
},
lastName: function () {
console.log("计算了一次----watch");
this.fullName2 = this.lastName + this.firstName;
},
}
//watch和computed都具备缓存的机制,computed语法简单,推荐优先使用
})
</script>
</body>
</html>
计算属性的setter和getter
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
{{fullName}}
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
firstName: "名字",
lastName: "姓氏",
},
// 计算属性
// computed: {
// fullName: function () {
// return this.lastName + this.firstName
// },
// },
// 计算属性的另一种写法
computed: {
fullName: {
get: function () {
return this.lastName + this.firstName
},// 调用差值表达式读取计算属性的内容时,使用get这个方法
set: function (value) {
// console.log(value)
var arr = value.split(" ");
this.firstName = arr[0];
this.lastName = arr[1];
},// set方法会接收到外部传过来的一个设置的value,比如vm.fullName = "xxxx"
// 当computed依赖的值发生改变时,计算属性重新计算
}
}
})
</script>
</body>
</html>
Vue中样式的绑定 class的对象绑定 点击切换颜色
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<!-- 第一种实现样式和数据绑定的方案:借助class和对象的形式----class的对象绑定 -->
<!-- class的对象绑定, div元素上有个class,class的名字是activated,class显示不显示取决于数据里isActivated变量-->
<div id="app">
<div @click="handleDivClick"
:class="{activated: isActivated}" >
Hello World
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
isActivated: false
},// isActivated 默认值为false,默认class不显示
methods: {
handleDivClick: function () {
// this.isActivated = true
this.isActivated = !this.isActivated;// 取反
}
}
})
</script>
</body>
</html>
Vue中样式的绑定 class和数组绑定
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<!-- 第二种实现样式和数据绑定的方案:借助class和数组的形式 -->
<div id="app">
<div @click="handleDivClick"
:class="[activated]" >
Hello World
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
activated: ""
},// activated初始为空
methods: {
handleDivClick: function () {
if (this.activated === "activated") {
this.activated = ""
}else {
this.activated = "activated"
}// 三元表达式 this.activated = this.activated === "activated" ? "" : "activated"
}
},
})
</script>
</body>
</html>
Vue中样式的绑定 class和style绑定
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div :style="styleObj" @click="handleDivClick">
Hello World
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
styleObj: {
color: "black"
},
},
methods: {
handleDivClick: function () {
this.styleObj.color = this.styleObj.color === "black" ? "red" : "black";
}
},
})
</script>
</body>
</html>
:style=“styleObj” 对象方式绑定
:style="[styleObj]" 数组方式绑定
Vue中的条件渲染
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<!--
v-if和v-show都能够控制模板标签是否在页面上显示
v-if对应的变量值如果是flase,v-if就不存在dom上,v-if每次隐藏显示dom,相当于删除dom再增加dom
而v-show对应的js表达式值为flase,这个标签对应的dom在页面上依然存在,展示形式为display : none <div style"display : none;"> </div>
在经常进行改变dom元素进行隐藏显示操作时,使用v-show性能更高
v-if可以和v-else嵌套使用
-->
<div id="app">
<div v-if="show">{{message}}</div>
<div v-show="show">{{message}}</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
show: false,
message: "Hello World",
},
})
</script>
</body>
</html>
Vue中的列表渲染