vue初学(一)

vue的特点:

渐进式。理解为一个系统中,可以同时存在jquery和vue,vue可以单独做一个模块,在改变原有系统时,可以一点点改成vue语法,所以称之为渐进式框架。

响应式。https://cn.vuejs.org/v2/guide/reactivity.html   可以看官方的解释,通俗来说就是,值修改后,会被监听到,使视图重新渲染。

MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器),VM负责监听M和V的修改,以此来实现双向绑定

Vue的语法

1、v-for

<div id="app">
    <ul>
        <li v-for="item in list">{{item}}</li>
    </ul>
</div>
<script>
    const app = new Vue({
        el:'#app',
        data:{
            message:"test",
            list:["列表1","列表2","列表3","列表4"]
        }
    });
</script>

2、v-on

v-on:click 点击事件 简写为@click

<div id="app">
    <h2>当前计数为:{{counter}}</h2>
<!--        <button v-on:click="counter++">+</button>-->
<!--        <button v-on:click="counter--">-</button>-->
    <button v-on:click="add">+</button>
    <button v-on:click="sub">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            counter:0
        },
        methods:{
            add:function () {
                console.log("add被执行");
                this.counter++;
            },
            sub:function () {
                console.log("sub被执行");
                this.counter--;
            }
        }
    });
</script>

v-on调用方法的时候,如果方法没有参数,可以省略小括号,如果方法有一个参数,调用的时候没有传参数,并且没有小括号,会打印出浏览器调用的事件,也就是event对象,如图1,如果调用的时候没有传参数,但是有小括号,会打印undefined。

如果方法有两个参数,第一个传参数了,第二个想要浏览器调用的事件对象,使用$event当参数

<div id="app">
    <button @click="btnClick(message,$event)">按钮</button>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      methods: {
        btnClick(aaa,bbb){
          console.log(aaa+"---------"+bbb);
        }
      }
    })
  </script>

v-on 还有一些修饰符可以进行修饰

@click.stop='doThis' 阻止事件冒泡 如,div有一个点击事件,button有一个点击事件,点击button时会触发div的点击事件,加上.stop后,点击button不会触发div的点击事件,阻止事件冒泡

@keyup.enter = 'doThis' 当回车键抬起时触发

@click.prevent  阻止默认行为,如表单的提交 ,不走action,走自定义的方法

@click.once 加上之后,按钮只有第一次点击有效果,后面点击没效果

3、v-once 

显示之后,message值发生变化后页面不会发生变化

<div id="app" v-once>{{message}}</div>

4、v-html

将data里的数据当做html放入指定位置并做解析

<div id="app">
    <h2>{{url}}</h2>
    <h2 v-html="url"></h2>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        url: '<a href="www.baidu.com">百度一下</a>'
      }
    })
  </script>

5、v-text 

和mustache语法效果一样,但是常用mustache,更灵活,可运算,可拼接字符串

<div id="app" v-text="message"></div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      }
    })
  </script>

6、v-pre

有该属性的div不会被vue渲染

<div id="app" v-pre>
    {{message}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      }
    })
  </script>

7、v-cloak

在vue没有渲染代码时页面不会显示源码

<style>
    [v-cloak]{
      display: none;
    }
  </style>
</head>
<body>
  <div id="app" v-cloak>
      {{message}}
    </div>

    <script src="../js/vue.js"></script>
    <script>
      setTimeout(function () {
            const app = new Vue({
              el: '#app',
              data: {
                message: '你好啊',
              }
            })
          },1000);
    </script>

8、v-bind

给属性动态绑定值 v-bind:src="imgUrl" 语法糖 :src="imgUrl"

<div id="app">
  <img v-bind:src="imgUrl" alt="">
  <a v-bind:href="aHref">百度一下</a>
  <img :src="imgUrl" alt="">
  <a :href="aHref">百度一下</a>
</div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        imgUrl: 'https://img14.360buyimg.com/babel/s1180x940_jfs/t1/152926/35/3995/99911/5f9a80d3E74cab70c/5b488b2392fbdaa4.jpg.webp',
        aHref: 'http://www.baidu.com'
      }
    })
  </script>

8.1 v-bind动态绑定class(对象用法)

注释中有第二种写法,写到methods中

<div id="app">
<!--      <h2 :class="{active:isActive,line:isLine}">{{message}}</h2>-->
      <h2 :class="getClasses()">{{message}}</h2>
    <button @click="changeColor">按钮</button>
    </div>

    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '你好啊',
          isActive: true,
          isLine: true
        },
        methods: {
          changeColor:function () {
            this.isActive = !this.isActive;
          },
          getClasses:function () {
            return {active:this.isActive,line:this.isLine};
          }
        }
      })

8.2 v-bind 动态绑定class(数组用法)

<div id="app">
<!--      <h2 class="title" :class="[active,line]">{{message}}</h2>-->
      <h2 class="title" :class="getClasses()">{{message}}</h2>
    <button @click="changeColor">按钮</button>
    </div>

    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '你好啊',
          active: "active",
          line: "line"
        },
        methods: {
          changeColor:function () {
            if(this.active == 'active'){
              this.active = "";
            }else{
              this.active = "active";
            }
          },
          getClasses:function () {
            return [this.active,this.line];
          }
        }
      })
    </script>

9、v-bind 动态绑定style

9.1 数组语法

<div id="app">
    <h2 :style="{fontSize:fontSize+'px',backgroundColor:backgroundColor}">{{message}}</h2>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        fontSize: 100,
        backgroundColor: 'red',
      }
    })
  </script>

9.2 数组语法

<div id="app">
    <h2 :style="[style1,style2]">{{message}}</h2>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        style1: {backgroundColor:'red'},
        style2: {fontSize: '100px'}
      }
    })
  </script>

10、计算属性 computed

<script>
  const app = new Vue({
    el: '#app',
    data: {
      books: [
        {id:'001',name:'test1',price:100},
        {id:'002',name:'test2',price:101},
        {id:'003',name:'test3',price:102},
      ]
    },
    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){
          result += this.books[i].price;
        }*/
        for(let book of this.books){
          result += book.price;
        }
        return result;
      }
    }
  })
</script>

10.1 计算属性的本质,为什么计算属性是属性,而不是方法

<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      firstName: '张',
      lastName: '小三'
    },
    computed: {
      fullName: {
        get: function () {
          return this.firstName + ' '+this.lastName
        },
        set: function (newValue) {
          console.log('-----------------'+newValue);
          const names = newValue.split(" ");
          this.firstName = names[0];
          this.lastName = names[1];
        }
      }
    }
  })
</script>

set方法基本不会使用,所以计算属性可以理解为是只读属性,因此,一般set方法可以省略,只有get方法,简写为 totalPrice(){} (按照10中看)

10.2 计算属性和methods的对比

计算属性在vue内部做了缓存,监听的值没有发生变化,那么计算属性中的function不会执行第二次,而methods是每调用一次就会执行一次,相比较来说,计算属性更高效

<div id="app">
    {{getFullName()}} {{getFullName()}} {{getFullName()}}
    {{fullName}}{{fullName}}{{fullName}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        firstName: '张',
        lastName: '小三'
      },
      methods: {
        getFullName: function () {
          console.log('getFullName');
          return this.firstName+' '+this.lastName;
        }
      },
      computed: {
        fullName: function () {
          console.log('fullName');
          return this.firstName+' '+this.lastName;
        }
      }

    })
  </script>

11、let和var的区别

var没有块级作用域的概念,let有

<div id="app">
  <button>按钮1</button>
  <button>按钮2</button>
  <button>按钮3</button>
</div>

  <script src="../js/vue.js"></script>
  <script>
    var btns = document.getElementsByTagName('button');
    for (var i = 0; i < btns.length; i++){
      btns.item(i).addEventListener('click',function () {
        console.log("第"+i+"个按钮被点击");
      })
    }
  </script>

闭包写法

<div id="app">
  <button>按钮1</button>
  <button>按钮2</button>
  <button>按钮3</button>
</div>

  <script src="../js/vue.js"></script>
  <script>
    var btns = document.getElementsByTagName('button');
    for (var i = 0; i < btns.length; i++){
      (function(i){
        btns[i].addEventListener('click',function () {
          console.log("第"+i+"个按钮被点击");
        })
      })(i)
    }
  </script>

let有块级作用域概念

<script src="../js/vue.js"></script>
<script>
  const btns = document.getElementsByTagName('button');
  for (let i = 0; i < btns.length; i++){
    btns[i].addEventListener('click',function () {
      console.log("第"+i+"个按钮被点击");
    })
  }
</script>

12、const

修饰常量,定义完之后不能修改,按照内存的来解释,就是不能修改地址,当修饰对象的时候,可以修改对象的值,因为修改值并没有修改const对象的指向。多使用const,少使用let

<div id="app">
    {{message}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      }
    })
    app.message = 'sdfsdf';

13、ES6 增强写法

<script>
  const name = '张三';
  const age = 18;
  const height = 180;
  const obj = {
    name: name,
    age: age,
    height: height,
    run: function () {
      console.log("跑跑跑");
    }
  }
  const obj2 = {
    name,
    age,
    height,
    run(){
      console.log("跑跑跑");
    }
  }
  console.log(obj);
  console.log(obj2);
</script>

14、v-if

条件判断

<div id="app">
  <span v-if="isShow">
    <label for="userNameLogin">用户名登录</label>
    <input type="text" id="userNameLogin" placeholder="请输入用户名" key="userNameLogin">
  </span>
  <span v-else>
    <label for="userNameLogin">邮箱登录</label>
    <input type="text" id="emailLogin" placeholder="请输入邮箱地址" key="emailLogin">
  </span>
  <button @click="isShow = !isShow">切换登录方式</button>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      isShow: true
    }
  })
</script>

这是一个登录方式切换的案例,因为v-if和v-else中的内容是互斥的,不会同时显示到页面,所以vue的虚拟dom不会重新创建元素,第二个label和input渲染到页面时实际上使用的是第一个label和input,vue会对里面的属性进行对比,例如id,文字,不同的会修改,但是value这种用户输入的不会修改,所以,在第一个input中输入123后,点击按钮切换到邮箱,input中还有123,且id之类的已经更换,这是由于vue的虚拟dom,有时需要这种效果,有时不需要,不需要时在标签中加入key属性,key不同时就会重新创建dom

14.1 v-if v-else-if v-else

<div id="app">
  <span v-if="score >= 90">优秀</span>
  <span v-else-if="score >= 60">及格</span>
  <span v-else>不及格</span>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      score: 99
    }
  })
</script>

只为案例,一般会写到computed中

<div id="app">
<!--    <span v-if="score >= 90">优秀</span>-->
<!--    <span v-else-if="score >= 60">及格</span>-->
<!--    <span v-else>不及格</span>-->
    <span>{{result}}</span>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        score: 99
      },
      computed: {
        result(){
          if(this.score >= 90){
            return "优秀"
          }else if(this.score >= 60){
            return "及格"
          }else{
            return "不及格"
          }
        }
      }
    })
  </script>

14.2 v-if 和 v-show的区别

两个都可以控制代码是否显示到页面

v-if 当条件为false时,代码不会在dom中显示,也就是说,true false来回切换的时候,vue做的操作就是删除和创建元素,当只切换一次的时候建议使用

v-show当条件为false时,代码会在dom中显示,按F12可以看,里面只是加了属性display:none,也就是说,true false来回切换的时候,vue做的操作就是修改display属性,当需要频繁切换显示或者不显示时,建议使用v-show

<div id="app">
    <span v-if="isShow" id="ifid">{{message}}</span><br>
    <span v-show="isShow" id="'showid">{{message}}</span>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        isShow: true,
      }
    })
  </script>

15、v-for 循环遍历数组,对象,角标

<div id="app">
  <ul>
    <li v-for="item in names">{{item}}</li>
  </ul>
  <ul>
    <li v-for="(item,index) in names">{{index+1}}.{{item}}</li>
  </ul>
  <ul>
    <li v-for="item in person">{{item}}</li>
  </ul>
  <ul>
    <li v-for="(value,key) in person">{{key}}--{{value}}</li>
  </ul>
  <ul>
    <li v-for="(value,key,index) in person">{{index}}.{{key}}--{{value}}</li>
  </ul>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        names: ['张三','李四','王五','赵柳'],
        person: {
          name: '张三',
          age: 18,
          height: 180
        }
      }
    })
  </script>

15.1 数组中通过下标修改元素的方式在vue中不是响应式的

<div id="app">
  <ul>
    <li v-for="item in letter">{{item}}</li>
  </ul>
  <button @click="btnClick">按钮</button>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        letter: ['a','b','c','d','e','f']
      },
      methods: {
        btnClick(){
          // this.letter.splice(0,1,'aaa')
          // this.letter.splice(1,0,'n')
          // this.letter.splice(1,1)
          this.letter[0] = 'bbbbbbbbbbbbbbbbbbbbb'
          console.log(this.letter);
        }

      }
    })
  </script>

splice方法可以修改,增加,替换

参数:从哪个角标开始,删除几个,替换成什么

16、js的高阶函数使用

const arr = ['78','23','111','34','343','22','56','777'];
let result4 = arr.filter(function (n) {
  return n>100;
}).map(function (n) {
  return n * 2;
}).reduce(function (preValue,n) {
  return preValue + n;
},0)
console.log(result4);
computed: {
  totalPrice () {
    // let totalPrice = 0;
    // for (let book of this.books) {
    //   totalPrice += book.price * book.count;
    // }
    // return totalPrice;
    //高阶函数用法
    return this.books.reduce(function (preValue,book) {
      return preValue + book.price * book.count;
    },0);
  }
}

17、v-model

双向绑定 把值跟data里的值绑定到一起,改变同时改变

<div id="app">
<!--  单选-->
  <select name="" v-model="fruit">
    <option value="苹果">苹果</option>
    <option value="香蕉">香蕉</option>
    <option value="橘子">橘子</option>
  </select>
  <br>选择的水果是:{{fruit}}
<!--  多选-->
  <br>
  <select name="" multiple v-model="fruits">
    <option value="苹果">苹果</option>
    <option value="香蕉">香蕉</option>
    <option value="橘子">橘子</option>
  </select>
  <br>选择的水果是:{{fruits}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        fruit: '香蕉',
        fruits: []
      }
    })
  </script>

17.1 v-model 结合redio使用

<div id="app">
  <label for="man">
    <input type="radio" id="man" v-model="sex" value="男">男
  </label>
  <label for="woman">
    <input type="radio" id="woman" v-model="sex" value="女">女
  </label>
  <br>性别是:{{sex}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        sex: ""
      }
    })
  </script>

17.2 v-model 结合checkbox 单选

<div id="app">
  <label for="licence">
    <input type="checkbox" id="licence" v-model="isAgree">是否同意该协议
  </label>
  <br><button :disabled="!isAgree">下一步</button>
  <br>isAgree的值是:{{isAgree}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        isAgree: false
      }
    })
  </script>

17.3  v-model 结合checkbox 多选

<div id="app">
  <input type="checkbox" name="hobbies" value="篮球" v-model="hobbies">篮球
  <input type="checkbox" name="hobbies" value="足球" v-model="hobbies">足球
  <input type="checkbox" name="hobbies" value="羽毛球" v-model="hobbies">羽毛球
  <input type="checkbox" name="hobbies" value="乒乓球" v-model="hobbies">乒乓球
  <br>
  <h2>爱好是:{{hobbies}}</h2>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        hobbies: []
      }
    })
  </script>

17.4  值绑定其实就是v-bind

<div id="app">
  <label :for="item" v-for="item in originalHobbies" >
    <input type="checkbox" :id="item" :value="item"  v-model="hobbies">{{item}}
  </label>
  <h2>爱好是:{{hobbies}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      hobbies: [],
      originalHobbies: ['篮球','足球','羽毛球','乒乓球']
    }
  })
</script>

17.5 v-model的修饰符

v-model.lazy 比如input中,修改value不会时时修改data中的值,在点击回车或者触发失去焦点事件的时候,会修改值

v-model.number 比如input中,type=“number” 实际上,value中的值类型是string,当特殊情况时需要做类型转换,使用该修饰符后可保证是number类型

v-model.trim 当输入的时候,会把值左右两边的空格去除,浏览器本身会去除,但是data里的值并没有改变,使用该修饰符后,data中的值也会被trim

<div id="app">
  <input type="text" v-model.lazy="message" >
  <h2>message的值是:{{message}}</h2>
  <input type="number" v-model.number="testnumber" >
  <h2>类型是:{{typeof testnumber}}</h2>
  <input type="text" v-model="message" >
  <h2>message的值是:{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      testnumber: 0
    }
  });
</script>

18、vue组件

18.1 vue组件的基本使用,已经全局组件和局部组件

<div id="app">
    <cpn></cpn>
    <cpn2></cpn2>
  </div>

  <script src="../js/vue.js"></script>
  <script>
    //全局组件
    //创建组件构造器
    const cpnC = Vue.extend({
      template: `
        <div>
          <h2>我是标题</h2>
          <p>我是内容,哈哈哈哈</p>
        </div>
      `
    });
    const cpnC2 = Vue.extend({
      template: `
        <div>
          <h2>我是标题2</h2>
          <p>我是内容,呵呵呵呵</p>
        </div>
      `
    });
    //注册组件
    Vue.component('cpn',cpnC);
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      //局部组件
      components: {
        cpn2: cpnC2
      }
    })
  </script>

18.2 vue组件的语法糖

<div id="app">
  <cpn></cpn>
  <cpn2></cpn2>
</div>

<script src="../js/vue.js"></script>
<script>
  //全局组件
  //创建组件构造器
  //注册组件
  Vue.component('cpn',{
    template: `
        <div>
          <h2>我是标题</h2>
          <p>我是内容,哈哈哈哈</p>
        </div>
      `
  });
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
    },
    //局部组件
    components: {
      cpn2: {
        template: `
        <div>
          <h2>我是标题2</h2>
          <p>我是内容,呵呵呵呵</p>
        </div>
      `
      }
    }
  })
</script>

只是把extend里的对象移到了component中,在vue源码中,component还是调用了extend

18.3 组件中模板的抽离

<div id="app">
  <cpn></cpn>
  <cpn2></cpn2>
</div>
<!--第一种抽离写法,script-->
<script type="text/x-template" id="cpn">
  <div>
    <h2>我是标题</h2>
    <p>我是内容,呵呵呵呵呵</p>
  </div>
</script>
<!--第二种抽离写法-->
<template id="cpn2">
  <div>
    <h2>我是标题2</h2>
    <p>我是内容,呵呵呵呵呵2</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>

18.4 父子组件

<div id="app">
    <cpn></cpn>
    <cpn2></cpn2>
  </div>


<template id="cpn">
  <div>
    <h2>我是爸爸</h2>
    <p>哈哈哈哈哈</p>
    <cpn2></cpn2>
  </div>
</template>
<template id="cpn2">
<div>
  <h2>我是儿子</h2>
  <p>呵呵呵呵呵</p>
</div>
</template>
  <script src="../js/vue.js"></script>
  <script>

    Vue.component('cpn',{
      template: '#cpn',
      components: {
        cpn2: {
          template: '#cpn2',
        }
      }
    });
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      components: {
        cpn2: {
          template: '#cpn2'
        }
      }
    })
  </script>

18.5 组件不能用vue实例中的变量,想在组件中使用变量时,需要使用data属性,组件中的data属性必须是一个函数

<div id="app">
    <cpn></cpn>
  </div>
<template id="cpn">
  <div>
    <h2>我是一个组件</h2>
    <h2>{{title}}</h2>
    <h2>{{title2}}</h2>
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      data(){
        return {
          title: '我是一个data里的标题',
          title2: '我是一个data里的标题2'
        }
      }
    };
    Vue.component('cpn',cpn);
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      }
    })
  </script>

18.5.1 什么组件中的data属性必须是一个函数

是因为在组件封装后,会有其他的地方调用组件,相互之间的数据不影响,每次调用data中的函数,返回的都是一个新的对象,例如下面这个计数器的案例,当在不同地方调用三次计数器,需要相互之间不影响

<div id="app">
    <cpn></cpn>
    <cpn></cpn>
    <cpn></cpn>
  </div>
<template id="cpn">
  <div>
    <h2>当前计数为:{{count}}</h2>
    <button @click="incrment">+</button>
    <button @click="decrment">-</button>
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      methods: {
        incrment(){
          this.count++;
        },
        decrment(){
          this.count--;
        },
      },
      data(){
        return{
          count: 0
        }
      }
    };
    Vue.component('cpn',cpn);
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      }
    })
  </script>

18.6 父子组件之间的通信  父组件向子组件传值 需要注意的是,当值为对象或者为数组时,default属性为一个函数,如例子中的books

<div id="app">
    <cpn :message="message" :books="books"></cpn>
  </div>
<template id="cpn">
  <div>
    <h2>我是子组件</h2>
    <p>{{message}}</p>
    <div>
      <ul>
        <li v-for="item in books">{{item}}</li>
      </ul>
    </div>
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>

    const cpn = {
      template: '#cpn',
      // props: ['message']
      props: {
        message: {
          type: String,
          default: 'aaaaaa',
          required: true
        },
        books: {
          type: Array,
          default(){
            return [];
          }
        }
      }
    };
    Vue.component('cpn',cpn);
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
        books: ['书1','书2','书3']
      },
      components: {
        cpn
      }
    });
  </script>

18.7 父子组件通信时,props属性中定义的属性名,在组件标签中使用的时候,不能使用驼峰式,如cMessage,这样会获取不到值,直接显示默认值,需要写成c-message

<div id="app">
  <cpn :c-message="message"></cpn>
  </div>
<template id="cpn">
  <div>{{cMessage}}</div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      props: {
        cMessage: {
          type: String,
          default() {
            return 'aaa';
          }
        }
      }
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      components: {
        cpn
      }
    })
  </script>

18.9 子组件向父组件传递数据  使用自定义事件

父组件监听子组件发射来的事件,会默认把传递的参数传过去,父组件在写的时候可以不用写小括号,和监听默认方法,如click,不传值传浏览器的event对象有区别,需注意

<div id="app">
    <cpn @cpnclick="cpnclick"></cpn>
  </div>
<template id="cpn">
  <div>
    <button v-for="item in categories" @click="btnclick(item)">{{item.name}}</button>
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      data(){
        return {
          categories: [
            {id:'111',name:'热门推荐'},
            {id:'222',name:'数码'},
            {id:'333',name:'家具'},
            {id:'444',name:'服饰'},
          ]
        }
      },
      methods: {
        btnclick(item){
          this.$emit('cpnclick',item)
        }
      }
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      components: {
        cpn
      },
      methods: {
        cpnclick(item){
          console.log('cpnclick', item);
        }
      }
    })
  </script>

18.10 父组件直接访问子组件 常用$refs

$children用来获取所有子组件

<div id="app">
    <cpn ref="aaa"></cpn>
  <button @click="btnclick">按钮</button>
  </div>
<template id="cpn">
  <div>
    我是子组件
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template : '#cpn',
      data() {
        return {
          name: '我是子组件的name'
        }
      }
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      components: {
        cpn
      },
      methods: {
        btnclick() {
          console.log(this.$children);
          console.log(this.$children[0].name);
          console.log(this.$refs);
          console.log(this.$refs.aaa);
          console.log(this.$refs.aaa.name);
        }
      }
    })
  </script>

18.11 子组件直接访问父组件 使用$parent 如果父组件是根,获取的是vue实例,不是的话获取的是vueComponent,不建议使用,组件主要是封装,获取父组件属性会出现问题,耦合度太高

19、slot 插槽

19.1 slot插槽的基本使用,以及具名插槽的使用

<div id="app">
    <cpn>
      <h2>我是第一个插槽</h2>
      <h2 slot="slot1">我是第二个插槽</h2>
      <h2 slot="slot2">我是第三个插槽</h2>
    </cpn>
  </div>
<template id="cpn">
  <div>
    <spn>我是子组件</spn>
    <slot></slot>
    <slot name="slot1"></slot>
    <slot name="slot2"></slot>
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn'
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      components: {
        cpn
      }
    })
  </script>

19.2 作用域插槽

首先要知道,在模板中使用的变量,必须是当前组件定义了的属性,无法直接使用父模板或者子模板的属性

修改子模板中的标签,但是内容还是来自于子模板,需要使用作用域插槽

案例中,books的值还是来自于子组件,但是父组件修改了子组件模板的标签

<div id="app">
    <cpn>
      <template slot-scope="slot">
<!--        <spn v-for="item in slot.data">{{ item +" - "}}</spn>-->
<!--        作用域插槽-->
        <spn>{{slot.data.join(' * ')}}</spn>
      </template>
    </cpn>
  </div>
<template id="cpn">
  <div>
    <slot :data="books">
      <ul>
        <li v-for="item in books">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>
  <script src="../js/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      data() {
        return {
          books: ['java','script','C++','C#','Vue']
        }
      }
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好啊',
      },
      components: {
        cpn
      }
    })
  </script>

20、模块化开发

commonJs   必须在node环境下才可以

导出:module.exports.name = '小明'

一起导出: module.exports = { name,age}

导入:const name = require('./aaa.js')

es6 导入导出

导出 export const name = '小明'

一起导出  export {name,age}

导入  impot {name,age} from "./aaa.js"

如果想自定义名称,导出时使用export default name,导入的时候使用 import n from “./aaa.js” 不需要大括号,可以自定义名字

如果想一起全部导入,import * as aaa from "./aaa.js"  等于是把所有导出的属性放到了aaa属性里,后面使用aaa.name

export default 一个模块只有一个

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值