1. 计算属性
1.1. 计算属性的本质
在想要计算数据结果时,可以使用computed代替method或者 其他方法计算,结果可以直接使用mastache进行展示 ``
<div id="app">
<h2> </h2>
<h2></h2>
<h2></h2>
<h2></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
firstName: 'kobe',
lastName: 'James'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
1.2. 计算属性和methods对比
computed相比method可以进行数据缓存,在计算结果不改变的情况下,不会进行多次计算
-
在computed中计算,将结果通过``显示出来
<div id="app"> <h2>总价格: </h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { books: [ {id: 100, name: '计算机发展', price: 102}, {id: 101, name: 'Unix操作系统详解', price: 122}, {id: 102, name: '高性能WEB架构', price: 103}, {id: 103, name: 'Python 高级编程', price: 84}, {id: 104, name: 'JavaScript 从入门到高级', price: 110} ] }, computed: { totalPrice: function () { return this.books.reduce(function (total, n) { return total + n.price; }, 0) }, } }); </script>
-
computed 中的get方法和set方法,默认是get方法
<div id="app"> <h2></h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { firstName: 'Kobe', lastName: 'Bryant' }, computed:{ // 计算属性一般没有set方法,只读属性 fullName: { // set 方法 set: function(newName){ const name = newName.split(' '); this.firstName = name[0] ; this.lastName = name[1]; }, // get方法 get: function () { return this.firstName + ' ' + this.lastName } } // 简写: // fullName: function () { // return this.firstName + ' ' + this.lastName // } } }) </script>
-
computed 和 mehtods 对比
<div id="app"> <!-- 第一种方法 特点: 过于繁琐--> <h2> </h2> <!-- 第二种方法,通过methods,特点: 每次调用都会重新直行方法--> <h2></h2> <!-- 第三种方法,通过computed, 特点: 在值不改变的情况下,只直行一次方法--> <h2></h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { firstName: 'Kobe', lastName: 'Bryant' }, methods: { getFullName() { console.log("fullname"); return this.firstName + ' ' + this.lastName; } }, computed: { fullName: function () { // console.log("fullname"); return this.firstName + ' ' + this.lastName; } } }) </script>
2. 事件监听
2.1. 事件监听的基本使用
<div id="app">
<h2>8</h2>
<!-- v-on 监听事件,@为v-on的语法糖-->
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
increment() {
this.count++
},
decrement() {
this.count--
}
}
})
</script>
2.2. 参数问题
<div id="app">
<!-- 不需要传参数的情况下,可以不加括号-->
<button @click="clickFunc1">按钮1</button>
<!-- 需要传参数的情况下,不加括号,默认会把evevt传入到函数中-->
<button @click="clickFunc2">按钮2</button>
<!-- 在传入多个参数的情况下,如果少传入一个参数,没有值的参数会默认为undefined-->
<button @click="clickFunc3(1,2)">按钮3</button>
<!--如果要指定传入event事件数据,参数为$event-->
<button @click="clickFUnc4(1,3,$event)">按钮4</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
clickFunc1(){
console.log('clickFunc');
},
clickFunc2(arg){
console.log(arg);
},
clickFunc3(arg1,arg2,arg3){
console.log(arg1, arg2, arg3);
},
clickFUnc4(arg1,arg2,arg3){
console.log(arg1, arg2, arg3);
}
}
})
</script>
2.3. 装饰符
<div id="app">
<!-- 1. stop 修饰符的使用-->
<!-- 如果不加stop修饰符,点击按钮1 的时候,也会调用div的click事件方法 -->
<div @click="divClick">
<p>this is div</p>
<button @click.stop="btnClick"> 按钮1</button>
</div>
<!-- 2. prevent装饰符的使用-->
<!-- 阻止其他动作-->
<div>
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
</div>
<!-- 3. 监听键盘输入动作-->
<div>
<input type="text" @keyup.enter="keyup">
</div>
<!-- 4. once 只触发一次-->
<div>
<button @click.once="onceClick">once 按钮</button>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
divClick(){
console.log('divClick');
},
btnClick(){
console.log('btnClick');
},
submitClick(){
console.log('submitClick');
},
keyup(){
console.log('keyup');
},
onceClick(){
console.log('onceClick');
}
}
})
</script>
3. 条件判断
3.1. v-if/v-else-if/v-else
<div id="app">
<button @click="clickFun">点击测试</button>
<div v-if="isActive">
<p>这是测试内容</p>
<p></p>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
isActive: false
},
methods:{
clickFun(){
// console.log(this.isActive = !this.isActive);
return this.isActive = !this.isActive;
}
}
})
</script>
3.2. 案例
-
案例1:
<div id="app"> <button @click="clickFun">点击测试</button> <div v-if="isActive"> <p>这是测试内容</p> <p>这是测试内容</p> <p>这是测试内容</p> <p>这是测试内容</p> <p>这是测试内容</p> <p></p> </div> <h1 v-else> 当v-if为false时显示我 </h1> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: ' 你好!', isActive: false }, methods:{ clickFun(){ // console.log(this.isActive = !this.isActive); return this.isActive = !this.isActive; } } }) </script>
-
案例2:
<div id="app"> <h2 v-if="score > 90">优秀</h2> <h2 v-else-if="score > 80">优秀</h2> <h2 v-else-if="score > 60">及格</h2> <h2 v-else>不及格</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { score: 90 }, }) </script>
-
案例3:
<div id="app"> <span v-if="isEmail"> <label for="email">邮箱登陆</label> <input type="text" placeholder="输入邮箱地址" id="email" key="email"> </span> <span v-else> <label for="username">用户登陆</label> <input type="text" placeholder="输入用户名" id="username" key="username"> </span> <button @click="isEmail = !isEmail">切换</button> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { isEmail: false }, methods: { changeBtn(){ return this.isEmail = !this.isEmail; } } }) </script>
3.3. v-show
-
v-show 与 v-if 的区别
<div id="app"> <!-- v-if: 当条件为false时, 包含v-if的指令元素不在DOM中 --> <h2 v-if="isShow" id="if"></h2> <!-- v-show: 当条件为false时, v-show只是给元素添加一个行内样式: display: none --> <h2 v-show="isShow" id="show"></h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: ' 你好!', isShow: true } }) </script>
4. 循环遍历
4.1. 遍历数组
<div id="app">
<!-- 第一种情况,没有引用索引值-->
<ul>
<li v-for="item in names"></li>
</ul>
<!-- 第二种情况,引用索引值-->
<ul>
<li v-for="(item,index) in names">
.
</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
names: ['why', 'kobe', 'james', 'curry']
}
})
</script>
4.2. 遍历对象
<div id="app">
<!-- 第一种情况,如果只是一个值,会显示value-->
<ul>
<li v-for="item in info"></li>
</ul>
<!-- 第二种情况,获取key、value 格式: (value,key)-->
<ul>
<li v-for="(value,key) in info"> - </li>
</ul>
<!-- 第三种情况,获取index-->
<ul>
<li v-for="(value,key,index) in info"> - - </li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'why',
age: '18',
height: 1.88
}
}
})
</script>
-
在使用过程中添加
key
<div id="app"> <button @click="addBtn">插入项目</button> <!-- v-for 中绑定key,在做增减项目中,可以提高页面渲染效率--> <ul> <li v-for="item in letters" :key="item"></li> </ul> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { letters: ['A','B','C','D','E'] }, methods: { addBtn(){ this.letters.splice(2,0,'F') } } }) </script>
4.3. 数组哪些方法是响应式
<div id="app">
<button @click="clickBtn">Button</button>
<ul>
<li v-for="item in letters"></li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A','B','C','D','E']
},
methods: {
clickBtn(){
// 1. push(...items: T[]): number; : 在尾部追加元素, 参数可以是多个
// this.letters.push('aaa','bbb')
// 2. pop(): T | undefined; : 弹出尾部元素
// let data = this.letters.pop();
// console.log(data);
// 3. shift(): T | undefined; : 弹出顶部元素
// let data = this.letters.shift();
// console.log(data);
// 4. unshift(...items: T[]): number; : 在顶部插入元素
// this.letters.unshift('a','b','c')
// 5. splice(start: number, deleteCount: number, ...items: T[]): T[];
// 删除功能 splice(起始位置,删除数量)
// this.letters.splice(1,2)
// 替换功能 splice(起始位置,删除数量,替换内容...)
// this.letters.splice(1,2,'a','b')
// 插入功能 splice(插入位置,删除数量,替换内容)
// this.letters.splice(1,0,'a')
// 6. sort 排序
// this.letters.sort()
// 7. reverse 反序
// this.letters.reverse()
// 非响应式方式:直接修改数组中某个值,页面不会更改
// this.letters[0] = 'bbaa' <-- 不会更改
// this.letters.splice(0,1,'bbaa') <-- 会更改
// Vue内部实现方法
// Vue.set(this.letters,0,'bbaa') <-- 会更改
}
}
})
</script>
4.4. 作业完成
<div id="app">
<ul>
<li v-for="(m,index) in movies" :class="{active: currentIndex === index}" @click="liClick(index)" :key="m"></li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies: ['海贼王','柯南','火影忍者','死神'],
currentIndex: 0
},
methods: {
liClick(index){
this.currentIndex = index
}
}
})
</script>
5. 书籍购物案例
-
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="app"> <div v-if="books.length === 0"> 购物车为空 </div> <div v-else> <table> <thead> <tr> <th></th> <th>书籍名称</th> <th>出版日期</th> <th>价格</th> <th>购买数量</th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="(book,index) in books"> <td></td> <td></td> <td></td> <td></td> <td> <button @click="decrement(index)" :disabled="book.count === 1">-</button> <button @click="increment(index)">+</button> </td> <td> <button @click="removeClick(index)">移除</button> </td> </tr> </tbody> </table> <h2>总价: </h2> </div> </div> <script src="../js/vue.js" type="application/javascript"></script> <script src="main.js" type="application/javascript"></script> </body> </html>
-
main.js
const app = new Vue({ el: "#app", data: { books: [ { id: 1, name: '《算法导论》', date: '2006-9', price: 85.00, count: 1 }, { id: 2, name: '《UNIX编程艺术》', date: '2006-2', price: 59.00, count: 1 }, { id: 3, name: '《高性能WEB架构设计》', date: '2001-2', price: 88.00, count: 1 }, { id: 4, name: '《代码大全》', date: '2016-2', price: 102.00, count: 1 } ] }, filters: { toRMB(price) { return '¥ ' + price.toFixed(2) } }, methods: { increment(index) { this.books[index].count++ }, decrement(index) { this.books[index].count-- }, removeClick(index) { this.books.splice(index, 1) } }, computed: { totalPrice() { // let price = 0; // 方法1 // for(let p of this.books){ // price += p.price * p.count // } // 方法2 // for (let i in this.books) { // price += this.books[i].price * this.books[i].count // } // 方法3 // for ( let i =0; i<this.books.length ; i++){ // price += this.books[i].price * this.books[i].count // } // 方法4 // let price = this.books.reduce(function (preNum,book) { // return preNum + book.price * book.count // },0); // 方法5 return this.books.reduce((total, book) => total += book.price * book.count, 0); } } });
-
style.css:
table { border: 1px solid #010101; width: 90%; } table th{ border: 1px solid #fbdfff; } table td{ border: 1px solid #fbdfff; }
5.1. 高阶函数使用
//原始数据
data = [1, 2, 3, 4, 5];
console.log(data);
// let d = data.map(n => n*2).filter(n => n>5).reduce((pre,n) => pre+n,0)
// 将data中每个元素乘以2
// 1. map()
let newData = data.map(function (n) {
return n * 2
});
// console.log(newData);
// 将newData中小于5的过滤掉
// 2. filter()
let newData2 = newData.filter(function (n) {
return n >= 5
});
// console.log(newData2);
// 将newData数据汇总
let total = 0
total = newData2.reduce(function (preNum, n) {
return preNum + n;
}, 0);
// console.log(total);
6. v-model的使用
6.1. v-model 基本使用
<div id="app">
<!-- v-model是双向绑定,当input值改变后,message也会改变-->
<label>
<input type="text" v-model="message">
</label>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!'
}
})
</script>
6.2. v-model 原理
<div id="app">
<!-- v-model 默认状态-->
<!-- <input type="text" v-model="message">-->
<!-- <input type="text" :value="message" @input="getInput">-->
<input type="text" :value="message" @input="message = $event.target.value">
<h2></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好!'
},
methods:{
getInput(event){
this.message = event.target.value;
}
}
})
</script>
6.3. v-model 与radio/checkbox/select结合使用
-
radio
<div id="app"> <label for="male"> <input type="radio" id="male" value="男" name="男" v-model="sex">男 </label> <label for="female"> <input type="radio" id="female" value="女" name="女" v-model="sex">女 </label> <h2>您选择的是: </h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { sex : '' } }) </script>
-
checkbox
<div id="app"> <!-- 单选框--> <h2>协议</h2> <p>内容</p> <p>内容</p> <p>内容</p> <label for="agree"> 是否同意本协议 <input type="checkbox" id="agree" v-model="isAgree"> 同意 </label> <button :disabled="!isAgree">下一步</button> <!-- 复选框--> <h2>请选择您的爱好:</h2> <label for="bb"> <input type="checkbox" id="bb" value="篮球" v-model="hobbies"> 篮球 </label> <input type="checkbox" value="足球" v-model="hobbies">足球 <input type="checkbox" value="台球" v-model="hobbies">台球 <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球 <p>您的爱好有: </p> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: ' 你好', isAgree: false, //单选 hobbies: [] //多选 } }) </script>
-
select
<div id="app"> <!-- 1. 单选--> <select name="fruit" v-model="fruit"> <option value="苹果">苹果</option> <option value="香蕉">香蕉</option> <option value="榴莲">榴莲</option> <option value="葡萄">葡萄</option> </select> <h2>您选择的水果是: </h2> <!-- 2. 多选--> <select name="fruit" v-model="fruits" multiple> <option value="苹果">苹果</option> <option value="香蕉">香蕉</option> <option value="榴莲">榴莲</option> <option value="葡萄">葡萄</option> </select> <h2>您选择的水果是: </h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: ' 你好!', fruit: '', fruits: [] } }) </script>
6.4. v-model 装饰符的使用
<div id="app">
<!-- 1. 装饰符: lazy 等待失去焦点或有回车输入才触发-->
验证码: <input type="text" v-model.lazy="message" :class="{red: message != code}">
<br>
<!-- 2. 装饰符: number 将输入内容转换为int类型-->
<input type="number" v-model.number="age">
<h2> --- </h2>
<!-- 3. 修饰符: trim 自动去除文本两端空格-->
<input type="text" v-model.trim="name">
<h2>名字: <<</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '',
code : 'kl23',
age: 0,
name:''
}
})
</script>
7. 组件化开发
7.1. 基础知识
<div id="app">
<!-- 3. 使用组件-->
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
// 1. 创建组建构造器
const cpnC = Vue.extend({
template: `
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈哈哈</p>
<p>我是内容,呵呵呵呵</p>
`
});
// 2. 注册组件
Vue.component('my-cpn', cpnC);
const app = new Vue({
el: '#app',
data: {
message: ' 你好!'
}
})
</script>
7.2. 全局组件&局部组件
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<div id="app2">
<!-- <cpn></cpn>-->
</div>
<script src="../js/vue.js"></script>
<script>
const cpnC = Vue.extend({
template: `
<div><h2>我是标题</h2><p>我是内容。。。。。。</p></div>
`
});
//全局组件,可以在任何一个局部组件使用
// Vue.component('cpn',cpnC);
const app = new Vue({
el: '#app',
components: {cpn: cpnC} // 局部注册
});
const app2 = new Vue({
el: "#app2"
})
</script>
7.3. 父组件&子组件
<div id="app">
<cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
// 1. 创建第一个组件构造: 子组件
const cpnC1 = Vue.extend({
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容,哈哈哈哈</p>
</div>
`
});
// 2. 创建第二个组 件构造 : 父组件
const cpnC2 = Vue.extend({
template: `
<div><h2>我是标题2</h2><p>我是内容,呵呵呵呵</p></div>
<cpn1></cpn1>
`,
components: {
cpn1: cpnC1
}
});
const app = new Vue({
el: '#app',
components: {
cpn: cpnC1,
}
})
</script>
7.5. 组件注册语法糖
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
<cpn3></cpn3>
</div>
<script src="../js/vue.js"></script>
<script>
// 1. 全局组件 普通方式
const cpn1 = Vue.extend({
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容,哈哈哈哈</p>
</div>`
});
Vue.component('cpn1', cpn1);
// 2. 语法糖方式
Vue.component('cpn2', {
template: `
<div>
<h2>我是标题2</h2>
<p>我是内容,哈哈哈哈</p>
</div>`
});
// 3. 局部组件 语法糖方式
const app = new Vue({
el: '#app',
data: {
message: ' 你好!'
},
components: {
cpn3: {
template: `
<div>
<h2>我是标题3</h2>
<p>我是内容,哈哈哈哈</p>
</div>`
}
}
})
</script>
7.6. 模板的分离写法
<div id="app">
<cpn></cpn>
<cpn2></cpn2>
</div>
<!--第一种方法,使用script标签, 类型为 "text/x-template"-->
<script type="text/x-template" id="cpn">
<div>
<h2>我是标题1</h2>
<p>我是内容,哈哈哈哈</p>
<p>我是内容,哈哈哈哈</p>
</div>
</script>
<!--第二种写法, 使用template标签-->
<template id="cpn2">
<div>
<h2>我是标题2</h2>
<p>我是内容,哈哈哈哈</p>
<p>我是内容,哈哈哈哈</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//全局注册
Vue.component('cpn', {
template: "#cpn"
});
const app = new Vue({
el: '#app',
data: {
message: ' 你好!'
},
//局部注册
components: {
cpn2: {template: "#cpn2"}
}
})
</script>
7.7. 数据的存放方法
<div id="app">
<cpn></cpn>
</div>
<!--模板中使用数据,需要指定data方法-->
<template id="cpn">
<div>
<h2></h2>
<p><section class="collection-head small geopattern" data-pattern-id="Vue 学习记录01: 基础知">
<div class="container">
<div class="columns">
<div class="column three-fourths">
<div class="collection-title">
<h1 class="collection-header">Vue 学习记录01: 基础知识</h1>
<div class="collection-info">
<span class="meta-info">
<span class="octicon octicon-calendar"></span> 2019/11/06
</span>
<span class="meta-info">
<span class="octicon octicon-file-directory"></span>
<a href="https://larryzl.github.io/categories/#Vuejs" title="Vuejs">Vuejs</a>
</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- / .banner -->
<section class="container content">
<div class="columns">
<div class="column three-fourths" >
<article class="article-content markdown-body">
<ul id="markdown-toc">
<li><a href="#1-认识vuejs" id="markdown-toc-1-认识vuejs">1. 认识Vuejs</a> <ul>
<li><a href="#11-vuejs基础" id="markdown-toc-11-vuejs基础">1.1. Vuejs基础</a></li>
<li><a href="#12-安装vue" id="markdown-toc-12-安装vue">1.2 安装Vue</a></li>
<li><a href="#13-vue初体验" id="markdown-toc-13-vue初体验">1.3 Vue初体验</a></li>
<li><a href="#14-vue中的mvvm" id="markdown-toc-14-vue中的mvvm">1.4 Vue中的MVVM</a></li>
<li><a href="#15-创建vue时opthons-可以放哪些东西" id="markdown-toc-15-创建vue时opthons-可以放哪些东西">1.5 创建Vue时,opthons 可以放哪些东西</a></li>
</ul>
</li>
<li><a href="#2-插值语法" id="markdown-toc-2-插值语法">2. 插值语法</a></li>
<li><a href="#3-动态绑定属性-v-bind" id="markdown-toc-3-动态绑定属性-v-bind">3. 动态绑定属性 v-bind</a> <ul>
<li><a href="#31-v-bind-基本属性" id="markdown-toc-31-v-bind-基本属性">3.1. v-bind 基本属性</a></li>
<li><a href="#32-v-bind-动态绑定class" id="markdown-toc-32-v-bind-动态绑定class">3.2. v-bind 动态绑定class</a></li>
<li><a href="#33-v-bind-绑定style" id="markdown-toc-33-v-bind-绑定style">3.3. v-bind 绑定style</a></li>
</ul>
</li>
<li><a href="#4-计算属性" id="markdown-toc-4-计算属性">4. 计算属性</a></li>
</ul>
<h2 id="1-认识vuejs">1. 认识Vuejs</h2>
<h3 id="11-vuejs基础">1.1. Vuejs基础</h3>
<ol>
<li>Vue特点</li>
<li>Vue渐进式</li>
</ol>
<h3 id="12-安装vue">1.2 安装Vue</h3>
<ol>
<li>
<p>CDN 引入</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
</code></pre></div> </div>
</li>
<li>
<p>下载引入</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <script src="../js/vue.js"></script>
</code></pre></div> </div>
</li>
<li>
<p>npm安装</p>
</li>
</ol>
<h3 id="13-vue初体验">1.3 Vue初体验</h3>
<ol>
<li>
<p>Hello Vuejs</p>
<ul>
<li>
<p>mustache 语法 -> 体验vue响应式</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <body>
<h2></h2>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data:{
message:'hello world'
}
})
</script>
</body>
</code></pre></div> </div>
</li>
</ul>
</li>
<li>
<p>Vue 列表展示</p>
<ul>
<li>
<p>v-for</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <body>
<div id="app" >
<ul>
<li v-for="item in movies"></li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
movies: ['海王','少年派','大话西游','盗梦空间']
}
})
</script>
</body>
</code></pre></div> </div>
</li>
<li>
<p>给数组追加元素时,新的元素也可以渲染出来</p>
</li>
</ul>
</li>
<li>
<p>Vue计数器小案例</p>
<ul>
<li>
<p>事件监听:v-on:click -> methods</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <body>
<div id="app">
<h2>当前计数: </h2>
<!-- <button v-on:click="counter++">+</button>-->
<!-- <button v-on:click="counter&#45;&#45;">-</button>-->
<button v-on:click="add">+</button>
<button @click="sub">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
add: function( ){
this.counter++;
},
sub: function () {
this.counter--;
}
}
})
</script>
</body>
</code></pre></div> </div>
</li>
</ul>
</li>
</ol>
<h3 id="14-vue中的mvvm">1.4 Vue中的MVVM</h3>
<h3 id="15-创建vue时opthons-可以放哪些东西">1.5 创建Vue时,opthons 可以放哪些东西</h3>
<ol>
<li>el:</li>
<li>data:</li>
<li>methods:</li>
<li>生命周期</li>
</ol>
<h2 id="2-插值语法">2. 插值语法</h2>
<ol>
<li>
<p>mustache 语法</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app" >
<h2></h2>
<h2></h2>
<h2></h2>
<h2></h2>
<h2> </h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message : 'hello',
firstName: 'kobe',
lastName: 'bryant'
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>v-once</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app" >
<h2></h2>
<h2 v-once></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message : 'hello'
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>v-html</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app" >
<h2></h2>
<h2 v-html="url"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message : 'hello',
url: '<a href="http://www.baidu.com">百度一下<a/>'
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>v-text</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app" >
<h2>,李银河</h2>
<h2 v-test="message">,李银河</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message : 'hello'
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>v-pre:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app" >
<h2></h2>
<h2 v-pre></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message : 'hello'
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>v-cloak: 斗篷</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
</div>
<script src="../js/vue.js"></script>
<script>
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
message : 'hello'
}
})
},1000)
</script>
</body>
</code></pre></div> </div>
</li>
</ol>
<h2 id="3-动态绑定属性-v-bind">3. 动态绑定属性 v-bind</h2>
<h3 id="31-v-bind-基本属性">3.1. v-bind 基本属性</h3>
<ol>
<li>v-bind:src</li>
<li>
<p>:href</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app" >
<h2></h2>
<a v-bind:href="url">百度一下</a>
<a :href="url">百度一下</a>
<img v-bind:src="imgUrl" alt="">
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
url : 'http://www.baidu.com',
imgUrl: 'http://img2.imgtn.bdimg.com/it/u=745008878,2424441072&fm=26&gp=0.jpg'
}
})
</script>
</code></pre></div> </div>
</li>
</ol>
<h3 id="32-v-bind-动态绑定class">3.2. v-bind 动态绑定class</h3>
<ol>
<li>
<p>对象语法: :class=’{类名:boolean}’</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app">
<h2 v-bind:class="{active: isActive , line: isLine}"></h2>
<h2 v-bind:class="getClasses()"></h2>
<button v-on:click="btnClick">click</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
isActive: true,
isLine: true
},
methods:{
btnClick: function () {
this.isActive = !this.isActive;
},
getClasses: function () {
return {active: this.isActive , line: this.isLine}
}
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>数组语法</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app">
<h2 :class="['active','line']"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!'
}
})
</script>
</code></pre></div> </div>
</li>
</ol>
<h3 id="33-v-bind-绑定style">3.3. v-bind 绑定style</h3>
<ol>
<li>
<p>对象语法</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app">
<h2 v-bind:style="{'font-size': '50px',background: 'red'}"></h2>
<h2 :style="{fontSize: finalFont + 'px' , background: finalColor}"></h2>
<h2 :style="getStyle()"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
finalFont: 100,
finalColor: 'red'
},
methods: {
getStyle: function () {
return {fontSize: this.finalFont + 'px' , background: this.finalColor}
}
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>数组语法</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app">
<h2 v-bind:style="[fontSize,backgroudColor]"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
fontSize: {fontSize: '30px'},
backgroudColor: {background: 'red'}
},
})
</script>
</code></pre></div> </div>
</li>
</ol>
<h2 id="4-计算属性">4. 计算属性</h2>
<ol>
<li>
<p>案例一: firstName + lastName</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <div id="app">
<h2> </h2>
<h2></h2>
<h2></h2>
<h2></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ' 你好!',
firstName: 'kobe',
lastName: 'James'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</code></pre></div> </div>
</li>
<li>
<p>案例二: books -> price</p>
</li>
</ol>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><div id="app">
<h2>总价格: </h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
books: [
{id: 100, name: '计算机发展', price: 102},
{id: 101, name: 'Unix操作系统详解', price: 122},
{id: 102, name: '高性能WEB架构', price: 103},
{id: 103, name: 'Python 高级编程', price: 84},
{id: 104, name: 'JavaScript 从入门到高级', price: 110}
]
},
computed: {
totalPrice: function () {
let result = 0;
for(let i=0;i < this.books.length; i++){
result += this.books[i].price;
}
for(let i in this.books){
console.log(i);
}
for(let book of this.books){
console.log(book.price)
}
return result;
},
}
})
</script>
</code></pre></div></div>
</article>
<div class="share">
<div class="share-component"></div>
</div>
<div class="comment">
</div>
</div>
<div class="column one-fourth">
<h3>Search</h3>
<div id="site_search">
<input type="text" id="search_box" placeholder="Search">
</div>
<ul id="search_results"></ul>
<link rel="stylesheet" type="text/css" href="https://larryzl.github.io/assets/css/modules/sidebar-search.css">
<script src="https://larryzl.github.io/assets/js/simple-jekyll-search.min.js"></script>
<script src="https://larryzl.github.io/assets/js/search.js"></script>
<script type="text/javascript">
SimpleJekyllSearch({
searchInput: document.getElementById('search_box'),
resultsContainer: document.getElementById('search_results'),
json: 'https://larryzl.github.io/assets/search_data.json',
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
exclude: ['Welcome']
})
</script>
<h3 class="post-directory-title mobile-hidden">Table of Contents</h3>
<div id="post-directory-module" class="mobile-hidden">
<section class="post-directory">
<!-- Links that trigger the jumping -->
<!-- Added by javascript below -->
<dl></dl>
</section>
</div>
<script src="https://larryzl.github.io/assets/js/jquery.toc.js"></script>
</div>
</div>
</section>
<!-- /section.content -->
</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
Vue.component('cpn', {
template: "#cpn",
data() {
return {
'title': '我是标题',
'content': '我是内容'
}
}
});
const app = new Vue({
el: '#app',
data: {
message: ' 你好!'
}
})
</script>
-
组件中的data为什么是个函数
<div id="app"> <!-- 如果data不是一个函数,在多次调用cpn时,所有计数器的数值会相互影响--> <cpn></cpn> <cpn></cpn> ------------------- <cpn1></cpn1> <cpn1></cpn1> </div> <template id="cpn"> <div> <h2>计数器0: </h2> <button @click="decrement">-</button> <button @click="increment">+</button> </div> </template> <template id="cpn1"> <div> <h2>计数器1: </h2> <button @click="decrement">-</button> <button @click="increment">+</button> </div> </template> <script src="../js/vue.js"></script> <script> Vue.component('cpn',{ template: '#cpn', data(){ return {counter:0}; }, methods:{ increment(){ this.counter++; }, decrement(){ this.counter--; } } }); //-下面模拟不实用函数方法的结果,多个组件会相互影响 const obj = { counter: 0 }; Vue.component('cpn1',{ template: '#cpn1', data(){ return obj; }, methods:{ increment(){ this.counter++; }, decrement(){ this.counter--; } } }); const app = new Vue({ el: '#app', data: { message: ' 你好!' } }) </script>
7.8. 父子组件的通信
-
父传子: 通过
props
向子组件传递数据<div id="app"> <cpn :ctitle="title" :cmovies="movies"></cpn> </div> <template id="cpn"> <div> <h2></h2> <ul> <li v-for="(item,index) in cmovies"> - </li> </ul> </div> </template> <script src="../js/vue.js"></script> <script> // 父组件 const app = new Vue({ el: '#app', data: { movies: ['海贼王', '火影忍者', '神奇女侠', '蝙蝠侠'], title: '电影列表' }, // 子组件 components: { cpn: { template: '#cpn', props: { ctitle: { type: String, default: '电影分类' }, cmovies: { type: Array, default: function () { return ['疯狂动物城', '冰雪奇缘'] } } } } } }) </script>
-
子传父: 通过
$emit
向父组件传递数据<div id="app"> <!-- 根据emit传输的名称绑定itemclick,itemClick为父组件methods中的方法名称, itemClick 不写参数,默认会把itemclick参数传递过去--> <cpn @itemclick="itemClick"></cpn> </div> <template id="cpn"> <div> <button v-for="item in categories" @click="btnClick(item)"></button> </div> </template> <script src="../js/vue.js"></script> <script> const cpn = { template: "#cpn", data() { return { categories: [ {id: 'aa', 'name': '爆款推荐'}, {id: 'aa', 'name': '电脑主机'}, {id: 'aa', 'name': '家具服饰'}, {id: 'aa', 'name': '手机数码'} ] } }, methods: { btnClick(item) { // 通过$emit 向父组件 传输数据 (名称,数据) this.$emit('itemclick', item) } } }; const app = new Vue({ el: '#app', data: { message: ' 你好!' }, components: { cpn }, methods: { itemClick(item) { console.log(item) } } }) </script>