Vue 学习记录02 基础进阶

2019/11/08 Vuejs

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> &lt;script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"&gt;&lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>下载引入</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
</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 语法 -&gt; 体验vue响应式</p>

        <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  &lt;body&gt;
  &lt;h2&gt;&lt;/h2&gt;
		
  &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
  &lt;script&gt;
    const app = new Vue({
      el: '#app',
        data:{
        message:'hello world'
        }
    })
  &lt;/script&gt;
		
  &lt;/body&gt;
</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>  &lt;body&gt;
  &lt;div id="app" &gt;
      &lt;ul&gt;
          &lt;li v-for="item in movies"&gt;&lt;/li&gt;
      &lt;/ul&gt;
		    
  &lt;/div&gt;
		
  &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
  &lt;script&gt;
      const app = new Vue({
          el: '#app',
          data: {
              message: ' 你好!',
              movies: ['海王','少年派','大话西游','盗梦空间']
		
          }
      })
  &lt;/script&gt;
  &lt;/body&gt;
</code></pre></div>        </div>
      </li>
      <li>
        <p>给数组追加元素时,新的元素也可以渲染出来</p>
      </li>
    </ul>
  </li>
  <li>
    <p>Vue计数器小案例</p>

    <ul>
      <li>
        <p>事件监听:v-on:click -&gt; methods</p>

        <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  &lt;body&gt;
  &lt;div id="app"&gt;
      &lt;h2&gt;当前计数: &lt;/h2&gt;
  &lt;!--    &lt;button v-on:click="counter++"&gt;+&lt;/button&gt;--&gt;
  &lt;!--    &lt;button v-on:click="counter&amp;#45;&amp;#45;"&gt;-&lt;/button&gt;--&gt;
      &lt;button v-on:click="add"&gt;+&lt;/button&gt;
      &lt;button @click="sub"&gt;-&lt;/button&gt;
  &lt;/div&gt;
		
  &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
  &lt;script&gt;
      const app = new Vue({
          el: '#app',
          data: {
              counter: 0
          },
           methods: {
              add: function( ){
                  this.counter++;
              },
              sub: function () {
                  this.counter--;
              }
          }
      })
  &lt;/script&gt;
  &lt;/body&gt;
</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> &lt;div id="app" &gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2&gt; &lt;/h2&gt;
 &lt;/div&gt;
	
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
	
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message : 'hello',
         firstName: 'kobe',
         lastName: 'bryant'
     }
	
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>v-once</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;div id="app" &gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2 v-once&gt;&lt;/h2&gt;
 &lt;/div&gt;
	
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
	
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message : 'hello'
     }
	
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>v-html</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;div id="app" &gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2 v-html="url"&gt;&lt;/h2&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message : 'hello',
         url: '&lt;a href="http://www.baidu.com"&gt;百度一下&lt;a/&gt;'
     }
	
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>v-text</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;div id="app" &gt;
     &lt;h2&gt;,李银河&lt;/h2&gt;
     &lt;h2 v-test="message"&gt;,李银河&lt;/h2&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message : 'hello'
     }
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>v-pre:</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;div id="app" &gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2 v-pre&gt;&lt;/h2&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message : 'hello'
     }
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>v-cloak: 斗篷</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;head&gt;
     &lt;meta charset="UTF-8"&gt;
     &lt;title&gt;Title&lt;/title&gt;
     &lt;style&gt;
         [v-cloak] {
             display: none;
         }
     &lt;/style&gt;
 &lt;/head&gt;
 &lt;body&gt;
	
 &lt;div id="app"  v-cloak&gt;
		
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
     setTimeout(function () {
     const app = new Vue({
       el: '#app',
       data: {
         message : 'hello'
       }
     })
   },1000)
 &lt;/script&gt;
	
 &lt;/body&gt;
</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> &lt;div id="app" &gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;a v-bind:href="url"&gt;百度一下&lt;/a&gt;
     &lt;a :href="url"&gt;百度一下&lt;/a&gt;
     &lt;img v-bind:src="imgUrl" alt=""&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
         url : 'http://www.baidu.com',
         imgUrl: 'http://img2.imgtn.bdimg.com/it/u=745008878,2424441072&amp;fm=26&amp;gp=0.jpg'
	
     }
   })
 &lt;/script&gt;
</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> &lt;div id="app"&gt;
     &lt;h2 v-bind:class="{active: isActive , line: isLine}"&gt;&lt;/h2&gt;
     &lt;h2 v-bind:class="getClasses()"&gt;&lt;/h2&gt;
     &lt;button v-on:click="btnClick"&gt;click&lt;/button&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   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}
	
       }
       }
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>数组语法</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;div id="app"&gt;
     &lt;h2 :class="['active','line']"&gt;&lt;/h2&gt;
 &lt;/div&gt;
	
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message: ' 你好!'
     }
   })
 &lt;/script&gt;
	
</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> &lt;div id="app"&gt;
     &lt;h2 v-bind:style="{'font-size': '50px',background: 'red'}"&gt;&lt;/h2&gt;
     &lt;h2 :style="{fontSize: finalFont + 'px' , background: finalColor}"&gt;&lt;/h2&gt;
     &lt;h2 :style="getStyle()"&gt;&lt;/h2&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message: ' 你好!',
         finalFont: 100,
         finalColor: 'red'
     },
       methods: {
       getStyle: function () {
           return {fontSize: this.finalFont + 'px' , background: this.finalColor}
       }
       }
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>数组语法</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &lt;div id="app"&gt;
     &lt;h2 v-bind:style="[fontSize,backgroudColor]"&gt;&lt;/h2&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   const app = new Vue({
     el: '#app',
     data: {
       message: ' 你好!',
       fontSize: {fontSize: '30px'},
       backgroudColor: {background: 'red'}
     },
   })
 &lt;/script&gt;
</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> &lt;div id="app"&gt;
     &lt;h2&gt; &lt;/h2&gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2&gt;&lt;/h2&gt;
     &lt;h2&gt;&lt;/h2&gt;
 &lt;/div&gt;
 &lt;script src="../js/vue.js"&gt;&lt;/script&gt;
 &lt;script&gt;
   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
       }
       }
   })
 &lt;/script&gt;
</code></pre></div>    </div>
  </li>
  <li>
    <p>案例二: books -&gt; price</p>
  </li>
</ol>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;div id="app"&gt;
		&lt;h2&gt;总价格:  &lt;/h2&gt;
&lt;/div&gt;
&lt;script src="../js/vue.js"&gt;&lt;/script&gt;
&lt;script&gt;
  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 &lt; 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;
      },
	  }
  })
&lt;/script&gt;
</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>
    

Search

    Table of Contents