Vue.js学习笔记

文章目录

  • Vue.js学习笔记
    • 1. Vue介绍
      • 1.1 Vue的特点:
      • 1.2 Vue的扩展插件
      • 1.3 Vue的基本使用
      • 1.4 强制数据绑定和绑定数据监听
      • 1.5 计算属性值的基本使用
      • 1.6 监视
      • 1.7 双向监视
      • 1.8 style和 class的强制绑定
      • 1.9 条件渲染
      • 1.10 vue的列表渲染
      • 1.11 列表的搜索和排序
      • 1.12 事件处理
      • 1.13 表单数据的自动收集
      • 1.14 vue实例生命周期
      • 1.15 Vue的动画:
      • 1.16 过滤器
      • 1.17 Vue的指令
      • 1.18 插件
    • 2. Vue组件化编码
      • 2.1 使用vue-cli创建模板项目
      • 2.2 基于脚手架编写项目
      • 2.3 打包发布项目
      • 2.4 vue_Eslint编码规范检查
      • 2.5 组件间的相互通信(1)
        • 2.5.1 练习一
          • 2.5.1.1添加功能
          • 2.5.1.2 删除功能
        • 2.5.2 练习二
          • 2.5.2.1 基本功能
          • 2.5.2.2 存储数据
      • 2.6 组件间的相互通信(2)- 自定义事件
        • 2.6.1 @事件名=‘事件名’
        • 2.6.2 利用js代码进行事件的绑定
      • 2.7 组件间的相互通信(3)-消息的订阅与发布
      • 2.8 组件间的相互通信slot
      • 2.9 数据存储优化
    • 3. Vue-ajax
      • 3.1 vue项目中的常用的2个ajax库
        • 3.1.1 vue-resource
        • 3.1.2 axios
      • 3.2 vue-resource的使用
      • 3.3 vue-axios的使用
      • 3.3 vue-anxios实践
    • 4. Vue路由
      • 4.1相关Api说明:
      • 4.2 基本路由
      • 4.3嵌套路由
      • 4.4 缓存路由组件对象
      • 4.4 路由组件传递数据
      • 4.5 编程式路由导航

Vue.js学习笔记

1. Vue介绍

1.1 Vue的特点:

  • 遵循mvvm模式
  • 代码简洁 体积小 运行效率高 适合移动或pc开发
  • 它本身只关注UI,可以轻松引入vue插件或其他第三方库开发项目

1.2 Vue的扩展插件

  1. vue-cli:vue 脚手架
  2. vue-resource(axios):ajax 请求
  3. vue-router: 路由
  4. vuex: 状态管理
  5. vue-lazyload: 图片懒加载
  6. vue-scroller: 页面滑动相关
  7. mint-ui: 基于 vue 的 UI 组件库(移动端)
  8. element-ui: 基于 vue 的 UI 组件库(PC 端)\

1.3 Vue的基本使用

  1. 引入Vue.js
  2. 创建Vue对象
    el : 指定根element(选择器)
    data : 初始化数据(页面可以访问)
  3. 双向数据绑定 : v-model
  4. 显示数据 : { {xxx}}
  5. 理解vue的mvvm实现
    Vue.js学习笔记_第1张图片Vue.js学习笔记_第2张图片
  • MVVM:
    model:模型,数据对象
    view:视图,模板页面
    viewModel:视图模型 vue的实例

v-model本质上是一个语法糖

如下代码<input v-model="test">
本质上是<input :value="test" @input="test = $event.target.value">,
其中@input是对<input>输入事件的一个监听:value="test"是将监听事件中的数据放入到input,
下面代码是v-model的一个简单的例子。
在这边需要强调一点,v-model不仅可以给input赋值还可以获取input中的数据,
而且数据的获取是实时的,因为语法糖中是用@input对输入框进行监听的。
可以在如下div中加入<p>{
     {
      test}}</p>获取input数据,
然后去修改input中数据会发现<p></p>中数据随之改变。

v-model不仅可以给input赋值还可以获取input中的数据,

1.4 强制数据绑定和绑定数据监听

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>01_HelloWorld</title>
    <link rel="stylesheet" href="../layui/css/layui.css">
</head>
<body>

<div id="el1">
    <input id="username" name="username" v-model="username">
    <p>{
     {
     username.toUpperCase()}}</p>
    <p>{
     {
     sex}}</p>
    <p>{
     {
     things}}</p>
    <p v-html="msg"></p><!--相当于是 innerHtml-->
    <p v-text="msg"></p><!--相当于是textContent-->
    <p>{
     {
     msg}}</p>
    <!--强制数据绑定-->
    <img :src="imghref"><!--src前面的:  相当于是在强制绑定-->
    <!--绑定事件监听-->
    <br>
    <button type="button" class="layui-btn layui-btn-danger" v-on:click="test">点击一下</button>
    <button type="button" class="layui-btn layui-btn-warm" @click="test1(username)">点击一下</button>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">

   new Vue({
     
        el:"#el1",
        data:{
     
            username:"tjk",
            sex:"男",
            things:"无所事事",
            msg:'I will back',
            imghref:"https://cdn.dragonstatic.com/parking/partner/meiguo.com/images/0.s.jpg"
        },
        methods:{
     
            test(){
     
                alert("你把爷点了");
            },
            test1(content){
     
                alert(content)
            }
        }
    })
</script>
</body>
</html>
  • 强制数据绑定
    在这里插入图片描述
    Vue.js学习笔记_第3张图片
  • 绑定事件监听
    在这里插入图片描述
    Vue.js学习笔记_第4张图片

1.5 计算属性值的基本使用

Vue.js学习笔记_第5张图片
计算属性中的一个方法,方法的返回值作为属性值

1.6 监视

所有vue代码中的this都指的是 vm对象本身
监视是指:所监视的属性中的值发生改变,然后进行回调函数的执行
Vue.js学习笔记_第6张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监视</title>
</head>
<body>
<div id="demo">
    <input type="text" placeholder="First Name" v-model="firstName"><br>
    <input type="text" placeholder="last Name" v-model="lastName"><br>
    姓名1:(单向):<input type="text" placeholder="Full Name1"  v-model="FullName1"><br>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
    new Vue({
     
        el:"#demo",
        data:{
     
            firstName:"A",
            lastName:"B"
            //FullName1:"AB"
        },
        watch:{
     
            firstName:function (value) {
     //对firstName进行监视
                alert(value);   //this 就是vm实例
                this.FullName1=value+""+this.lastName;
            }
        }
    })
    
    //第二种
    vm.$watch('lastName',function (value) {
     
        this.FullName2=this.firstName+"-"+value;
    });

</script>
</body>
</html>

回调函数:1.你定义的 2.执行了 3.你没有调用

1.7 双向监视

Vue.js学习笔记_第7张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>getset(双向)</title>
</head>
<body>
<div id="demo">
    <input type="text" placeholder="First Name" v-model="firstName"><br>
    <input type="text" placeholder="last Name" v-model="lastName"><br>
    姓名1:(单向):<input type="text" placeholder="Full Name1"  v-model="FullName1"><br>
    姓名2:(单向):<input type="text" placeholder="Full Name2"  v-model="FullName2"><br>
    姓名3:(双向):<input type="text" placeholder="Full Name3"  v-model="FullName3"><br>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
   var vm=new Vue({
     
        el:"#demo",
        data:{
     
            firstName:"A",
            lastName:"B"
            //FullName1:"AB"
        },
       computed:{
     
           //回调函数:
           //1. 你定义的  2. 你没有调用  3.最终执行了
           //回调函数 (当需要读取当前属性值时回调)  计算并返回当前属性的值
           FullName3:{
     
               get(){
     
                   return this.firstName+" "+this.lastName;
               },
               //监视特定属性的属性值,当属性值发生改变时进行回调,更新相关的属性数据
               set(value){
     
                        const names=value.split(' ');
                       this.firstName=names[0];
                       this.lastName=names[1];
               }
           }
   },
        watch:{
     
            firstName:function (value) {
     //对firstName进行监视
                this.FullName1=value+" "+this.lastName;
            }
        }
    });
    //监视的第二种写法
    vm.$watch('lastName',function (value) {
     
        this.FullName2=this.firstName+" "+value;
    });
</script>
</body>
</html>

计算属性存在缓存,多次读取只执行一次getter计算

1.8 style和 class的强制绑定

  • class动态绑定
  1. :class=”xxx “
  2. xxx是字符串
  3. xxx是对象
  4. xxx是数组
  • style绑定
    1.:style=”{color:red,fontsize:fontsize+‘px’}“
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>class和style的强制绑定</title>
    <link rel="stylesheet" href="../layui/css/layui.css">
    <style type="text/css">
        .aclass{
     
            color: red;

        }
    </style>
</head>
<body>
<div id="demo">
    <h2>1.class绑定 :class=’xxx‘</h2>
<button type="button" :class="a">显示效果</button><br>
<hr>
    <button type="button" @click="update">点击一下</button>
</div>
<h2>2. style绑定</h2>
<script src="../layui/layui.js"></script>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
   var vm=new Vue({
     
        el:"#demo",
        data:{
     
           a:'',//相当于是声明一下
       },
        methods:{
     
            //此事件是点击事件   所以点击  然后颜色会发生变化
            update(){
     
              this.a="layui-btn layui-btn-danger"
             }
        }

    });

</script>
</body>
</html>

1.9 条件渲染

  • v-if v-else
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-if v-else</title>
    <link rel="stylesheet" href="../layui/css/layui.css">

</head>
<body>
<div id="dome">
    <p v-if="xxx">床前明月光</p>
    <p v-else>疑是地上霜</p>   <!-- //默认是true-->

    <button class="layui-btn layui-btn-danger" @click='xxx=!xxx'>点击切换</button>

<br>
    <p v-show="xxx">表白呀</p>
    <p v-show="!xxx">还是别了吧</p>
</div>

<script src="../layui/layui.js"></script>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
    el:"#dome",
    data:{
     
        xxx:true
    }
})
</script>
</body>
</html>

Vue.js学习笔记_第8张图片
v-if 和v-show的区别:
v-if是将整个属性进行移除 v-show是将整个控件加载完成后style设置为不显示

1.10 vue的列表渲染

  • v- for 遍历对象
    Vue.js学习笔记_第9张图片- v-for 遍历数组
    Vue.js学习笔记_第10张图片Vue.js学习笔记_第11张图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for</title>


</head>
<body>
<div id="dome">
    <h3 >测试:v-for 遍历数组</h3>
    <ul>
        <li v-for="(p,index) in persons" :key="index">
     --------------------------------<br>
    |{
     {
     index}}|{
     {
     p.name}}|{
     {
     p.age}}|<button type="button" @click="deletep(index)">删除该行</button>
            <button @click="updatep(index,{name:'cat' ,age:'25'})">更新该行</button>|
        </li>
    </ul>
    <h3> 测试:v-for 遍历对象</h3>
    <ul>             //属性值  属性名(用处不多)
        <li v-for="(value,key) in persons[1]" :key="key">
            {
     {
     value}}:{
     {
     key}}
        </li>

    </ul>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
    el:"#dome",
    data:{
     
        persons:[//vue本身只监视了persos的改变,没有监视数组内部数据的改变
                  //vue重写了数组的一系列改变数组内部数据的方法(先调用原有的方法,然后更新界面)
                  {
     name:"tjk",age:"13"},
                  {
     name:"tjk1",age:"131"},
                  {
     name:"tjk2",age:"132"},
                  {
     name:"tjk3",age:"133"},
        ]
    },
    methods:{
     
        deletep(index){
     
            //删除person中指定index的p
            var i=this.persons.splice(index,1);
            alert(i.persons.name);
            console.log(i);

            //splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。
        },
        updatep(index,newp){
     
            //this.persons[index]=newp;//数据改变了,但是界面显示不了
            this.persons.splice(index,1,newp);//可以实现增删改操作    当是增加的时候  int=0即可
        }
    }
})



</script>
</body>
</html>

1.11 列表的搜索和排序

  • 搜索:
    在这里插入图片描述
    Vue.js学习笔记_第12张图片

  • 排序:
    在这里插入图片描述
    Vue.js学习笔记_第13张图片sort (function (a,b){

    });
    Vue.js学习笔记_第14张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for</title>
</head>
<body>
<div id="dome">
<input type="text"  v-model="searchName" />
    <ul>
        <li v-for="(p,index) in persons" :key="index">
            {
     {
     index}}=={
     {
     p.name}}=={
     {
     p.age}}
        </li>
    </ul>
    =====================================================================
    <ul>
        <li v-for="(p,index) in filterPersons" :key="index">
            {
     {
     index}}=={
     {
     p.name}}=={
     {
     p.age}}
        </li>
    </ul>
        <button type="button" @click="setOrderType(1)" >按年龄升序</button>
        <button type="button" @click="setOrderType(2)">按年龄降序</button>
        <button type="button"  @click="setOrderType(0)">原有的顺序</button>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
    el: "#dome",
    data: {
     
        dataType:0,
        searchName: "",
        persons: [//vue本身只监视了persos的改变,没有监视数组内部数据的改变
            //vue重写了数组的一系列改变数组内部数据的方法(先调用原有的方法,然后更新界面)
            {
     name: "tjk", age: 13},
            {
     name: "tjk1", age: 131},
            {
     name: "tjk2", age: 132},
            {
     name: "tjk3", age: 133},
        ],
    },
    computed: {
     
        filterPersons() {
     
            //取出相关的数据
            console.log(this);
           const {
     searchName,persons,dataType} = this;//解构赋值   相当于是   person=this.person
            //最终需要希纳是的数组
             let  fPersons;
            //对person进行过滤
            //alert(persons[1].name);                                            //将每一个数组的name中查看有无searchNmae的字符  有则赋给fPserson

            fPersons= persons.filter(p=>p.name.indexOf(searchName)!=-1);         //   fPersons= persons.filter(p=>true);  表示不进行过滤
             if(dataType!=0){
     
                 fPersons.sort(function (p1,p2) {
     //如果返回负数p1在前,返回正数  p2 在前
                     if(dataType==2){
     
                         return p2.age-p1.age;
                     }else{
     
                         return p1.age-p2.age;
                     }
                 })
             }                                                                   // indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
            return fPersons;                                                      //p相当于是persons   =》后面的相当于是匿名函数
                }
    },
    methods: {
     
        setOrderType(type) {
     
            this.dataType = type;
        },
    }
})
</script>
</body>
</html>

1.12 事件处理

  • 绑定监听
    Vue.js学习笔记_第15张图片
    Vue.js学习笔记_第16张图片

该target属性可以是为事件注册的元素或其后代。它往往是比较有用event.target到this,以确定事件是否正在由于事件冒泡处理。当事件冒泡时,此属性在事件委托中非常有用。

  • 事件修饰符

stopPropagation()的用法;
Vue.js学习笔记_第17张图片
在这里插入图片描述
@click.stop和event.stopPropagation()的用法是一样的 阻止单击事件继续传播

@click.prevent:
阻止事件的默认行为

  • 按键修饰符
    在这里插入图片描述
    Vue.js学习笔记_第18张图片
    每一个event都有一个keycode
    如果按照下面这样写的话,就不用识别keyCode()了会自动识别按钮 “回车键”
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件处理</title>
</head>
<body>
<div id="dome">
   <h2> 1.绑定监听</h2>
<button type="button" @click="test1">test1</button>
 <button type="button" @click="test2('tjktjktjk')">test2</button>
    <button type="button" @click="test3">test3</button>
    <button type="button" @click="test4('123',$event)">test4</button>

    <h2> 2. 事件修饰器</h2>
<div style="width:200px;height: 200px;background: #00FF00" @click="test5">
    <div style="width:100px;height: 100px;background: #FFFF00 " @click.stop="test6">
    </div>
</div>
<a href="www.baidu.com" @click="test7">阻止默认事件触发</a>
    <h2> 3.按键修饰器</h2>
    <input type="text" @keyup="test8">
    <input type="text" @keyup.enter="test8">
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
   el:"#dome",
   data:{
     

    },
    methods: {
     
        test1() {
     
            alert("test1");
        },
        test2(msg) {
     
            alert(msg);
        },
        test3(event) {
     
            alert(event.target.innerHTML);
        },
        test4(a, b) {
     
            alert(a + '----' + b.target.innerHTML);

        },
        test5() {
     
            alert("点击了外面");
        },
        test6() {
     
            //event.stopPropagation();
            alert("点击了里面");
        },
        test7() {
     
            alert("这就行了");
        },
        test8(event){
     
            alert(event.target.value+"event.code:"+event.keyCode);
            }
        

    }
})
</script>
</body>
</html>

完整的key press 过程分为两个部分,按键被按下,然后按键被松开并复位。

当按钮被松开时,发生 keyup 事件。它发生在当前获得焦点的元素上。

keyup() 方法触发 keyup 事件,或规定当发生 keyup 事件时运行的函数

1.13 表单数据的自动收集

主要还是用的 v-mode=““

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自动收集</title>
</head>
<body>
<div id="dome">
  <form action=""  @submit="handSubmit">
      <span> 用户名:</span>
      <input type="text" v-model="username"><br>
      <span> 密码:</span>
      <input type="password" v-model="pwd"><br>
      <span>性别</span>
      <input type="radio" id="female" value="女" v-model="sex" >
      <label  for="female" ></label>
      <input type="radio" id="male" value="男" v-model="sex" >
      <label  for="male" ></label><br>

      <span>爱好;</span>
      <input type="checkbox" id="basket" value="basket" v-model="likes">
      <label  for="basket" >篮球</label>
      <input type="checkbox" id="foot"   value="foot" v-model="likes">
      <label  for="foot" >足球</label>
      <input type="checkbox" id="pingpang"  value="pingpang" v-model="likes" >
      <label  for="pingpang" >乒乓球</label><br>

      <span>城市</span>
      <select v-model="cityId">
          <option >未选择</option>
          <option :value="city.id" v-for="(city,index) in allCitys" :key="index"><!--//添加: 是因为不加的时候相当于是一个字符串-->
          {
     {
     city.name}}
          </option>

      </select><br>
      <span>介绍</span>
      <textarea rows="10" v-model="desc"></textarea ><br>
      <input type="submit" value="提交">
  </form>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
     el:"#dome",
    data:{
     
         username:"",
         pwd:'',
        sex:'男',
        likes:['foot'],
        allCitys:[{
     id:1,name:'渭南'},{
     id:2,name:'西安'},{
     id:3,name:'韩城'}],
        cityId:"3",
        desc:"aaab",
     },
    methods:{
     
        handSubmit(){
     
           alert(this.username+"---"+this.pwd+"---"+this.sex+"---"+this.likes+"---"+this.cityId+"---"+this.desc);

        }
    }

})
</script>
</body>
</html>
  • @submit=" "//防止自动提交
    在这里插入图片描述
    在这里插入图片描述
    Vue.js学习笔记_第19张图片
    Vue.js学习笔记_第20张图片

1.14 vue实例生命周期

实例的生命周期有三个阶段:初始化显示 更新显示 死亡
生命周期的回调函数 也叫做 钩子函数
Vue.js学习笔记_第21张图片Vue.js学习笔记_第22张图片

  • 启动定时器 —> 关闭定时器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>生命周期</title>
</head>
<body>
<div id="test">
  <button @click="vmDeatory" >destory Vue</button>
    <p v-show="isShow"> 我骄傲 </p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
    el:"#test",
    data:{
     
        isShow:true,
    },
    methods:{
     
        vmDeatory(){
     //干掉vm
            this.$destroy();
        }
    },
    mounted(){
     //初始化显示之后立即调用(1次)
        //循环定时器
        this.intervalId=setInterval(()=>{
     
            this.isShow=!this.isShow;//只要是回调函数就使用箭头函数  箭头函数没有内置对象   不存在自己的this
        },1000);
    },
    //死亡前的回调函数  1次
    beforeDestroy(){
     
        console.log("--");
        clearInterval(this.intervalId)
    },
})


</script>
</body>
</html>

Vue.js学习笔记_第23张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>生命周期</title>
</head>
<body>
<div id="test">
  <button @click="vmDeatory" >destory Vue</button>
    <p v-show="isShow"> 我骄傲 </p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
var vm=new Vue({
     
    el:"#test",
    data:{
     
        isShow:true,
    },
    methods:{
     
        vmDeatory(){
     //干掉vm
            this.$destroy();
        }
    },
    //初始化阶段
    beforeCreate(){
     
        console.log("beforeCreate");
    },
    created(){
     
        console.log("created");
    },
    beforeMount(){
     
       ("beforeMount");
    },
    mounted(){
     //初始化显示之后立即调用(1次)
        //循环定时器
        this.intervalId=setInterval(()=>{
     
            this.isShow=!this.isShow;//只要是回调函数就使用箭头函数  箭头函数没有内置对象   不存在自己的this
        },1000);
    },
    //更新阶段
beforeUpdate(){
     
    console.log("beforeUpdate");
},
    updated(){
     
        console.log("updated");
    },
    //死亡前的回调函数  1次
    beforeDestroy(){
     
        console.log("beforeDestroy");
        clearInterval(this.intervalId)
    },
    destroyed(){
     
        console.log("destroyed");
    }
})


</script>
</body>
</html>

Vue.js学习笔记_第24张图片常用的mounted():发送ajax 请求,启动定时器等任务
beforeDestory():做收尾工作:如:清除定时器

1.15 Vue的动画:

(1).操作css的trasition或animation
(2).vue会给目标元素添加/移除特定的class
(3).过度的相关类名

  • xxx-enter-active:指示显示的transition
  • xxx-leave-active:指定隐藏的transition
  • xxx-enter/xxx-leave-to:指定隐藏时的样式

Vue.js学习笔记_第25张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动画</title>
    <style>

     /* 显示、隐藏的过度效guo*/
        .xxx-enter-active, .xxx-leave-active {
     
            transition: opacity 1s;
        }
      /*  !* 隐藏时的样式*!*/
        .xxx-enter, .xxx-leave-to{
     
            opacity: 0;
        }
     /* 显示的过度效guo*/
        .yyy-enter-active{
     
            transition: all 3s;
        }
       /* 隐藏的过渡效果*/
     .yyy-leave-active{
     
         transition: all 5s;
     }

     /*  !* 隐藏时的样式*!*/
        .yyy-enter,.yyy-leave-to{
     
            opacity: 0; /*设置元素的不透明级别*/
            transform: translateX(20px);/*向 右移动20px后消失*/
        }


    </style>
</head>
<body>
<div id="test">
  <button @click="isShow=!isShow" >toggle</button>

    <transition name="xxx">
        <p v-show="isShow"> 我骄傲 </p>
    </transition>
</div>

<div id="test2">
    <button @click="isShow=!isShow" >toggle2</button>

    <transition name="yyy">
        <p v-show="isShow"> 我骄傲2 </p>
    </transition>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
     
    el:"#test",
    data() {
     
        return {
     
            isShow:true,

        }
    }
})
new Vue({
     
    el:"#test2",
    data() {
     
        return {
     
            isShow:true,
        }
    }
})
</script>
</body>
</html>

Vue.js学习笔记_第26张图片首先将要过渡的元素用transition包裹,并设置过渡的name

  • 设置CSS为opacity:0,说明过渡刚进入和离开的时候透明度为0,即不显示

1.16 过滤器

Vue.js学习笔记_第27张图片

  • 过滤器功能: 对要显示的数据进行特定格式化后再显示
  • 注意: 并没有改变原本的数据, 可是产生新的对应的数据
  • 定义和使用过滤器
  1. 定义过滤器 Vue.filter(filterName,function(value[,arg1,arg2,…])
    { // 进行一定的数据处理 returnnewValue })
  2. 使用过滤器
    { {myData|filterName}}
    { {myData|filterName(arg)}}

1.17 Vue的指令

v:text: 更新元素的 textContent
v-html: 更新元素的 innerHTML
v-if: 如果为 true, 当前标签才会输出到页面
v-else: 如果为 false, 当前标签才会输出到页面
v-show: 通过控制 display 样式来控制显示/隐藏
v-for: 遍历数组/对象
v-on: 绑定事件监听, 一般简写为@
v-bind: 强制绑定解析表达式, 可以省略 v-bind
v-model: 双向数据绑定
ref: 指定唯一标识,vue 对象通过$els 属性访问这个元素对象
v-cloak: 防止闪现, 与 css 配合:[v-cloak]{display:none}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>指令</title>
<style>
    [v-cloak]{
     
        display: none;
    }
</style>
</head>
<body>
<div id="test">
<p ref="content">什么,你看见我了 </p>
    <button  @click="hint">点一下</button>
    <p>{
     {
     msg}}</p>
    <p v-text="msg" v-cloak=""></p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
     
    el:"#test",
    data: {
     
        msg:'tjk',
    },
    methods:{
     
        hint(){
     
            alert(this.$refs.content.textContent);
        }
    }
})
</script>
</body>
</html>

Vue.js学习笔记_第28张图片纠错 上面的闪光 叫闪屏就是页面没有加载完首先出来{ {msg}}
如下:
Vue.js学习笔记_第29张图片

  • 自定义指令
    Vue.js学习笔记_第30张图片

1.18 插件

  • html文件
    Vue.js学习笔记_第31张图片
    Vue.js学习笔记_第32张图片

2. Vue组件化编码

Vue.js学习笔记_第33张图片

2.1 使用vue-cli创建模板项目

npm install -g vue-cli
vue init webpack vue_demo
cd vue_demo 
npm install
npm run dev 
访问:http://localhost:8080/

github点击下载:
node.js点击下载

在这里插入图片描述
在这里插入图片描述

vue - cli的卸载命令 npm uninstall vue-cli -g

  • npm install -g vue -cli
    Vue.js学习笔记_第34张图片如果出现如下错误:可以点win+x 以管理员方式运行 即可避免
    Vue.js学习笔记_第35张图片

  • vue
    Vue.js学习笔记_第36张图片如果vue显示 不识别该指令 那么就需要配置环境变量
    在计算机全局搜索 vue.cmd
    然后复制路径 粘贴到path中即可

  • 准备创建项目

Vue.js学习笔记_第37张图片接下来这一步可能会报错又
如果爆出权限不够,可以点击菜单然后选择cmd 以管理员方式运行即可
npm install 的作用:
Vue.js学习笔记_第38张图片
Vue.js学习笔记_第39张图片
run dev
Vue.js学习笔记_第40张图片Vue.js学习笔记_第41张图片

2.2 基于脚手架编写项目

Vue.js学习笔记_第42张图片
Vue.js学习笔记_第43张图片
在这里插入图片描述

Vue.js学习笔记_第44张图片

用webstrom 上面创建好的工程
Vue.js学习笔记_第45张图片
端口号可以自己修改

打开项目后可以在ws的Terminal平台上进行项目运行 如果输入npm run dev 出现“不是内部或者。。。命令”可以查看一下ws的setting中Node.js是否配置了node 如果配置完成后,重新启动项目还是不行 那么试试以管理员方式运行
Vue.js学习笔记_第46张图片

  • components:{App}
    Vue.js学习笔记_第47张图片
    开始要创建项目了
  1. mian.js
    入口的js import 是引入实例
/*入口js:: 创建Vue实例*/
import  Vue from 'vue' // 导包
import  App from './App.vue' // 导包
 new Vue({
     
  el:'#app',
  components:{
     
    App
  }, // 将组件映射成为指定名称的标签,相当于{App:App}
  template:'' // 模板插入到el所用
})

  1. App.vue
<!--根组件-->
<template>
  <div>
<img class="logo" src="./assets/2.jpg"/>
<HelloWorld/>
  </div>
</template>
<script>
//1. 引入组件
  import  HelloWorld from './components/HelloWorld.vue'
  export  default  {
     
    /*2. 映射组件标签*/
    components:{
     
      HelloWorld
    }
  }

</script>
<style>
  .logo{
     
    width: 500px;
    height: 800px;
  }

</style>

  1. HelloWorld.vue
<template>
    <div>
         <p class="msg">{
     {
     msg}}</p>
    </div>
</template>
<script>
    export default {
       //配置对象与Vue一致
         data(){
        //data可以写对象也可以写函数,但是在组件中必须写函数
             return{
     
               msg:"Hello Vue Component"
                    }
                }
    }
</script>
<style>
.msg{
     
  color:black;
  font-size: 30px;
}
</style>

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuedome</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

Vue.js学习笔记_第48张图片
template:是使用组件标签
main.js中的el 元素指的是 index.html中的id

  • 项目写完后需要进行运行
    在cmd框中输入 npm run dev 进行运行

2.3 打包发布项目

  1. 打包: npm run build
  2. 发布1:使用静态服务器工具包(安装静态服务器)
    a. npm install -g serve
    在这里插入图片描述
    b. serve dist
    c. 访问:
    Vue.js学习笔记_第49张图片- 2. 使用动态web服务器(tomcat)
    修改配置 webpack.prod.conf.js
    Vue.js学习笔记_第50张图片
    进行重新的打包编译
    npm run build
    然后将目录结构下的dist 文件复制下来 改名到tomcat的webapp目录下
    Vue.js学习笔记_第51张图片
    注意:此名字必须与上面配置文件中修改的一样
    然后进行服务器的运行和工程的访问即可
    http://localhost:8080/vue_demo/

2.4 vue_Eslint编码规范检查

  • 说明:
  1. ESLint是一个代码规范检查工具
  2. 它规定了特定的规则
  3. 基本已经替代了以前的JSlint
  • ESLint 提供以下支持
    1.ES
    2.JSX
    3.style 检查
    4.自定义错误和提示
  • ESLint 提供以下几种校验
  1. 语法错误校验
  2. 不重要或丢失的标点符号,如分号
  3. 没法运行到的代码块(使用过 WebStorm 的童鞋应该了解)
  4. 未被使用的参数提醒
  5. 确保样式的统一规则,如 sass 或者 less
  6. 检查变量的命名
  • 规则的错误等级有三种
  1. 0:关闭规则。
  2. 1:打开规则,并且作为一个警告(信息打印黄色字体)
  3. 2:打开规则,并且作为一个错误(信息打印红色字体)
  • 相关配置文件
  1. .eslintrc.js: 全局规则配置文件 ‘rules’:{ ‘no-new’:1 }
  2. 在 js/vue 文件中修改局部规则 /eslint-disableno-new/ newVue({ el:‘body’, components:{App} })
  3. .eslintignore: 指令检查忽略的文件 *.js *.vue
  • 修改规则
    Vue.js学习笔记_第52张图片
  • 组件的含义
    Vue.js学习笔记_第53张图片

2.5 组件间的相互通信(1)

Props

2.5.1 练习一

2.5.1.1添加功能
  1. 首先将页面拆分开来
    Vue.js学习笔记_第54张图片Vue.js学习笔记_第55张图片
    Vue.js学习笔记_第56张图片
  2. 编写main.js
/*
创建vue实例
 */
import  Vue from  'vue'
import  App from  './App.vue'
new Vue({
     
  el:'#app',/*这里需要和index界面的div的id一样*/
  components:{
     /*相当于是注册组件*/
    App
  },
  template:''//使用组件
})

App.vue

<template>
  <div>
    <header class="site-header jumbotron">
      <div class="container">
        <div class="row">
          <div class="col-xs-12">
            <h1>请发表对kunkun的评论</h1>
          </div>
        </div>
      </div>
    </header>
    <div class="container">
      <Add :addComment="addComment"/><!--将此方法传递给子组件-->
      <list :comments="comments"/>
    </div>
  </div>
</template>

<script>
  import Add from './components/Add.vue'
  import  List from './components/List.vue'
    export default {
     
    data(){
     
      return {
     
        comments:[   /*组件间的相互通信最好同名 数据在那个组件,更新数据的行为就在那个组件*/
          {
     
            name:"张菁",
            content:"偶有还不错哦哦"
          },{
     
          name:"张十八",
            content:"张菁说得对"
          },{
     
          name:"宋十五",
            content:"滑行吧"
          }
        ]
      }
    },
      methods:{
     
      addComment(comment){
     
        this.comments.unshift(comment);
      }
      },
    components:{
     
      Add,
      List
    }
    }

</script>

<style>

</style>

add.vue

<template>

    <div class="col-md-4">
      <form class="form-horizontal">
        <div class="form-group">
          <label>用户名</label>
          <input type="text" class="form-control" placeholder="用户名" v-model="name"><!--自动收集数据 <input v-model="data" />-->
        </div>
        <div class="form-group">
          <label>评论内容</label>
          <textarea class="form-control" rows="6" placeholder="评论内容" v-model="content"></textarea>
        </div>
        <div class="form-group">
          <div class="col-sm-offset-2 col-sm-10">
            <button type="button" class="btn btn-default pull-right" @click="add">提交</button>
          </div>
        </div>
      </form>
    </div>
</template>

<script>
    export default {
     
      props:{
     
        addComment:{
     /*要求指定的东西有属性名、属性值的类型和必要性*/
          type:Function,
          required:true,

        }
      },
      data(){
     
        return{
     
          name:'',
          content:''
        }
      },
      methods:{
     
        add (){
     
          /*检查输入的合法性*/
            const name=this.name.trim();
            const content=this.content.trim();
            if(!name||!content){
     
              alert("为写入数据");
              return null;
          }
            /*根据输入的数据,封装成comment对象*/
           const  comment={
     
             name,
             content
           }
          /*添加到comments对象中*/
           this.addComment(comment);
           /*清除输入*/
            this.name='';
            this.content='';
        }
      }
    }
</script>

<style>

</style>

list.vue

<template>
  <div class="container">
  <div class="col-md-8">
    <h3 class="reply">评论回复:</h3>
    <h2 style='display: none'>暂无评论,点击左侧添加评论!!!</h2>
    <ul class="list-group">
      <Item v-for="(comment,index) in comments" :key="index" :comment="comment"/>
    </ul>
  </div>
  </div>
</template>

<script>
  import Item from './Item'
    export default {
     
      /*声明接受属性 这个属性就会成为组件对象的属性  模板中可以直接使用*/
      props:['comments'],
      components:{
     
        Item
      }
    }
</script>

<style>
  .reply {
     
    margin-top: 0px;
  }

</style>

item.vue

<template>
<div>
  <li class="list-group-item">
    <div class="handle">
      <a href="javascript:;">删除</a>
    </div>
    <p class="user"><span >{
     {
     comment.name}}</span><span>:</span></p>
    <p class="centence">{
     {
     comment.content}}</p>
  </li>
</div>
</template>

<script>
    export default {
     
      props:{
     /*指定属性名和属性值类型*/
        comment:Object
      }
    }
</script>

<style>
  li {
     
    transition: .5s;
    overflow: hidden;
  }

  .handle {
     
    width: 40px;
    border: 1px solid #ccc;
    background: #fff;
    position: absolute;
    right: 10px;
    top: 1px;
    text-align: center;
  }

  .handle a {
     
    display: block;
    text-decoration: none;
  }

  .list-group-item .centence {
     
    padding: 0px 50px;
  }

  .user {
     
    font-size: 22px;
  }
</style>
  • 注意:

    1. 数据在哪个组件,更新数据的行为就在哪个组件
      比如:父组件的数据要给子组件或者子组件需要获取到父组件的数据,则应该将方法写在父组件中
      Vue.js学习笔记_第57张图片
      Vue.js学习笔记_第58张图片
    1. 组件间的相互通信组好同名
      将comments数据传递给

在这里插入图片描述

    1. 子组件获取父组件的数据
      a.
      Vue.js学习笔记_第59张图片
      b. 在这里插入图片描述
      c. Vue.js学习笔记_第60张图片
    1. 自动收集数据
      Vue.js学习笔记_第61张图片
    1. 将父组件中的数据传递给子组件进行遍历
      在这里插入图片描述Vue.js学习笔记_第62张图片
2.5.1.2 删除功能
    1. 首先需在App.vue编写删除函数
      Vue.js学习笔记_第63张图片
    1. 将函数传递给字组件
      Vue.js学习笔记_第64张图片
    1. List组件进行接收函数
      然后将此函数继续向下传递,注意index是数组的下标也需要传递
      Vue.js学习笔记_第65张图片
    1. 在item.vue中进行接收并调用
      在这里插入图片描述

2.5.2 练习二

Vue.js学习笔记_第66张图片

2.5.2.1 基本功能

App.vue

<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <!---->
<TodoHeader :addTodo="addTodo" />
      <!---->
<TodoList :todos="todos" :delTodo="delTodo"/>
      <!---->
<TodoFooter :todos="todos" :deleteCompleteTodos="deleteCompleteTodos" :selectAllTodos="selectAllTodos"/>

    </div>
  </div>
</template>

<script>
  import  TodoHeader from './components/TodoHeader.vue'
  import  TodoFooter from './components/TodoFooter.vue'
  import  TodoList from './components/TodoList.vue'
  export default {
     
    data(){
     
      return {
     
        todos:[
          {
     tittle:"吃饭",complete:false},
          {
     tittle:"睡觉",complete:true},
          {
     tittle:"打豆豆",complete:false}

        ]
      }
    },
    methods:{
     
      /*添加todo*/
      addTodo(todo){
     
        this.todos.unshift(todo);
      },
      /*删除选中的todo*/
      delTodo(index){
     
        this.todos.splice(index,1);
      },
/*
      删除所有选中的todo
*/
      deleteCompleteTodos(){
     
              this.todos=this.todos.filter(todo=>!todo.complete);

      },
      /*全选或者全部选*/
      selectAllTodos(isCheck){
     
this.todos.forEach(todo=>todo.complete=isCheck);
      }
    },

    components:{
     
      TodoHeader,TodoFooter,TodoList
    },


  }

</script>

<style>
  .todo-container {
     
    width: 600px;
    margin: 0 auto;
  }
  .todo-container .todo-wrap {
     
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
</style>


TodoList.vue

<template>
  <ul class="todo-main">
    <TodoItem v-for="(todo,index) in todos " :key="index" :todo="todo" :index="index" :delTodo="delTodo"/>
  </ul>
</template>

<script>
  import  TodoItem from './TodoItem.vue'
    export default {
     
    components:{
     
      TodoItem
    },
      props:{
     
        todos:Array,
        delTodo:Function
      }
    }
</script>

<style>
  .todo-main {
     
    margin-left: 0px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding: 0px;
  }

  .todo-empty {
     
    height: 40px;
    line-height: 40px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding-left: 5px;
    margin-top: 10px;
  }
  /*item*/
  li {
     
    list-style: none;
    height: 36px;
    line-height: 36px;
    padding: 0 5px;
    border-bottom: 1px solid #ddd;
  }

  li label {
     
    float: left;
    cursor: pointer;
  }

  li label li input {
     
    vertical-align: middle;
    margin-right: 6px;
    position: relative;
    top: -1px;
  }

  li button {
     
    float: right;
    display: none;
    margin-top: 3px;
  }

  li:before {
     
    content: initial;
  }

  li:last-child {
     
    border-bottom: none;
  }

</style>


TodoItem.vue


<template>
    <div>
<!--      进入内部元素 以后onmouseout会执行   出内部元素 onmouseover 会执行
      <li onmouseenter="" onmouseleave="" onmouseover="" onmouseout="">-->
      <li @mouseenter="handleShow(true)"   @mouseleave="handleShow(false)" :style="{background: bgColor}">
        <label>
          <input type="checkbox" v-model="todo.complete"/>
          <span>{
     {
     todo.tittle}}</span>
        </label>
        <button class="btn btn-danger" v-show="isShow" @click="deleteItem">删除</button>
      </li>
    </div>
</template>

<script>
    export default {
     
        props: {
     
          todo: Object,
          index: Number,
          delTodo:Function
        },
      data(){
     
          return{
     
            bgColor:'white',/*默认的背景颜色*/
            isShow:false   /*按钮是否展示*/
          }
      },
      methods:{
     

        handleShow(bool){
     
          if(bool){
     
            this.bgColor="#aaaaaa",
              this.isShow=true
          }else{
     
            this.bgColor="white",
              this.isShow=false
          }
        },
        deleteItem(){
     
          const {
     todo,index,delTodo}=this;
          var result=todo.tittle;
          if(window.confirm('确认删除'+result+'吗?')){
     
            delTodo(index);
          }
        }
      }
    }
</script>

<style>

</style>

TodoHeader.vue

<template>
  <div class="todo-header">
    <input type="text" placeholder="请输入你的任务名称,按回车键确认" v-model="tittle" @keyup.enter="addItem"/>
  </div>
</template>

<script>
    export default {
     
      props:{
     
        addTodo:{
     
          type:Function,
          required:true
        }
      },
      data(){
     
        return {
     
          tittle:''
        }
      },
      methods:{
     
        addItem(){
     
           /* 1.检查输入的合法性*/
         const tittle=this.tittle.trim();
         if(!tittle){
     
           alert("请您输入信息后在进行提交");
           return null;
         }

          /*2. 根据输入生成一个todo对象*/
               const todo={
     
                 tittle,
                 complete:false
               }
          /*3.  添加到todos数组中*/
          this.addTodo(todo);
          /*4. 清除输入*/
          this.tittle='';
        }
      }
    }
</script>

<style>
  .todo-header input {
     
    width: 560px;
    height: 28px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 4px 7px;
  }

  .todo-header input:focus {
     
    outline: none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
  }
</style>

TodoFooter.vue

<template>
  <div class="todo-footer">
    <label>
      <input type="checkbox" v-model="isAllCheck"/>
    </label>
    <span>
          <span>已完成{
     {
     completeSize}}</span> / 全部{
     {
     todos.length}}
        </span>
    <button class="btn btn-danger" v-show="completeSize" @click="deleteCompleteTodos">清除已完成任务</button>
  </div>
</template>

<script>
    export default {
     
      props: {
     
        todos: Array,
        deleteCompleteTodos: Function,
        selectAllTodos: Function
      },
      computed:{
     
        completeSize(){
     
          return this.todos.reduce((preTotal,todo)=>preTotal+(todo.complete?1:0),0);
        },
        isAllCheck:{
     
          get(){
     
            return this.completeSize==this.todos.length && this.completeSize>0;
          },
          set(vlaue){
     /*vlaue是当前checkbox最新的值*/
            this.selectAllTodos(value);
          }
        }
      }
    }
</script>

<style>
  .todo-footer {
     
    height: 40px;
    line-height: 40px;
    padding-left: 6px;
    margin-top: 5px;
  }

  .todo-footer label {
     
    display: inline-block;
    margin-right: 20px;
    cursor: pointer;
  }

  .todo-footer label input {
     
    position: relative;
    top: -1px;
    vertical-align: middle;
    margin-right: 5px;
  }

  .todo-footer button {
     
    float: right;
    margin-top: 5px;
  }

</style>

注意:

    1. 注意计算属性的用法
      a.你定义的 b.执行了 c.你没有调用

Vue.js学习笔记_第67张图片

Vue.js学习笔记_第68张图片

    1. Es6新标准的用法
    1. reduce函数
      reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
      reduce(callback,initiaValue)会传入两个变量,回调函数(callback)和初始值(initiaValue)
    1. === 称为等同符,当两边值的类型相同时,直接比较值,若类型不相同,直接返回false
2.5.2.2 存储数据

将浏览器上输入数据的结果以文件的形式保存在电脑上。

    1. JSON.parse 方法用于将一个 JSON 字符串转换为对象。 JSON.parse( || )如果是空字符串将会执行|| 后面的语句
    1. localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。
    1. 深度监视:一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。)
    1. JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串
      Vue.js学习笔记_第69张图片产生的效果就是 浏览器上对数据的修改 会进行保存

2.6 组件间的相互通信(2)- 自定义事件

  • 父组件通过使用prop传递数据给子组件
  • 子组件只能通过Vue自定义事件系统将数据传递给父组件
    每个Vue实例都实现了事件接口:
    a. 使用 $ on(eventName)监听事件
    b. 使用 $ emit(eventName,data )触发事件
    在这里插入图片描述

父组件可以在使用子组件的地方直接使用v-on来监听子组件触发的事件
不能用$on监听子组件释放事件,而必须在模板里直接用v-on绑定

2.6.1 @事件名=‘事件名’

父组件:
Vue.js学习笔记_第70张图片
子组件
Vue.js学习笔记_第71张图片注意: 这种方式只能在父子组件之间传递
此方法用来代替函数属性

2.6.2 利用js代码进行事件的绑定

Vue.js学习笔记_第72张图片
js:
Vue.js学习笔记_第73张图片
子组件:
在这里插入图片描述

2.7 组件间的相互通信(3)-消息的订阅与发布

  • 1.这个需要下载内库
//下载
npm install --save pubsub-js
//查看版本信息
npm info pubsub-js

注意:

  • 消息的订阅与发布需要引用pubsub.js这个库,哪个vue需要用到消息订阅与发布就需要import
  • 因为消息的订阅与发布是异步的所以需要放在mounted中进行执行
  • 绑定事件监听== 订阅消息
    触发事件==发布消息

订阅消息:
Vue.js学习笔记_第74张图片
Vue.js学习笔记_第75张图片

   //订阅消息
     PubSub.subscribe('delTodo',(msg,index) =>{
        //这个msg相当于是前面的函数名   index相当于是函数的参数
              this.delTodo(index);
     })
  //   用了箭头函数相当取消本函数内的this对象,要找this只能在外面找

发布消息:
Vue.js学习笔记_第76张图片
Vue.js学习笔记_第77张图片

   //发布消息
            PubSub.publish('delTodo',index);  
//第一个参数是调用的函数名,第二个参数是给函数传递的参数

消息的订阅与发布:好处是组件间传递信息时没有关系限制,父子 祖孙 或者兄弟之间皆可

2.8 组件间的相互通信slot

此方法用于父组件向子组件传递‘标签数据’
1. 此方法只能传递标签,不可以进行数据及参数的传递
2. 此方法中所有标签属性用到的函数方法及参数需要在父组件中

父组件中: 在这里插入图片描述注意:所有子组件中的数据用到的方法都必须 Vue.js学习笔记_第78张图片

子组件:
Vue.js学习笔记_第79张图片

2.9 数据存储优化

将方法写在外部:
Vue.js学习笔记_第80张图片在vue中进行导包:
Vue.js学习笔记_第81张图片调用:
Vue.js学习笔记_第82张图片
Vue.js学习笔记_第83张图片

3. Vue-ajax

3.1 vue项目中的常用的2个ajax库

3.1.1 vue-resource

vue插件 非官方库

3.1.2 axios

通用的ajax请求库,官方推荐

3.2 vue-resource的使用

  • 下载
    npm install vue-resource -save
<template>
  <div>
    <div v-if="!repoUrl">Loading!!!</div>
    <div v-else="repoUrl">most star repo is <a :href="repoUrl">{
     {
     repoName}}</a></div>
  </div>
</template>

<script>
export  default {
     
  data(){
     
    return{
     
      repoUrl:'',
      repoName:''
    }
  },
  mounted(){
     
    //发送ajax请求获取数据  https://api.github.com/search/repositories?q=v&sort=stars
    const url='https://api.github.com/search/repositories?q=v&sort=stars';
  this.$http.get(url).then(
      response=>{
     
      const  result=response.data;
      //得到最受欢迎的repo
        const  mostRepo=result.items[0];
        this.repoUrl=mostRepo.html_url;
        this.repoName=mostRepo.name;
    }, reponse=>{
     
            alert("请求失败");
    })
  }
}
</script>
<style>
</style>

3.3 vue-axios的使用

  • 下载
    npm install vue-axios --save
<template>
  <div>
    <div v-if="!repoUrl">Loading!!!</div>
    <div v-else="repoUrl">most star repo is <a :href="repoUrl">{
     {
     repoName}}</a></div>
  </div>
</template>

<script>
  import  axios from 'axios'
export  default {
     
  data(){
     
    return{
     
      repoUrl:'',
      repoName:''
    }
  },
  mounted(){
     
    //发送ajax请求获取数据  https://api.github.com/search/repositories?q=v&sort=stars
    const url='https://api.github.com/search/repositories?q=v&sort=stars';
 
    //使用axios发送ajax请求
    axios.get(url).then( response=>{
     
      const  result=response.data;
      //得到最受欢迎的repo
      const  mostRepo=result.items[0];
      this.repoUrl=mostRepo.html_url;
      this.repoName=mostRepo.name;
    }).catch(error=>{
     
      alert("失败了");
    })
  }
}
</script>
<style>
</style>

3.3 vue-anxios实践

  • App.vue
<template>
  <div id="app">
    <div class="container">
     <Search/>
      <UserMain/>
    </div>
  </div>
</template>

<script>
  import Search from './compontents/Search.vue'
  import Main from './compontents/Main.vue'
  export default {
     

    components:{
     
      Search,
      UserMain:Main  /*可以起别名*/
    }
  }
</script>
<style>
</style>

  • Search.vue
<template>
 <section class="jumbotron">
   <h3 class="jumbotron-heading">Search Github Users</h3>
   <div>
     <input type="text" placeholder="enter the name you search" v-model="searchName"/>
     <button @click="search">Search</button>
   </div>
 </section>
</template>

<script>
 import  PubSub from 'pubsub-js'
   export default {
     
     data(){
     
       return {
     
         searchName:''
       }
     },
     methods:{
     
       search(){
     
         const  searchName=this.searchName.trim();
         if(searchName){
     
           //发布搜索的消息
           PubSub.publish('search',searchName);
           alert(searchName);
         }
       }
     }
   }
</script>

<style>

</style>

  • Main.vue
<template>
  <div>
  <h2 v-if="firstView">输入用户名搜索</h2>
  <h2 v-else-if="loading">LOADING...</h2>
  <h2 v-else-if="errorMsg">{
     {
     errorMsg}}</h2>
  <div class="row">
    <div class="card" v-for="(user,index) in users" :key="index">
      <a :href="user.url" target="_blank">
        <img :src="user.avatarUrl" style='width: 100px'/>
      </a>
    <p class="card-text">{
     {
     user.name}}</p>
    </div>
  </div>
  </div>
</template>
<script>
  import  PubSub from 'pubsub-js'
  import  axios from 'axios'

export default {
     
    data(){
     
      return {
     
           firstView:true,
           loading:false,
           users:null,  /*{url avatar_url name}*/
           errorMsg:''
      }
    },
      mounted(){
     
      //是否在此发ajax请求   不是,而是在点击search之后
        //订阅搜索的消息
        PubSub.subscribe('search',(msg,searchName)=>{
     
          //说明需要发ajax请求进行搜索

          //更新状态(请求中的状态)
           this.firstView=false,
             this.loading=true,
             this.users=[],
             this.errorMsg=''
          //发ajax请求
          const  url=`https://api.github.com/search/users?q=${
       searchName}`
          axios.get(url).then(response=>{
     
            const  result=response.data;
              const users=result.items.map(item=>({
     
              url:item.html_url,
              avatarUrl:item.avatar_url,
              name:item.login,
            }));
            //成功,更新成功的状态
            this.users=users;
            this.loading=false;
          }).catch(error=>{
     
            //失败
            this.loading=false;
            this.errorMsg="请求失败";
          })
        })
      }
    }
</script>
<style>
  .card {
     
    float: left;
    width: 33.333%;
    padding: .75rem;
    margin-bottom: 2rem;
    border: 1px solid #efefef;
    text-align: center;
  }
  .card > img {
     
    margin-bottom: .75rem;
    border-radius: 100px;
  }
  .card-text {
     
    font-size: 85%;
  }

</style>

Vue.js学习笔记_第84张图片

4. Vue路由

通过 Vue.js 可以实现多视图的单页Web应用
路由的含义:
一种映射关系 key–value
key:path
value:处理请求的回调函数(后台路由);组件(前台路由)
下载:npm install vue-router --save
在这里插入图片描述

4.1相关Api说明:

  1. VueRouter(): 用于创建路由器的构建函数
    new VueRouter({
    // 多个配置项
    })
  2. 路由配置
    routes: [ {
    // 一般路由
    path: ‘/about’,
    component: About
    },
    {
    // 自动跳转路由
    path: ‘/’,
    redirect: ‘/about’
    } ]
  3. 注册路由器
    import router from ‘./router’
    new Vue({
    router
    })
  4. 使用路由组件标签
 1. <router-link>: 用来生成路由链接
  <router-link to="/xxx">Go to XXX</router-link>
 2. <router-view>: 用来显示当前路由组件界面
  <router-view></router-view>

4.2 基本路由

使用路由的基本步骤:

  1. 定义路由组件
  2. 注册路由
  3. 使用路由

  • main.js
import Vue from 'vue'
import App from './App.vue'
import  router from './router'   /*默认暴露可以用任何名字*/

new Vue({
     //配置对象的属性名都是一些确定的名称,不能随便修改
 el:'#app',
 components:{
     App},
 template:'',
 router
})
  • App.vue
<template>
 <div>
   <div class="row">
     <div class="col-xs-offset-2 col-xs-8">
       <div class="page-header"><h2>Router Test</h2></div>
     </div>
   </div>

   <div class="row">
     <div class="col-xs-2 col-xs-offset-2">
       <div class="list-group">
         <!--生成路由链接-->
         <router-link to="/about" class="list-group-item">About</router-link>
         <router-link to="/home" class="list-group-item">Home</router-link>
       </div>
     </div>
     <div class="col-xs-6">
       <div class="panel">
         <div class="panel-body">
           <!--显示当前组件-->
          <router-view ></router-view>
         </div>
       </div>
     </div>
   </div>
 </div>
</template>

<script>

 export default {
     
 }
</script>
<style>
</style>

4.3嵌套路由

  • index
/*
* 路由器模块
* */
import Vue from 'vue'
import  VueRouter from 'vue-router'
import About from '../views/About.vue'
import Home from '../views/Home.vue'
import News from '../views/News.vue'
import  Message from '../views/Message.vue'
Vue.use(VueRouter);
export  default new VueRouter({
     
//n个路由
  routes: [
    {
     
      path: '/about',
      component: About,
    },
    {
     
      path: '/home',
      component: Home,
      children:[
        {
     
          /*path:'/News',//  path最左侧的/永远代表跟路由  直接写/News不对
          */
          path:'/home/News',
          /*path:'News',   简化写法*/
          component:News,

        },
        {
     
          path:'Message',
          component:Message
        },
        {
     
          path:'',
          redirect:'News'
        }

      ]
    },
    {
     
      path:'/',
      redirect:'/about'
    }
  ]
})

path:'/News',// path最左侧的/永远代表跟路由 直接写/News不对
path:'News', 简化写法 代表本级目录下的文件

4.4 缓存路由组件对象

是什么:

  1. 默认情况下, 被切换的路由组件对象会死亡释放, 再次回来时是重新创建的
  2. 如果可以缓存路由组件对象, 可以提高用户体验

编码实现:

<keep-alive>
 <router-view></router-view> 
 </keep-alive>

Vue.js学习笔记_第85张图片
Vue.js学习笔记_第86张图片

4.4 路由组件传递数据

  • 路由路径携带参数
    (1). 配置路由:
  children:[{
     
            path:'/home/message/detail/:id',
            component:MessageDetail
          }]

(2). 路由路径:

   <li v-for="(message,index) in messages" :key="message.id" >
            <router-link :to="`/home/message/detail/${message.id}`"> <a >{
     {
     message.tittle}}</a></router-link>
 </li>

(3) 路由组件中读取请求参数
this.$route.params.id
index.js

/*
* 路由器模块
* */
import Vue from 'vue'
import  VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import  Message from '../views/Message.vue'
import MessageDetail from '../views/MessageDetail.vue'
Vue.use(VueRouter);
export  default new VueRouter({
     
//n个路由
  routes: [
    {
     
      path: '/home',
      component: Home,
      children:[
        {
     
          path:'/home/News',
          component:News,
        },
        {
     
          path:'Message',
          component:Message,
          children:[  重点:
            path:'/home/message/detail/:id',
            component:MessageDetail
          }]
        }
      ]
    }
  ]
})

message.vue

<template>
    <div>
       <ul>
         <li v-for="(message,index) in messages" :key="message.id" >
            <router-link :to="`/home/message/detail/${message.id}`"> <a >{
     {
     message.tittle}}</a></router-link>  //注意符号``
         </li>
        </ul>
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
     
      data(){
     
        return{
     
          messages:[]
        }
      },
      mounted(){
     
        //模拟ajax请求从后台获取数据
        setTimeout(()=>{
     
           const messages=[{
     
             id:1,
             tittle:'message001',
           },
             {
     
               id:2,
               tittle:'message002',
             },
             {
     
               id:3,
               tittle:'message003'
             }
           ]
          this.messages=messages;
    },1000);

      }
    }
</script>

<style>

</style>

MessageDetail.vue:

<template>
<div>
  <ul>
    <p>ID:{
     {
     $route.params.id}}</p>
    <li>id:{
     {
     messageDetail.id}}</li>
    <li>tittle:{
     {
     messageDetail.tittle}}</li>
    <li>content:{
     {
     messageDetail.content}}</li>
  </ul>
</div>
</template>

<script>
  export  default {
     
    data(){
     
      return {
     
        messageDetail:{
     },
      }
    },
    mounted(){
     
      setTimeout(()=>{
     
        const allMessageDetails=[{
     
          id:1,
          tittle:'message001',
          content:"massage001Content"
        },
          {
     
            id:2,
            tittle:'message002',
            content:"massage002Content"
          },
          {
     
            id:3,
            tittle:'message003',
            content:"massage003Content"
          }];
        this.allMessageDetails=allMessageDetails;
        const id=(this.$route.params.id)*1;       this.messageDetail=allMessageDetails.find(detail=>detail.id===id)   //filter 过滤产生的数据类型是数组类型的
                                                                            //find 查找满足条件的某一个
      },1000)
    },
    watch:{
     //点击路由连发生改变后,进行修改
      $route:function (value) {
     //路由路径发生改变
        const id=(value.params.id)*1;
        this.messageDetail=this.allMessageDetails.find(detail=>detail.id===id)
      }
    }
  }
</script>
<style>
</style>
  • 属性携带数据


接收参数:
Vue.js学习笔记_第87张图片

4.5 编程式路由导航

栈的结构进行

  1. 默认情况下, 被切换的路由组件对象会死亡释放, 再次回来时是重新创建的
  2. 如果可以缓存路由组件对象, 可以提高用户体验
    $.router 代表路由器
    $.route 代表当前组件

相关 API :

1) this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面) 
2) this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面) 
3) this.$router.back(): 请求(返回)上一个记录路由 
4) this.$router.go(-1): 请求(返回)上一个记录路由 
5) this.$router.go(1): 请求下一个记录路由
<template>
   <div>
      <ul>
        <li v-for="(message,index) in messages" :key="message.id" >
           <router-link :to="`/home/message/detail/${message.id}`"> <a >{
     {
     message.tittle}}</a></router-link>
          <button @click="pushShow(message.id)">push查看</button>
          <button @click="replaceShow(message.id)">replace查看</button>
        </li>
       </ul>
     <button @click="$router.back()">回退</button>
     <hr>
       <router-view></router-view>
   </div>
</template>

<script>
   export default {
     
     data(){
     
       return{
     
         messages:[]
       }
     },
     mounted(){
     
       //模拟ajax请求从后台获取数据
       setTimeout(()=>{
     
          const messages=[{
     
            id:1,
            tittle:'message001',
          },
            {
     
              id:2,
              tittle:'message002',
            },
            {
     
              id:3,
              tittle:'message003'
            }
          ]
         this.messages=messages;
   },1000);

     },
     methods:{
     
       pushShow(id){
     
         this.$router.push(`/home/message/detail/${
       id}`)
       },
       replaceShow(id){
     
         this.$router.replace(`/home/message/detail/${
       id}`)
       }
     }
   }
</script>

<style>

</style>

你可能感兴趣的:(前端学习笔记,vue.js)