Vue.js学习笔记 Vue基本语法篇

文章目录

前言

本篇博客是在学习技术胖-Vue3.x从零开始学-第一季 基础语法篇过程中记录整理的笔记,若文章中出现相关问题,请指出!

  • 当前该链接失效了,有需要的小伙伴可以去b站或者技术胖官网去找相应的视频与笔记。

所有博客文件目录索引:博客目录索引(持续更新)

vscode的vue.js插件:Vue 3 Snippets

1、基础学习

1.1、第一个vue:helloworld(template以及mount()使用)

<body>
  <div id="app">
  </div>
    
  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    Vue.createApp({  //创建一个Vue实例
      template: '<div>Hello world!</div>'   //template表示模板
    }).mount("#app");  //挂载到`id=app`的DOM上
  </script>
</body>

目的:将指定的模板以HTML形式挂载到指定id的dom节点上,通过Vue的createApp(xxx)得到的对象(需要传入一个对象,该对象中的属性template表示的是模板),接着调用mount(id=xxx)进行挂载指定。



1.2、编写计数器(mounted应用)

面向DOM编程 =》 面向数据编程

目标:进行dom挂载以及使用定时器,从而完成计数器的实现!

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    Vue.createApp({
      data() {   //data表示数据属性,用于返回数据的
        return {
          counter: 1
        }
      },
      mounted() {  //该属性就是自动执行函数,可在其中编写计数器
        setInterval(() => {
          this.counter++;//此时其中的this指的就是该对象中的counter
        }, 1000);
      },
      template: "<p>{{counter}}</p>"    //指定的模板
    }).mount("#app");
  </script>
</body>

mounted的是一个声明周期钩子函数,页加载渲染完成,自动执行的方法就可以!

效果:将指定的模板挂载到div元素里,接着会自动执行定时器,来对counter进行每秒+1。

GIF



1.3、vue的绑定事件和事件方法(v-on:xxx以及methdos属性使用)

直接使用案例来应用

为挂载上去的模板添加单击事件以及使用methdos属性来申明多个函数(给单击事件用):

  1. createApp()中传入的对象里添加一个methods属性,该属性为对象可包含多个函数方法。
  2. 在指定的DOM元素上添加v-on:click = "xxx" (函数名),用于为指定的dom节点绑定事件。
<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    Vue.createApp({
      data() {
        return {
          content: '欢迎你的光临,贵宾一位!'
        }
      },
      //1、methods属性:对象中包含了多个函数方法,其中来进行操作content
      methods: {
        welcomeBtnClick() {
          this.content = "欢迎你的光临,贵宾一位!";
        },
        byeBtnClick() {
          this.content = "欢迎下次光临,真空套餐下次8折优惠";
        }
      },
      //2、v:on:xxx   表示在该dom元素上绑定事件
      template: `<div>
                  <div>{{content}}</div>
                  <button v-on:click='welcomeBtnClick'>有顾客来</button>&nbsp;      
                  <button v-on:click='byeBtnClick' >顾客离开</button>
                </div>`
    }).mount("#app");
  </script>
</body>

GIF

总结:对于事件的创建,我们可以直接通过在dom元素上设置v-on:xxx 的形式来绑定事件,事件执行函数可以写在methods对象中!



1.4、显示隐藏套餐服务(v-if使用)

目的:通过v-if与按钮点击来显示与隐藏dom元素!

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    Vue.createApp({
      data() {
        return {
          //setMeal:表示需要显示的字符串  isShowMeal:用于控制字符串的显示,布尔值
          setMeal: '真空套餐  帝王套餐  夏日套餐 学生套餐',
          isShowMeal: true
        }
      },
      methods: {
        //点击事件,让isShowMeal属性在true与false之间切换
        showOrHideBtnClick() {
          this.isShowMeal = !this.isShowMeal;
        }
      },
      //重点:v-if:需要传入一个布尔值(应当是data中的可以随时能够响应),目的是用于控制该dom元素的显示与隐藏
      //下面的绑定单击事件就不需要多说了!
      template: `<div>
                  <div>
                    <div v-if="isShowMeal">{{setMeal}}</div>
                    <button v-on:click="showOrHideBtnClick">显示/隐藏 套餐</button>
                  </div>
                </div>`
    }).mount("#app");
  </script>
</body>

GIF

image-20210701142505824

总结:对于v-if应当搭配data属性中的指定属性值来进行实时判断,一旦指定属性值修改为true或false来达到控制dom元素展示与隐藏的效果!!!



1.5、vue列表与循环(v-for)

目的:如何进行循环展示和双向数据绑定。

方式:通过使用v-for="(item,index) in 可遍历对象",来达到生成多个标签以及绑定数据效果!

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    Vue.createApp({
      data() {
        return {
          list: ['1-大脚', '2-刘英', '3-晓红']
        }
      },
      methods: {
        addOneToList() {
          this.list.push('佳丽');
        }
      },
      // 列表遍历(和后端特别像,遍历形式生成多个li标签并进行渲染)
      //v-for = "(item,index) in 可遍历对象":通过该种方式能够得到对应的值以及索引
      template: `
          <ul>
            <li v-for="(item,index) in list">值:{{item}}&nbsp;&nbsp;&nbsp;&nbsp;索引:{{index}}</li>
            <button v-on:click="addOneToList">增加一个佳丽</button>
          </ul>
      `
    }).mount("#app");
  </script>

</body>

效果:

GIF

总结:对于v:for能够进行遍历指定的data数据中的可遍历对象,并且根据可遍历对象的数量来生成指定的dom元素以及数据绑定,并且若是你修改了该数据就会让页面上的数据达到实时更新的效果!



1.6、动态添加指定值并显示在页面中(v-model绑定输入数据)

目的:通过一个输入框,一个按钮,点击按钮时就能够将输入框中的内容添加到列表中并实时显示!

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    Vue.createApp({
      data() {
        return {
          inputVal: '',   //配合下面input标签中的v-model来监听输入的值到inputval
          list: []       //配合下面函数addOneToList去添加inputval值到list数组中
        }
      },
      methods: {
        addOneToList() {
          this.list.push(this.inputVal);
        }
      },
      //v-model(重点):负责监听用户的输入事件以更新数据,例如键盘输入事件等等
      //input标签注释:一旦输入完毕就会更新data对象中的属性inputVal值
      //button标签注释:点击按钮,将inputVal添加到list数组中,此时改数组更新了联动带着v-for进行更新!!!
      template: `
          <ul>
            <li v-for="(item,index) in list">值:{{item}}&nbsp;&nbsp;&nbsp;&nbsp;索引:{{index}}</li>
          </ul>
          <input type="text" v-model="inputVal">   
          <button v-on:click="addOneToList">添加佳丽</button>   
      `
    }).mount("#app");
  </script>

</body>

GIF

总结:v-model=xxx起到了监听输入事件的效果,能够实时将数据更新到data对象的xxx属性中,之后我们可对该属性进行一些vue提供的方法来起到页面的实时效果如列表展示等等。



1.7、组件化开发(初识自定义组件以及v-bind绑定)

本部分小总结:

const app = Vue.createApp({}):创建出一个vue实例。
app.mount("#id"):将vue实例中的template模板挂载到指定dom元素上。
app.component(key,value):key为一个string字符串(可外部引用标签渲染模板<key/>),value为一个对象(属性有props、template)
	props:['aa',''],数组字符串形式,用于外部使用v-bind:aa="bbb"进行传入到内部得到值
    template:字符串,其作用于仅仅是在其组件中,也就是说不能使用vue实例的数据,只能够通过外部传入到props使用props中键对应的值
//vue可在标签中定义的属性
v-bind:aa = 'bb':直接拿到vue实例的bb值传入到aa变量里。(可用该属性来进行内外部组件传值以及标签属性赋值等等)

目的:将组件应用到vue实例中去,并进行动态遍历组件中的标签对。

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    //此时实例化出来一个组件
    const app = Vue.createApp({
      data() {
        return {
          list: ['cl', 'liner', 'meimei']
        }
      },
      //3、将自定义的组件应用到template中,通过标签键值对的形式(下面应用了两个组件,一个是my-title,另一个是my-list)
      //组件1:my-title仅仅用于标题展示
      //组件2::来对自定义组件进行遍历,不过需要你使用v-bind的方式来绑定值才可以传入到组件中的props里。(v-bind:a=b,其中a对应props里的值,b对应外部v:for中检索出来的值)
      //其中的组件2就是减少代码冗余的目的的
      template: `
        <my-title/>
        <ul>
          <my-list v-for="(item, index) of list" v-bind:val="item" v-bind:index = "index" />
        </ul>
      `
    });

    //1、组件1:仅仅用作标题
    app.component('my-title', {
      template: `
        <h1>长路的店铺</h1>
      `
    });

    //2、组件2:用于遍历的标签li
    app.component('my-list', {
      props: ['val', 'index'],  //需要配合外部的v:bind来接收
      template: `
        <li>值为:{{val}},索引:{{index}}</li>
      `
    })

    //最后一步:挂载到id="app"的标签上
    app.mount("#app");

  </script>

</body>

image-20210701154434440



综合小案例(列表展示与添加)

知识点应用:vue列表与循环、绑定输入数据以及自定义组件化!

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    const app = Vue.createApp({
      data() {
        return {
          inputVal: '',
          list: ['cl', 'liner', 'meimei']
        }
      },
      methods: {
        addValToList() {
          this.list.push(this.inputVal);
          this.inputVal = '';
        }
      },
      template: `
        <my-title/>
        <ul>
          <my-li v-for="(item, index) of list" v-bind:val="item" v-bind:index = "index" />
        </ul>
        <input type="text" v-model="inputVal">
        <button v-on:click="addValToList">点击添加人物</button>
      `
    });

    app.component('my-title', {
      template: `
        <h1>长路小店</h1>
      `
    });

    app.component('my-li', {
      props: ['val', 'index'],
      template: `
        <li>值为:{{val}},索引:{{index}}</li>
      `
    })

    //最后一步:挂载到id="app"的标签上
    app.mount("#app");

  </script>

</body>

GIF



2、深入知识点学习

2.1、CreateApp()以及mount()方法介绍

方法介绍

Vue.createApp({}):创建一个Vue的应用,对象中可传入的参数如下

  • data:可写成函数的形式,返回一个对象。
  • template:也就是你之后mount()要挂载的Html元素。

mount():就是挂载到某个Html的DOM节点上,它接受一个字符串型参数,参数可以使用CSS选择器,一般都是ID选择器的形式,指定挂载的DOM元素。


示例

测试挂载后得到的返回值:

<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    //vue实例
    const app = Vue.createApp({});
    console.log(app);

    //vue执行mount()之后的返回值
    //情况1:若是参数为空,返回null
    let vm = app.mount();
    console.log(vm);
    //情况2:若是参数指定了某个dom元素,返回一个Proxy对象(根组件vm)
    vm = app.mount("#app");
    console.log(vm);
  </script>

</body>

image-20210701161151629



2.2、介绍MVVM

Vue的编程设计模式:mvvm,首先是面向数据的编程,程序中定义了数据,然后定义了模板,Vue就可以把数据和模板自动进行关联。最后挂载到真实的DOM上,展示给用户。

  • mvvm解释: 第一个m代表model数据,第一个v代表view视图,最后两个字幕vm代表viewModel视图数据连接层。

  • <script>
        const app = Vue.createApp({
            data() {
                return {
                    message: 'jspang.com'   //1.在这里定义了数据,也就是`model`数据
                }
            },
            template: "<h2>{{message}}</h2>" //2.在这里定义了模板,也就是`view`,
            //定义后的自动关联,就叫做`vm`,viewModel数据视图连接层。
        })
        app.mount("#app")
    </script>
    


2.3、获取与使用根组件(重点,用于操控vue实例中的data)

获取根组件:通过调用mount()得到返回值,即根组件。

  • 用途:通过该根组件能够获取到vue实例中的data数据,即根组件.$data即可获取!!!
<body>
  <div id="app"></div>

  <!-- 引入vue.js框架 -->
  <script src="https://unpkg.com/vue@next"></script>
  <script>
    //vue实例
    const app = Vue.createApp({
      data() {
        return {
          message: 'hello,world'
        }
      },
      template: `
        <p>{{message}}</p>
      `
    });

    //重点:获取根实例
    const vm = app.mount("#app");

    //获取到之前vue实例app中的data对象
    console.log(vm.$data);
    //此时也就自然而然的获取到data中的属性message,此时也就可以进行操作!
    console.log(vm.$data.message);

  </script>

</body>

修改data中的属性操作,我们可以再控制台窗口进行测试:

GIF



2.4、vue的生命周期函数(重要)

生命周期函数:在某一时刻会自动执行的函数。

自动执行函数:mounted()

  const app = Vue.createApp({
    data() {
      return {
        message: 'jspang.com'
      }
    },
    template: "<h2>{{message}}</h2>",
    //自动执行函数
    mounted() {
      alert("自动执行!!!");
    },
  })

效果:在页面数据还没有进行渲染时就会执行的函数!!!

生命周期

四个函数介绍:实例与模板渲染相关的四个API

  • beforeCreate( ) :在实例生成之前会自动执行的函数
  • created( ) : 在实例生成之后会自动执行的函数
  • beforeMount( ) : 在模板渲染完成之前执行的函数
  • mounted( ) : 在模板渲染完成之后执行的函数

测试:

<script>
  const app = Vue.createApp({
    data() {
      return {
        message: 'changlu'
      }
    },
    template: "<h2>{{message}}</h2>",
    //生命周期函数测试
    beforeCreate() {
      console.log('beforeCreate')
    },
    created() {
      console.log('created')
    },
    beforeMount() {
      console.log('beforeMount')
    },
    mounted() {
      console.log('mounted')
    },
  })
  const vm = app.mount("#app")

</script>

image-20210701165205887

PS注释:(针对于mounted()函数中调用alert()方法,页面上数据没有渲染出来原因(仅仅是查阅博客):alert会造成线程阻塞。)


模板渲染完成后两个函数:检测数据发生改变

  • beforeUpdate():数据变化之前。当data中的数据变化时, 会立即自动执行的函数。
  • updated():数据变化之后。当data中的数据发生变化,页面重新渲染完后,会自动执行的函数

测试:

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: 'changlu'
      }
    },
    methods: {
      updateMsg() {
        this.message = 'liner';
      }
    },
    //为按钮来绑定单击事件,来进行修改data中的message值
    template: `
      <h2>{{message}}</h2>
      <button v-on:click="updateMsg">点击更改数据</button>
    `,
    //更改数据前
    beforeUpdate() {
      console.log('beforeUpdate')
    },
    //更改数据后
    updated() {
      console.log('updated')
    },
  })

  const vm = app.mount("#app")

</script>

GIF 、

说明:也就意味着在数据真正修改渲染前你还可以通过beforeUpdate()函数来进行操作!


vue实例销毁时前后两个函数:一个是销毁前执行,一个是销毁后执行。

  • beforeUnmount( ) :当Vue应用失效时,会自动执行的函数
  • unmounted() : 当Vue应用失效时,且DOM完全销毁之后,会自动执行

测试:通过vue的实例调用unmount()即可销毁该实例(此时双向绑定失效)


<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: 'changlu'
      }
    },
    //为按钮来绑定单击事件,来进行修改data中的message值
    template: `
      <h2>{{message}}</h2>
    `,
    //销毁前执行
    beforeUnmount() {
      console.log('beforeUnmount')
    },
    //销毁后执行
    unmounted() {
      console.log('unmounted')
    },
  });

  //执行销毁函数()
  app.unmount();

</script>

image-20210701170955981

效果:销毁vue实例最后的结果就是将所有与指定绑定的dom元素的template模板html代码全部销毁!!!



3、差值表达式{{}}相关使用

3.1、差值表达式与v-html使用时机(处理标签键值对的字符串)

差值表达式:{{xxxx}},利用这种形式能够将data中的数据展示在模板中。

v-html:对于字面值为标签的并且想要在页面中显示就需要使用该属性才能够进行渲染(与innerHtml性质一样),不能够使用{{}}形式会原样输出!!!

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: `<i>hello,world</i>`
      }
    },
    //若是data对象的属性是一个html标签,直接使用{{}}会直接将其当成一个字面值进行输出的
    // template: `
    //   <h2>{{message}}</h2>
    // `,
    //重点:此时要想在页面中有改message指定标签的效果,就需要使用v-html=属性 形式,不需要使用{{}}来获取值了!!!
    template: `
      <h2 v-html="message"></h2>
    `,
  });

  app.mount("#app");

</script>

image-20210701171928900

总结:对于data中属性是字符串的,并且改字符串是标签形式的,想要在页面上有标签的效果就需要使用v-html。



3.2、v-once(差值表达式只作一次渲染)

v-once:直接在指定dom元素上使用即可,之后对于字面值渲染就不会再生效!!!

示例demo:

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: `hello,world`
      }
    },
    methods: {
      updateMsg() {
        console.log(111);
        this.message = "nihao";
      }
    },
    //v-once:作用就是让该标签中的字面值渲染失效
    template: `
      <h2 v-once>{{message}}</h2>
      <button v-on:click="updateMsg">点我修改</button>
    `,
  });

  app.mount("#app");

</script>

GIF

总结:可以看到使用了该属性后,之后对于该标签的渲染就不会再生效了!!!



3.3、差值表达式中可使用js代码

{{}}中可使用js代码:最常用的就是三元运算符、一些简单的运算。

注意点:其中的表达式需要你能够返回字符串的,否则就会报错。

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        sex: 1
      }
    },
    //{{}}中使用三元运算符、数学运算、传入字符串
    //注意点:其中的表达式需要你能够返回字符串的,否则就会报错
    template: `
    <div>{{sex==1?'男':'女'}}</div>
    <div>{{1+2}}</div>
    <div>{{'123'}}</div>
    `,
  });

  app.mount("#app");

</script>

image-20210701173322960



4、v-bind(第二个功能,为标签中的默认参数设置值)

需求:鼠标触碰p标签时,出现文字为data对象中属性message对应的值。

分析:原本我们触碰标签显示值通过title属性来赋值的,而这里又需要你去将data对象里的属性进行赋值到title,此时我们就需要使用v-bind来进行绑定!

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: `<i>hello,world</i>`
      }
    },
    //需求:鼠标触碰p标签时,出现文字为data对象中属性message对应的值
    //错误写法:title = "message",这种方式就是简单的设置title为字符串message
    //正确写法:v:bind = "message",此时就能够将data对象中的message属性值赋值到title里
    template: `
      <h2 
        v-html="message"
        v-bind:title = "message"
        ></h2>
    `,
  });

  app.mount("#app");

</script>

GIF

image-20210701174330540

说明:通过效果,我们能够看到在h2标签里插入了title为执行message的值!!!



5、模板动态参数和阻止默认事件

5.1、v-on基本使用与简写@

基本使用:v-on:xx事件。

简写方式:@xx事件,如@click。

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: `<i>hello,world</i>`
      }
    },
    methods: {
      simClick() {
        alert("你点了我一下~~");
      }
    },
    //这里v:on使用简写@,一样的效果
    template: `
      <button @click="simClick">点我一下</button>
    `,
  });

  app.mount("#app");
</script>

GIF



5.2、模板动态参数(v:bind简写:配合[]动态设置参数)

v-bind简写::

注意看下面的:[name]="message" => v-bind:title = 'jspang.com',使用了v-bind的简写以及[]动态匹配data对象中的属性。

示例:

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: 'jspang.com',
        name: 'title'
      }
    },
    //:[name]="message"  => v-bind:title = 'jspang.com'
    //其中:表示v-bind:  [name]表示读取data对象中的name值为'title'   "message"表示读取data对象中的message属性为'jspang.com'
    template: `
        <h2 :[name]="message">
        {{message}}
        </h2>
    `
  });

  const vm = app.mount("#app");
</script>

image-20210702090259979



5.3、事件动态绑定(v-on:click => @[xxx])

之前我们绑定一个事件是使用v-on:click,其实际上是静态绑定,相当于绑死了,我们若是想要更改其事件就需要在源代码上修改!

本部分介绍一种动态绑定的方式,通过模板动态参数的形式来指定某个事件:[xxx]

动态事件绑定简写:@[event],其中的event由data指定。

  • 其中@的完整写法是v-on:。、

示例如下:

<body>
    <div id="app"></div>

    <!-- 引入vue -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        Vue.createApp({
            data() {
                return {
                    event: 'click'
                }
            },
            methods: {
                appearPop() {
                    alert("hello,world!");
                }
            },
            //@[event] => v-on:click
            //@是v-on:简写  [event]表示动态绑定data对象中的属性,这里获取到click值
            template: `
                <button @[event]='appearPop' >点我一下</button>
            `
        }).mount("#app");
    </script>
</body>

我们原本动态绑定的是单击事件,在浏览器上我们使用根组件来对data对象中的event属性进行事件修改,之后再测试就是鼠标移入则触发事件!

GIF

说明:我认为它的底层使用到了onEventListener()来动态传入参数指定事件!!!



5.4、阻止默认事件(@click.prevent)

回顾一下js怎么写阻止默认事件的,就是在指定我们想要阻止的事件中调用e.preventDefault(),之后编写指定要执行的代码即可。

在vue中也帮我们简化了这一步骤:提供了一个模板修饰符,直接可以阻止默认行为。

语法:@click.prevent,也就是在阻止的默认事件后对prevent属性来指定函数。

示例:

<body>
    <div id="app"></div>

    <!-- 引入vue -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        Vue.createApp({
            methods: {
                preventFun() {
                    alert("成功阻止!");
                }
            },
            //@click.prevent 为阻止事件后执行的函数
            //底层应该是调用了preventDefault()进行阻止默认事件,接着执行对应的prevent函数!
            template: `
                <form action="https://www.baidu.com" @click.prevent = "preventFun" >
                    <input type="submit">
                </form>
            `
        }).mount("#app");
    </script>
</body>

阻止了原本表单提交的事件,并且执行了我们的函数:

GIF



6、模板中使用条件判断(三元运算符与v-if)

两种方式:①三元运算符。②v-if

三元运算符—应用在筛选样式中

<head>
  ...
  <style>
    .one {
      color: red;
    }

    .two {
      color: blue;
    }
  </style>
</head>


<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: 'cls'
      }
    },
    //配合:绑定指定的样式到class中
    template: `
      <span :class="message=='cl'?'one':'two'" >666</span>
    `
  }).mount("#app");
</script>

image-20210702094145130


v-if应用—多种情况来判断

通过v-if编写多条标签,根据是否符合条件来进行显示指定的标签,这样的话可以有更多的选择性:

<style>
    .one {
        color: red;
    }

    .two {
        color: green;
    }

    .three {
        color: orange;
    }
</style>


<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: '技术胖'
      }
    },
    //根据v-if来判断该标签是否显示
    template: `
      <h2 v-if="message=='jspang.com'" class="one" > {{message}} </h2>
      <h2 v-if="message=='技术胖'" class="two"> {{message}} </h2>
      <h2 v-if="message=='bilibili'"  class="three"> {{message}} </h2>
    `
  }).mount("#app");
</script>

image-20210702094546950



7、三大函数属性(methods、computed、watch)

7.1、计算属性computed(以及与methdos区别)

计算属性的特性是:当计算属性依赖的内容发生变更时,才会重新执行计算。

必备条件:必须要返回一个值,在页面渲染的同时就会执行里边的业务逻辑。

两者区别:

  1. 方法methods:只要页面重新渲染,就会重新执行方法。
  2. 计算属性computed: 当计算属性依赖的内容发生变更时,才会重新执行计算。

问题引出

当我们将一个方法函数写在methods中,一旦数据重新渲染就会重新执行methods中的所有方法!!!

后果:按理说对于methods方法全都重新执行是好事,数据能够进行实时刷新嘛,不过对于想要返回指定时间戳的函数同样也会跟随该机制重新计算得到新的时间戳!

<script src="https://unpkg.com/vue@next"></script>
<script>
  const vm = Vue.createApp({
    data() {
      return {
        message: '技术胖'
      }
    },
    methods: {
      getTotal() {
        return Date.now()
      }
    },
    template: ` 
        <h2>{{message}}</h2>
        <h2> {{getTotal}}</h2>
    `
  }).mount("#app");
</script>

我们刷新data对象中的message属性,就会带动methods中的方法重新执行:

GIF


避免上述时间戳重新获取:在computed对象属性中编写函数方法

计算属性computed: 当计算属性依赖的内容发生变更时,才会重新执行计算。(不再是data对象中数据刷新就会执行一遍methods方法)

<script src="https://unpkg.com/vue@next"></script>
<script>
  const vm = Vue.createApp({
    data() {
      return {
        message: '技术胖'
      }
    },
    //1、计算属性computed:与methods写法相同
    computed: {
      getTotal() {
        return Date.now()
      }
    },
    //2、执行computed计算属性中的方法不需要带有()
    template: ` 
        <h2>{{message}}</h2>
        <h2> {{getTotal}}</h2>
    `
  }).mount("#app");
</script>

GIF


实际小例子:

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const vm = Vue.createApp({
    data() {
      return {
        price: 10,
        count: 5
      }
    },
    //将一些需要计算的函数放在计算属性computed属性里
    //计算属性会帮助我们完成模板的自动更新
    computed: {
      total() {
        return this.price * this.count
      }
    },
    methods: {
      addCount() {
        this.count++;
      }
    },
    template: ` 
        <h2>total:{{total}}</h2>
        <button @click="addCount">再买一个</button>
    `
  }).mount("#app");
</script>

GIF



7.2、侦听器/监听器(watch属性、与computed区别)

watch属性使用

watch侦听器的作用就是侦听一个data中的值的变化,变化后可以写一个方法,让其进行一些操作(业务逻辑的编写)。

特征:

  • watch属性(对象):内部编写函数,函数名对应要监听的属性。
  • 函数包含两个参数:当监听的属性发生变化时触发,参数一是更改后的值,参数二为更改前的值。

示例:

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const vm = Vue.createApp({
    data() {
      return {
        price: 10,
        count: 0
      }
    },
    methods: {
      addCount() {
        this.count++;
      }
    },
    //监听器属性watch
    watch: {
      //函数名对应的监听的指定data对象的值(这里指):count
      //可以传入两个参数,参数一:现在值,参数二:变化前的值
      count(current, prev) {
        console.log('watch changed')
        console.log('现在的值:', current)
        console.log('变化前的值:', prev)
      }
    },
    template: ` 
        <h2>count:{{count}}</h2>
        <button @click="addCount">再买一个</button>
    `
  }).mount("#app");
</script>

GIF


与computed属性区别

computed:其中的函数必须要返回一个值,而且在页面渲染的同时就会执行里边的业务逻辑,也就是会先执行一遍你写的业务逻辑。

watch:只有发生变化时才会执行,也就是说值没有变化,它是不执行里边业务逻辑的。



三者函数使用优先级

现在总结一下method、watch和computed三者如果都能实现相同的功能,它们之间的取舍和使用优先级。

  • computed 和 method都能实现的功能,建议使用computed,因为有缓存,不用渲染页面就刷新。
    • computed中的函数必须有返回值!
  • computed 和 watch 都能实现的功能,建议使用computed,因为更加简洁。
    • watch属性中写的函数,其函数名为监控的属性!

建议最好使用computed来实现一些计算的功能,对于其他属性更新变化时不会重新触发时间戳函数需要使用computed,否则每次都会更新其他数据时就会执行一遍methods里的方法。

最重要的就是能够理解这三者的区别:

  1. methods:可以写任意函数,一旦data对象中的数据更新就会全部执行一遍。
  2. computed:函数必须有返回值,只有与函数中相关联的属性才会去执行指定函数。
  3. watch:编写的函数名可以执行想要监控的属性,来进行一些监控操作等等。



9、v-show(控制dom元素是否清除,本质就是添加style="display: none;")

9.1、实际使用

用法:v-show,传入一个布尔值。

  • true:表示不对dom元素进行任何操作。
  • false:表示为改dom元素设置style="display: none;"效果,直接就是清除该dom元素。

示例:

<body>
  <div id="app"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        show: true,
      }
    },
    //v-show:用于设置dom元素的显示与否,传入布尔值
    //通过data对象中的show布尔值来进行控制dom元素的显示与不显示
    template: `
        <h2 v-show="show">JSPang.com</h2>  
    `
  })
  const vm = app.mount("#app")

</script>

GIF



9.2、v-show与v-if区别

v-if:更加灵活,可以增加多个判断,比如v-else-iif和else,而v-show不具备这样的灵活性。

  • 效果:设置true为应用该dom元素,为false表示不应用该dom元素。

v-show:

  • 效果:设置为true不对该元素有任何影响,false就为该元素添加style="display: none;",页面中不显示该dom元素。

推荐使用:如果显示和隐藏的状态切换比较频繁,并且没有什么多余复杂的业务逻辑,建议使用v-show,因为他不会一直渲染你的页面DOM元素,这或多或少对性能和稳定性有点提升。反之可以使用v-if。



10、v-for循环

10.1、遍历数组示例

遍历数组

<body>
  <div id="app"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        listArray: ['谢大脚', '刘英', '晓红']
      }
    },
    //遍历数组可获得值与索引(参数一、参数二)
    template: `
        <ul>
            <li v-for="(item,index)  in listArray">[{{index}}]{{item}}</li>
        </ul>
    `
  })
  const vm = app.mount("#app")
</script>

image-20210702124959034



10.2、提升性能(循环中的key)

vue中在进行列表渲染的时候,会默认遵守就地复用策略

  • 复用策略:当在进行列表渲染的时候,vue会直接对已有的标签进行复用,不会将所有的标签全部重新删除和创建,只会重新渲染数据,然后再创建新的元素直到数据渲染完。(简而言之就是不会重新删除与创建标签,但是会将数据全部重新渲染)

为了提高循环时性能,在数组其中一项变化后,整个数组不进行全部重新渲染,Vue提供了绑定key值的使用方法,目的就是增加渲染性能,避免重复渲染。

  • 效果:不会去改变原有的元素和数据,而是创建新的元素然后把新的数据渲染进去。(简而言之仅仅会渲染新的数据或修改的数据)

对于key的值设置:不建议使用索引index为key值,但此时又为了保持唯一性,所以这里使用了index+item进行绑定key值。

<ul>
    <li v-for="(item,index)  in listArray" :key="index+item">
        [{{index}}]{{item}}
    </li>
</ul>


10.3、for循环遍历对象

v-for="(value,key,index) in listObject":可接收三个参数分别为值、键以及索引。

示例:

<body>
  <div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        //......
        listObject: {
          GirlOne: '谢大脚',
          GirlTwo: '刘英',
          GirlThree: '晓红'
        }
      }
    },
    //遍历对象
    //v-for="(value,key,index)  in listObject" => 参数1:值  参数2:键  参数三:键值对的索引位置
    template: `
      <ul>
          <li v-for="(value,key,index)  in listObject" :key="index+key">
              [{{index}}]{{value}}-{{key}}
          </li>
      </ul>
    `
  })
  const vm = app.mount("#app")
</script>

image-20210702132850693



10.4、v-for注意点

10.4.1、允许循环数字

<li v-for="val in 100" :key="val">
    {{val}}
</li>


10.4.2、v-for中如何使用v-if(两者不能嵌套在一个标签,引出template标签)

在v-for中使用判断:不能直接在v-for的标签中使用v-if,这样是没有任何效果的。

简而言之:v-for与v-if不能同时在一个标签中使用!!!

第一种解决方案:在需要遍历的外部添加一个div标签,真正遍历在内部的li标签里(该标签里可以拿到外部标签遍历的值)

image-20210702133927602

不推荐使用!!!有很大的弊端。

第二种解决方案:使用template标签,就是将原本外层的div改成vue里的<template>标签,就能够实现完美解决v-for与v-if的嵌套使用!

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        listArray: ['谢大脚', '刘英', '晓红']
      }
    },
    //使用template标签,该标签在vue中起到了虚拟标签的作用,最终该template不会显示出现
    //效果:弥补了方案一中冗余嵌套的标签!!!
    template: `
      <ul>
        <template v-for="(item,index) in listArray" :key="index+item">
          <li v-if="item != '谢大脚'">
            [{{index}}]{{item}}
          </li>
        </template>
      </ul>
    `
  })
  const vm = app.mount("#app")
</script>

image-20210702134354783



11、绑定事件详解

11.1、方法和参数

11.1.1、绑定事件的两种形式(函数、表达式)

方式一:绑定事件函数

methods: {
  addCountClick() {
    this.count++;
  },
},
template: `
    <div>目前已点佳丽数量{{count}}.</div>
    <button @click="addCountClick">增加一位佳丽</button>
  `

方式二:表达式形式

//表达式形式(直接在表达式中书写js代码):@click="count++"
template: `
    <div>目前已点佳丽数量{{count}}.</div>
    <button @click="count++">增加一位佳丽</button>
  `


11.1.2、在函数中获取event事件对象(无参与有参)

无参:直接拿到event对象

event.target使用

事件中的event对象,实际测试event.target对象,使用target对象来统一处理相同的操作

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        dataArr: ['cl', 'liner', 'linlin']
      }
    },
    methods: {
      //通过event.target获取源冒泡对象
      delBtn(event) {
        console.log(event.target);//dom对象
        console.log(event.target.innerText);//dom对象
        //删除指定元素通过标签中的id
        this.dataArr.splice(event.target.innerText[2], 1);
      }
    },
    //直接通过ul标签进行冒泡捕捉单击事件
    template: `
      <ul @click="delBtn" >
        <li v-for='(val,item) in dataArr' :key='val+item'>
          {{val}}  
          <button>删除{{item}}</button>
        </li>
      </ul>
      `
  });
  const vm = app.mount("#app")
</script>

GIF


若是有一个或多个时,需要传入实参$event才会能获取到

函数多参数时如何获取event对象?

若是函数只有一个参数,将其设置为event你就能够拿到对应的事件对象,但是若是有多个参数就需要你在调用时将$event作为实参传入!

image-20210702140820736



11.1.3、一个事件调用多个方法

下面演示点击事件绑定两个方法:直接在事件后面调用多个函数使用,隔开

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    methods: {
      handleBtnClick1() {
        alert(1)
      },
      handleBtnClick2() {
        alert(2)
      },
    },
    //若是想让一个事件执行两个方法:直接在
    template: `
          <button @click="handleBtnClick1(),handleBtnClick2()">增加一位佳丽</button>
      `
  });
  const vm = app.mount("#app")
</script>

GIF



11.2、六种事件修饰符

Vue中的事件修饰符,分别是stop,prevent,capture,self,once和passive。

  • stop:停止冒泡,如@click.stop=" addCountClick()"。

  • self:只有点击自己内部内容才会生效,对于内部成对标签出现,都不属于自己的,属于是子元素。

    • //第一个div中添加了self修饰符,但是由于内部全部都是div元素所以无论点哪里都不会生效(若是你设置外边框线很粗,点它的边框也是会生效的)
      template:`
          <div @click.self="handleBtnClick1">
              <div>目前已点佳丽数量{{count}}.</div>
              <button @click=" addCountClick()">增加一位佳丽</button>
          </div>
          `
      
      //此时我们为第一个div元素内部添加一段文字,我们点击该文字就会生效了!!!
      template:`
          <div @click.self="handleBtnClick1">
              我是最外层的DIV文字
              <div>目前已点佳丽数量{{count}}.</div>
              <button @click=" addCountClick()">增加一位佳丽</button>
          </div>
      `
      
  • prevent:阻止默然行为的修饰符,这个以前讲过,例如阻止form表单的默认提交行为。

  • capture:冒泡顺序发生改变,原本冒泡顺序是由内到外,改变之后就变为由外到内。

  • once:事件只执行一次。

  • passive:解决滚动时性能的修饰符。

可供测试模板:

<body>
  <div id="app"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 0
      }
    },
    methods: {
      addCountClick() {
        this.count++;
        alert(0)
      },
      handleBtnClick1() {
        alert(1)
      },
    },
    template: `
      <div @click:capture="handleBtnClick1"> 
          我是最外层的DIV文字
          <div>目前已点佳丽数量{{count}}.</div>
          <button @click=" addCountClick()">增加一位佳丽</button>
      </div>
      `
  })
  const vm = app.mount("#app")

</script>



11.3、键盘与鼠标修饰符

按键修饰符和鼠标修饰符:使用使用特定的某个按键时才会用到

11.3.1、键盘修饰符(演示键盘事件以及单一按键事件)

keydown事件

<body>
  <div id="app"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {}
    },
    methods: {
      handleKeyDown() {
        console.log('keydow....')
      }
    },
    //keydown事件:能够响应键盘输入
    template: `
        <div>
            <input @keydown="handleKeyDown"/>
        </div>
      `
  })
  const vm = app.mount("#app")

</script>

image-20210702143755104


单个按键修饰符

单个按键修饰符:顾名思义,就是指定键盘上某个特殊的按键时才会响应事件方法。

各种单个按键修饰符提供如下

  • e·nter 、tab、delete、esc、up 、down、left、right

image-20210702144003982



11.3.2、鼠标修饰符(单个按键触发函数)

鼠标修饰符:按下鼠标上的某个键时,才会响应指定的函数方法。

  • 最常用:left、right、middle

image-20210702144211783

<body>
  <div id="app"></div>
</body>

<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {}
    },
    methods: {
      handleClick() {
        alert('right click!')
      }
    },
    //keydown事件:能够响应键盘输入
    template: `
        <div @click.right="handleClick">changluya</div>
      `
  })
  const vm = app.mount("#app")

</script>



12、表单与数据绑定(双向数据绑定,使用v-model)

Vue3中表单和数据绑定的一些方法

双向数据绑定:data中的变量改变时,绑定的数据会跟随变化,此为一项修改;当通过页面修改数据,data中的变量也随之改变,这就是另一项修改。两个彼此依存改变。

12.1、input、textarea,checkbox,radio的双向绑定

input与textarea标签双向绑定:两者都是输入内容

v-model:将输入的值传入到指定的data对象属性中

<body>
  <div id="app"></div>
</body>

<script>
  const app = Vue.createApp({
    data() {
      return {
        //model(数据)
        message: ''
      }
    },
    //view(模板)
    //input、textarea标签:绑定v-model:监听输入的值传入到message中
    template: `
        <p>{{message}}</p>
        <input type="text" v-model='message'>
        <div><textarea v-model="message" /></div> 
      `
  })
  const vm = app.mount("#app")

</script>

image-20210702145528660


checkbox:复选框(单个存储布尔值,多个存储value值)

若是只有一个选项:data中准备一个布尔值,选中表示为true,取消勾选为false。

data() {
    return {
        checked: false,
    }
},
//view(模板)
//input、textarea标签:绑定v-model:监听输入的值传入到message中
template: `
    <div>{{checked}}<input type="checkbox" v-model="checked" /></div>
`

image-20210702150052065

若是有多个选项:data中准备一个空数组[],选中就会将value值push到绑定的元素中。

data() {
    return {
        girls: []
    }
},
//view(模板)
//input、textarea标签:绑定v-model:监听输入的值传入到message中
template: `
    <div>
        {{girls}}
        大脚<input type="checkbox" v-model="girls" value="大脚" />
        刘英<input type="checkbox" v-model="girls" value="刘英" />
        晓红<input type="checkbox" v-model="girls" value="晓红" />
    </div>
`

image-20210702150020701


radio:单选(存储到字符串中)

data() {
  return {
    //字符串来接收
    girl: '',
  }
},
template: `
  <div>
      {{girl}}
      大脚<input type="radio" v-model="girl" value="大脚" />
      刘英<input type="radio" v-model="girl" value="刘英" />
      晓红<input type="radio" v-model="girl" value="晓红" />
  </div>
  `

image-20210702150251766



解决单个checkbox返回布尔值情况(配合checkbox里的true-value和false-value)

使用的原因?为了解决多选框checkbox只有一个时返回true或false的问题,我们要的是真正对应多选框中的值而不是是否勾选的布尔值!

目的:通过使用v-model配合true-value和false-value来达到返回value到绑定的属性汇中去!

示例:

<body>
  <div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        name: '',
      }
    },
    //checkbox多选框若是只有一个选项时,勾选与非勾选返回的是布尔值true或false
    //如何让绑定的属性获取到值呢?通过添加两个修饰符true-value与false-value,设置指定的值之后就会根据是否勾选返回真正val到绑定的属性中去
    template: `
      <div>{{name}}
        <input type="checkbox" v-model="name" 
            true-value="changlu"
            false-value="liner"
        />
      </div>
      `
  })
  const vm = app.mount("#app")

</script>

image-20210702151247315



12.2、v-model的修饰符(lazy、number、trim)

lazy修饰符

之前配合v-model进行双向绑定之后,输入任何内容的时候,插值表达式会跟着改变。

需求:就是我输入内容时并不立马显示,而是输入框失去焦点之后再显示,此时就可以使用到lazy修饰符了。

lazy修饰符(懒更新修饰符):双向绑定的值并不会立即修改,只有当输入框失去焦点之后再进行改变值!

<body>
  <div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: '',
      }
    },
    //为v-model设置lazy修饰符,实现输入框失去焦点之后才会更新数据
    template: `
      <div>
          {{message}}<input v-model.lazy="message" />
      </div>
      `
  })
  const vm = app.mount("#app")

</script>

效果:不使用懒加载时我们是一输入就会进行数据更新,而使用了懒加载在失去焦点时才会进行更新。

GIF


number修饰符

当我们在input输入好内容之后,我们得到得到的value默认都是字符串,若是输入数字同样也是字符串。

需求:当我们输入非数字就是字符串,输入数字为number类型。

number:此时我们就可以使用number修饰符了,你输入的值只要是数字,就变成了number类型,输入的是字母,它还会是字符串类型。

<body>
  <div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: '',
      }
    },
    //为v-model设置lazy修饰符,实现输入框失去焦点之后才会更新数据
    template: `
      <div>
          {{typeof message}}<input v-model.number="message" />
      </div>
      `
  })
  const vm = app.mount("#app")

</script>

GIF


trim修饰符:过滤掉左右两边的空格

不使用trim修饰符时:输入空格正常也是会传入到data指定属性中

GIF

使用trim修饰符后:绑定的data属性不会去接收空格

<body>
  <div id="app"></div>
</body>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        message: '',
      }
    },
    watch: {
      message(cur) {
        console.log(cur);
      }
    },
    //为v-model后新增.trim修饰符
    template: `
      <div>
          {{message}}<input v-model.trim="message" />
      </div>
      `
  })
  const vm = app.mount("#app")

</script>

GIF

我们最后使用拼接测试是否帮我们将左右两边的空格都过滤掉了:vm.$data.message+456,最终确认确实是将左右两边的空格清楚了!!!


思考

1、关于删除事件直接删除一行

vue是数据驱动的,不直接操作dom元素,你要把dom元素想像成一个对象,然后对这个对象进行增加删除操作,vue会自动更新视图。

思路:一旦data对象中的listArray数组中删除了某个元素,在v-for中就会重新渲染该元素!!!

<body>
  <div id="app"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        listArray: ['谢大脚', '刘英', '晓红']
      }
    },
    methods: {
      del(num) {
        //直接对原数组操控即可达到渲染目的
        this.listArray.splice(num, 1);
      }
    },
    //遍历数组可获得值与索引(参数一、参数二)
    template: `
        <ul>
            <li v-for="(item,index)  in listArray" >[{{index}}]{{item}}
              <button @click='del(index)'>删除</button>
            </li>
        </ul>
    `
  })
  const vm = app.mount("#app")
</script>

GIF



整理者:长路 时间:2021.7.1-7.2

评论区请在客户端页面查看