1.模板语法

什么是模板?

  • Root容器中的代码就被称为Vue的模板,每当我们引入Vue.js过后,全局就多了一个名为Vue的构造函数.
  • 模板语法一般分为两种:
    • 1.插值语法(一定要切记,使用模板语法过后,语法包括的值就不再是字符串..他就是js表达式了)
      • 功能:用于解析标签体内容。(就是起始标签和结束标签包括的内容)
      • 写法:,xxx是js表达式,且可以直接读取到data中的所有属性。
    • 2.指令语法
      • 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…..)。
      • 举例:v-bind:href=”xxx” 或  简写为 :href=”xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性。
    • 备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子。
      <!-- 准备好一个容器-->
          <div id="root">
              <h1>插值语法</h1>
              <h3>你好,{{name}}</h3>
              <hr/>
              <!--重点: 一旦使用了指令语法,那么后面的属性值就有字符串(数值)变成了js表达式 -->
              <h1>指令语法</h1>
              <!-- 完整写法 此时这里的 school.url.toUpperCase() 就是js表达式 并非字符串 读取url变量-->
              <a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
              <!-- 简洁写法(省略v-bind) -->
              <a :href="school.url" x="hello">点我去{{school.name}}学习2</a>
          </div>
          <script>
              Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

              new Vue({
                  el:'#root',
                  data:{
                      name:'zpl',
                      school:{
                          name:'五邑大学',
                          url:'https://www.wyu.edu.cn/',
                      }
                  }
              })
      </script>

运行结果:

image

2.数据绑定

  • 单向数据绑定: v-bind
    • 数据只能从data流向页面。
  • 双向数据绑定: v-model
    • 数据不仅能从data流向页面,还可以从页面流向data。
  • 备注:只能用于表单类元素(输入类元素,就是要有value值才行,类似h标签不适用)上,如input,select等…,v-model可以简化为:v-model,因为v-model就是默认收集value值
<!-- 准备好一个容器-->
    <div id="root">
        <!-- 普通写法 -->
        <!-- 单向数据绑定:<input type="text" v-bind:value="name"><br/>
        双向数据绑定:<input type="text" v-model:value="name"><br/> -->

        <!-- 简写 -->
        单向数据绑定:<input type="text" :value="name"><br/>
        双向数据绑定:<input type="text" v-model="name"><br/>
<!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素上 -->
        <!-- <h2 v-model:x="name">你好啊</h2> -->
    </div>
    <script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
   
    new Vue({
        el: '#root',
        data: {
            name : '五邑大学'
        }
  })
    </script>

单向数据绑定运行结果:

image

双向数据绑定运行结果:

image

3.el和data的两种写法

    1. el的两种写法:
    • (1).new Vue时候配置el属性。
    • (2).先创建Vue实例,随后再通过vm.$mount(‘#root’)指定el的值。
    1. data的两种写法
    • (1).对象式
    • (2).函数式
    • 如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。(不能使用箭头函数)
    1. 一个重要的原则:
    • 由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。(因为箭头函数没有this,他会向上指向windows)
      <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
      //el的两种写法
      /* const v = new Vue({
          //el:'#root', //第一种写法
          data:{
              name:'尚硅谷'
          }
      })
      console.log(v)
      v.$mount('#root') //第二种写法(更为灵活) */
      //data的两种写法
      new Vue({
          el:'#root',
          //data的第一种写法:对象式
          /* data:{
              name:'尚硅谷'
          } */
      //data的第二种写法:函数式 (不能用箭头函数,因为箭头函数没有this,会向上指向windows)
                  data(){ //这里因为是对象函数,可以省略function和冒号:
                      console.log('@@@',this) //此处的this是Vue实例对象
                      return{
                          name:'五邑大学'
                      }
                  }
              })
          </script>

运行结果:

image

4.理解MVVM模型(Model-View-ViewModel)

  • 1.M:模型(Model) :对应data 中的数据
  • 2.V:视图(View) :模板
  • 3.VM:视图模型(ViewModel) : Vue 实例对象

具体模型图

image

代码解析图如下

image

发现:

  • 1.data中所有的属性,最后都出现在了vm身上
  • 2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。

5.数据代理

1.回顾Object.defineProperty()函数的用法:

  • Object.defineProperty()函的用法,顾名思义,这个方法就是给对象添加属性的,在Vue的底层,很多都用到这个方法,如数据劫持,数据代理,计算属性等…
  • 语法:
    语法格式:
       Object.defineProperty(obj,prop,description)
           
       obj: 必须 目标对象
       prop: 必须 需要定义或修改的属性名字(你要修改的是哪一个属性)
       description: 必须 目标属性所拥有的特性 (要改的属性有什么样的特性,说明,属性值),一般为对象形式

       description的常用属性值:
       1.value: 设置属性的值  默认为undefined
       2.writable: 值是否可以重写。true | false  默认为false
       3.enumerable: 目标属性是否可以被枚举。true | false 默认为 false
       4.configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false  默认为false

例子:

<script>
//Object.defineProperty()方法用于定义新属性或修改原有的属性值
// 先创建一个对象
let a = {
    name: 'Cheung Pui Lam',
    age: 20,
    address: '五邑大学'
}
// 常用的添加属性的方法1
a.sex = '男';
a.subject = '电子信息工程';

// 常用的添加属性的方法2-Object.defineProperty()
Object.defineProperty(a , 'age' , {//这里将 age 这个属性改为了18
    //1.value: 设置或修改属性的值  默认为undefined
    value : 18,

    //2.writable: 值是否可以重写。true | false  默认为false
    writable: false,//此时的age就不能被修改了!
        // 3.enumerable: 目标属性是否可以被枚举(就是遍历)。true | false 默认为 false
        enumerable: false,//此时这个age属性就无法被枚举(遍历)了!
// 4.configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false  默认为false
        configurable: false//表示现在的 age 属性不能被删除和修改特性(后面不能再修改)
        })
        a.age = 10;//age依然是 18  => 对应的是 writable: false 属性
        console.log(Object.keys(a));//使用keys()方法来遍历,没有出现 age属性 => 对应 enumerable: false 属性
        delete a.age;//但是结果依然有age属性 => 对应 configurable: true 属性
        console.log(a);
</script>

运行结果:

image

2.Object.defineProperty()函数的高级用法

  • 这里介绍 Object.defineProperty() 方法的两个高级用法(内置的get() 和 set() 方法)
    • 1.get() 方法:当有人读取目标对象的某一个属性时,就会执行这个该函数,且返回值就是目标属性(该属性)的值
    • set() 方法:当有人修改目标对象的某一个属性时,就会执行这个该函数,且返回值就是目标属性(该属性)的值
       <script>
      //Object.defineProperty()方法用于定义新属性或修改原有的属性值
      // 先创建一个对象
      let num = 20;//这里设置一个冰凉用于传递和接收 age属性的属性值
      let a = {
          name: 'Cheung Pui Lam',
          age: num,
          address: '五邑大学'
      }

      // 常用的添加属性的方法2-Object.defineProperty()
      Object.defineProperty(a , 'age' , {
      get(){//每当读取 age属性(目标属性)时就会调用这个函数
          console.log('给属性被读取了!');
          return num;//一定要有返回值
      },
      set(value){//每当修改 age属性(目标属性)时就会调用这个函数
          console.log('该属性被修改了!,且该属性值是', value );
          num = value
      }
      })
      console.log(a);
      </script>

运行结果:

image
image

2.理解数据代理

  • 所谓的数据代理,实际上就是通过一个对象代理另一个对象中属性的操作(读/写),说白了就是通过 对象1 操作 对象2, 对象1 能够访问和修改 对象2 的一些属性和方法
    <!-- 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)-->
    <script type="text/javascript" >
        let obj = {x:100}
        let obj2 = {y:200}

            Object.defineProperty(obj2,'x',{//给obj2添加一个x属性,返回的是obj的x值
            get(){//每当读取obj2中的x属性就会返回obj的x值
                return obj.x//这里相当于给obj2添加属性 x:100
            },
            set(value){//每当修改obj2的x值,就会将该值传递给obj的x
    obj.x = value
                    }
                })
                console.log(obj,obj2);
           </script>

运行结果:

image
image
表示了我们可以通过obj2一样可以操作obj,这就是数据代理

3.Vue当中是如何应用数据代理的?

  • 就拿插值语法来讲,我们在实例化对象的时候会在Vue构造函数中传入data{}对象,给里面填入一些属性,而这些属性在实例化对象的时候就通过数据代理的方式传送给实例化对象

原理如图所示:

image

  • 代码解析:
    <!-- 
    1.Vue中的数据代理:
    通过vm对象来代理data对象中属性的操作(读/写)
    2.Vue中数据代理的好处:
        更加方便的操作data中的数据
    3.基本原理:
            通过Object.defineProperty()把data对象中所有属性添加到vm上。
            为每一个添加到vm上的属性,都指定一个getter/setter。
            在getter/setter内部去操作(读/写)data中对应的属性。
          -->
         <!-- 准备好一个容器-->
         <div id="root">
             <h2>姓名:{{name}}</h2>
             <h2>学校地址:{{school}}</h2>
         </div>
      </body>

      <script type="text/javascript">
          Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
           
          const vm = new Vue({
              el:'#root',
              data:{
                  name:'zpl',
                  school:'五邑大学'
              }
          })
          console.log(vm);//输出实例对象
          console.log(vm.name === vm._data.name);//true,说明原Vue构造函数里面的data就是vm里面的_data
      </script>

运行结果:

image

这类Vue博客是博主在学习”尚硅谷“的Vue教程记录的一些代码笔记以及心得
教程链接为:BiliBli