前端框架Vue(一)


什么是Vue

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,高效地开发用户界面。

Vue 的两个核心功能:

  • 声明式渲染:Vue 基于标准 HTML 拓展了一套模板语法,使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。
  • 响应性:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。

Vue 是渐进式框架,可以自底向上逐层的应用。

基础语法

模板语法

插值语法

{{xxxx}},其中xxxx会作为js表达式运行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test01</title>
</head>
<body>
    <!-- vue 操作此dom 此元素里面的后代元素全部可以被vue操作控制 -->
    <div id="root">
      <!-- 插值表达式语法:{{js表达式}} 表达式中的变量来自于data函数的返回值 -->
      <h1>你好{{name}}</h1>
      <h1>1+1={{1+20}}</h1>
    </div>
    <!-- CDN引入方式 -->
    <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
    <!-- 引入本地vue.js文件 -->
    <script src="./vue.js"></script>
    <script>
     // 初始化 vue 对象
      const app = Vue.createApp({
        data(){  // 这里存放页面需要引用的数据,通过return返回对象
          // data这里定义数据
          return {
            name:'AiLynn',
          }
        }
      })
    app.mount('#root') // 挂载到id=root的元素上,开始操控此元素
    </script>
</body>
</html>

指令语法

v-开头

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test01</title>
</head>
<body>
    <!-- vue 操作此dom 此元素里面的后代元素全部可以被vue操作控制 -->
    <div id="root">
      <!-- 插值表达式语法:{{js表达式}} 表达式中的变量来自于data函数的返回值 -->
      <h1>你好{{name}}</h1>
      <h1>1+1={{1+20}}</h1>
      <!-- 指令语法 v-指令 -->
      <a v-bind:href="vue3link">点我跳转到vue官网</a>
    </div>
    <!-- CDN引入方式 -->
    <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
    <!-- 引入本地vue.js文件 -->
    <script src="./vue.js"></script>
    <script>
     // 初始化 vue 对象
      const app = Vue.createApp({
        data(){  // 这里存放页面需要引用的数据,通过return返回对象
          // data这里定义数据
          return {
            name:'AiLynn',
            vue3link:'https://cn.vuejs.org/'
          }
        }
      })
    app.mount('#root') // 挂载到id=root的元素上,开始操控此元素
    </script>
</body>
</html>

数据绑定

单向绑定

v-bind 单向数据绑定

  • 语法:v-bind:herf="xxx"或简写为:href
  • 特点:数据只能从js流向html

双向绑定

v-model 双向数据绑定

  • 语法:v-model="xxxx"
  • 特点:数据不仅能从js流向html,还能从html流向js
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test02</title>
</head>
<body>
    <div id="root">
        <!-- v-bind:待绑定的属性="data返回的变量" -->
        <!-- 单向绑定,数据只能从js流向html -->
        <input type="text" placeholder="请输入姓名" v-bind:value="name">
        <!-- 上面的v-bind:value="name"可以简写为 :value="name" -->
        <!-- v-model="值" 自动绑定元素对应的属性(文本框、下拉框等) -->
        <!-- 双向绑定,数据可以从js流向html,也可以从html流向js -->
        <!-- <input type="text" placeholder="请输入年龄" v-model="age"> -->
        <!-- v-model的lazy模式,当脱离焦点后再进行同步 -->
        <input type="text" placeholder="请输入年龄" v-model.lazy="age">
        <h3>姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
    </div>
    <script src="./vue.js"></script>
    <script>
      Vue.createApp({
        data(){
            return{
                name:"AiLynn",
                age:18
            }
        }
      }).mount("#root")
    </script>
</body>
</html>
v-model的补充说明
  • v-model的lazy模式,当脱离焦点后再进行同步

    <input type="text" placeholder="请输入年龄" v-model.lazy="age">
  • number修饰符,会将v-model绑定的数据转成number

    <input type="text" placeholder="请输入年龄" v-model.number="age">
  • trim修饰符,可以自动过滤用户的首尾空白字符串

    <input type="text" placeholder="请输入年龄" v-model.trim="age">

事件监听

语法:v-on:事件名

简写语法 @事件名,如@click

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test03</title>
</head>
<body>
    <div id="root">
        <!-- v-on:事件="js表达式" 简写为@事件="js表达式" -->
        <button v-on:click="age++">点我加1岁</button>
        <h3>年龄:{{age}}</h3>
        <!-- 加法计数器 -->
        <input type="text" placeholder="请输入第1个值" v-model.number="value1">
        <input type="text" placeholder="请输入第2个值" v-model.number="value2">
        <button @click="add">计算</button>
        <h3>结果:{{res}}</h3>
        <!-- 函数不加括号, vue会默认传递事件对象给函数 -->
        <input type="text" placeholder="请输入用户名" v-model="username" @keyup.enter="checkName">
        <!-- vue通过 $event 表示事件对象参数 -->
        <input type="text" placeholder="请输入用户名" v-model="username" @keyup.enter="checkName1('AiLynn',$event)">

        <h3>{{username}}</h3>
    </div>
    <script src="./vue.js"></script>

    <script>
        Vue.createApp({
            // 选项式API
            data(){
                return{
                    name: "AiLynn",
                    age: 18,
                    value1: "",
                    value2: "",
                    res: "",
                    username: ""
                }
            },
            methods:{   // 自定义定义方法
                // data定义的数据会绑定到this
                add(){
                    this.res = this.value1 + this.value2
                },
                checkName(){
                    console.log("触发了checkName")
                    console.log(event.target.tagName)   // 事件对象目标元素的标签名
                },
                checkName1(name,event){
                    console.log('检查:',name)
                    console.log(event.target.tagName)   // 事件对象目标元素的标签名
                }
            }
        }).mount("#root")
    </script>
</body>
</html>

条件渲染

v-if,后面可以跟v-elsev-else-if形成多条件分支

v-show,与v-if用法相同,区别是v-if销毁创建dom,而v-show只是更改display样式。即v-if的资源开销要比v-show要大

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test04</title>
</head>
<body>
    <div id="root">
        <button @click="ate=!ate">开饭/消化</button>
        <!-- v-if 用于控制元素是否显示 控制元素的生成和销毁-->
        <!-- <h3 v-if="ate">吃过了</h3> -->
        <!-- v-show 作用是控制了元素的样式 (v-if 性能开销比v-show小,在元素频繁切换的场景建议使用v-show)-->
        <h3 v-show="ate">吃过了</h3>
        <h3 v-else>饿了</h3>
        <!-- v-if 后面紧跟着 v-else 或 v-else-if 可以实现分支效果 -->
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.createApp({
            data(){
                return{
                    ate: false,
                }
            },
            methods:{

            }
        }).mount("#root")
    </script>
</body>
</html>

列表渲染

v-for,用于渲染列表。

语法:v-for="item in items" 用在需要多次渲染的元素上。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test05</title>
</head>
<body>
    <div id="root">
        <h3>待办事项:</h3>
        <ul>
            <!-- v-for 用于需要循环渲染的元素上,常用于列表元素 -->
            <!-- v-for 语法 v-for="item in itemlist" -->
            <li v-for="todo in todo_list">{{todo}}</li>
        </ul>
    </div>
    <script src="./vue.js"></script>
    <script>
        Vue.createApp({
            data(){
                return{
                    todo_list: ["吃饭","睡觉","打豆豆"]
                }
            }
        }).mount("#root")
    </script>
</body>
</html>

MVVM模型

M Model:数据层,即data()返回的数据

V View:视图,data()挂载的html的内容

VM ViewModel:视图模型,主要用于Model和View之间的桥梁,包含DOM Listeners和Data Bindings,通过数据的双向绑定进行关联

响应式原理

什么是响应式?

响应式就是视图渲染时使用到了一个数据,当数据更新时,视图就会响应是否更新。

在 Vue2 中,Vue 是使用 Object.defineProperty 来实现响应式的。

在 Vue 3 中,数据是基于 JavaScript Proxy(代理) 实现响应式的。通过Proxy(代理)拦截对象中任意属性的变化,包括属性值的读写、属性的增加、属性的删除等;通过Reffect(反射)对源对象的属性进行操作。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue_test06</title>
</head>
<body>
    <script>
        // proxy 是ES6引入的API,作用是在目标对象之前拦截一层代理,可以通过操作代理实现操作对象。
        const obj = {
            addr:"北京"
        }
        // 创建代理obj
        const p = new Proxy(obj,{
            // 拦截取值动作
            get: function(target,key){  // 目标对象,属性
                console.log("拦截get操作--vue这里做了更复杂的操作")
                // console.log(target)
                // console.log(key)
                // return target[key]
                return Reflect.get(target,key)  // 反射的方式取值
            },
            // 拦截设置值的动作
            set: function(target,key,value){
                console.log('拦截set操作--vue这里做了更复杂的操作')
                target[key]=value
                Reflect.set(target,key,value)
            }
        })
    </script>
</body>
</html>

选项式API扩展知识

computed

computed 计算属性——用于简化模板里的逻辑

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue_test07</title>
</head>
<body>
  <div id="root">
    <h3>{{chilema}}</h3>
    <button @click="ate=!ate">吃饭/消化</button>
  </div>
  <script src="./vue.js"></script>
  <script>
    const vm = Vue.createApp({
      data(){
        return{
          ate: false
        }
      },
      computed:{  // 计算属性——用于简化模板里的逻辑
        chilema(){  // 定义方法——模板里面当做属性来用
          return this.ate?"吃过了":"没吃呢"
        }
      }
      // computed与methods的区别:
      // computed会缓存结果(当操作的数据没有发生改变时),
      // 而methods会立即执行,不缓存结果。
    }).mount("#root")
  </script>
</body>
</html>

watch

watch监听器,可以检测数据的变化,执行一些复杂逻辑

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue_test08</title>
</head>
<body>
  <!-- 监听器的作用:可以检测数据的变化,执行一些复杂逻辑 -->
  <div id="root">
    <input type="text" placeholder="请输入用户名" v-model="username">
    <h3>判断结果:{{result}}</h3>
    <input type="password" placeholder="请输入密码" v-model="password">
    <input type="password" placeholder="请再次输入密码" v-model="password_repeat">
    <h3>{{res}}</h3>
  </div>
  <script src="./vue.js"></script>
  <script>
    Vue.createApp({
      data(){
        return{
          username:'',
          result:'',
          password:'',
          password_repeat:'',
          res:''
        }
      },
      watch:{
        // 监听器语法
        // 监听的变量名(new变量名,old变量名){判断,如果新变量名xxxx,就xxxx}
        username(newname,oldname){
          console.log('newname:',newname)
          console.log('oldname:',oldname)
          if(newname.length<8){
            this.result='用户名不合法'
          }else{
            this.result="合法"
          }
        },
        password_repeat(newvalue,oldvalue){
          if(newvalue !=this.password){
            this.res='两次密码输入不一致'
          }else{
            this.res=''
          }
        }
      }
    }).mount("#root")
  </script>
</body>
</html>

文章作者: 老百
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 老百 !
 上一篇
前端框架Vue(二) 前端框架Vue(二)
Vue 是一款用于构建用户界面的 JavaScript 框架。本小节介绍了Vue的组件的定义及组件间的相互通信。附Vue开发环境搭建。
2023-07-18
下一篇 
Python Web UI自动化测试之PO模式 Python Web UI自动化测试之PO模式
目前提到Web UI自动化测试,最先想到的就是Selenium。Selenium支持多种浏览器、多种程序语言及多种平台,并且支持分布式,是当前最主流的Web UI测试框架。
2023-07-06
  目录