Vue-无构建工具的创建、挂载、渲染

简介

Vue是一个动态构建用户界面的 渐进式 JS框架.

  • 借鉴了Angular的模板语法和数据绑定
  • 借鉴了React的组件化和虚拟DOM

特点:

  1. 声明式渲染: 先声明后使用
  2. 响应式数据: 数据改变时, 视图会响应数据的改变, 重新渲染新的值
  3. 组件化开发

安装

  1. 项目初始化: npm init -y
  2. 安装vue: npm install vue

无构建工具的环境

引入vue.js

  • vue.global.js是完整版(在初学阶段使用)
  • esm(ES Module): 使用ES的模块规范导入导出export default
  • runtime: 运行时版本, 相对于编译版本, 体积更小, 效率更高
<!-- 1. 引入vue.js -->
<script src="./node_modules/vue/dist/vue.global.js"></script>

编写页面(视图)

<!-- 2. 编写页面 -->
<div id="app">hello</div>

创建App实例并挂载

<script>
  // 1. 从Vue中解构相应的API
  const { createApp } = Vue

  // 2. 创建App, 传入一个对象, 返回一个应用实例
  const app = createApp({})
  // 3. 挂载
  app.mount('#app')
</script>

声明式渲染

跟变量, 函数类似, 需要使用什么就先声明一下.

  1. 声明状态(变量)
const app = createApp({
  // data 配置项: data必须是一个函数, 在函数中返回对象, 在返回的对象中声明状态
  data() {
    return {
      msg: 'hello',
    }
  },
})
  1. 使用状态(变量)
<div id="app">
  // 通过{{}}(插值表达式)使用在data中定义的状态
  {{ msg }}
</div>

完整代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 1. 引入vue.js -->
    <script src="../04.vue/node_modules/vue/dist/vue.global.js"></script>
  </head>
  <body>
    <!-- 2. 创建div容器 -->
    <div id="app">
      姓名: {{name}} <br />
      年龄: {{age}} <br />
      学号: {{stu.sn}} <br />
      书籍: {{books[0]}}
    </div>

    <script>
      const { createApp } = Vue
      const app = createApp({
        data() {
          return {
            name: 'xiaoming',
            age: 20,
            stu: {
              sn: '20200101',
            },
            books: ['vue', 'js', 'gis'],
          }
        },
      })
      const instance = app.mount('#app')
    </script>
  </body>
</html>

挂载

一个应用实例必须在调用了 .mount() 方法后才会渲染

  • 传入参数: 可以是一个 CSS 选择器字符串(常用) 或者 一个实际的 DOM 元素
  • 返回值: 根组件实例
<body>
  <div id="app">{{msg}}</div>

  <script>
    const { createApp } = Vue
    const app = createApp({
      data() {
        return {
          msg: 'hello',
        }
      },
    })
    console.log(app)
    // 由于mount返回的不是app实例本身, 因此mount的调用需要放在链式调用的最后
    const instance = app.mount('#app')
    console.log(instance)  // Proxy对象
  </script>
</body>

根组件实例

在data中定义的状态会被代理到instance上.

当改变代理对象的状态值时, 可以拦截到set操作, 从而自定义set操作.

在自定义的set操作中更新DOM

setTimeout(() => {
  instance.msg = 'world'
}, 1000)

响应式原理

<body>
  <script>
    const obj = {
      name: 'xiaoming',
      0: 'test',
    }
    // 对象访问属性必须使用[]语法的两种情况
    // 1. 属性名是一个无效的标识符
    // 2. 属性名是一个变量
    // console.log(obj[0])
    let key = 'name'
    // console.log(obj[key]) // obj.name

    // 创建代理对象的过程叫做属性的劫持
    // 1. 将普通对象(目标对象)的每一个属性拦截, 添加自定义的getter和setter
    // 2. 后续对代理对象属性的设置, 触发自定义setter, 在setter中更新页面

    // p对象可以认为包含任意属性, 代理对象有效的属性跟目标对象是一致
    const p = new Proxy(obj, {
      get(target, key) {
        // 当访问p对象的属性时, 调用该函数, 将该函数的返回值做为表达式的结果
        // target: 目标对象
        // key: 代理对象的属性
        console.log('访问${key}属性')
        return target[key]
      },
      set(target, key, value) {
        console.log('设置${key}属性')
        target[key] = value
      },
    })
    console.log(p)
    
    // 对于普通对象而言, 访问的过程是由js引擎控制
    // console.log(obj.name)
    // 自定义的访问过程, 叫属性的getter操作(元编程)[meta]
  </script>
</body>

基本选项

状态

data选项

  1. data选项必须是一个函数
  2. 在函数中返回一个对象, 在对象中定义状态
  3. 在data中定义的状态, 可以在模板中使用
const app = createApp({
  data() {
    return {
      msg: 'hello',
    }
  },
})

方法

methods选项

  1. 语法: methods中定义方法
  2. 作用: 修改data中的状态
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
  </head>
  <body>
    <div id="app">
      <button v-on:click="increment">点击+1: {{count}}</button>
    </div>

    <script>
      const { createApp } = Vue

      const app = createApp({
        data() {
          return {
            count: 0,
          }
        },
        methods: {
          increment() {
            // methods中定义的方法要求是普通函数 在普通函数中通过this拿到当前实例对象
            // 该函数中的this指向当前根组件实例instance
            console.log(this)
            this.count++
          },
        },
      })
      const instance = app.mount('#app')
    </script>
  </body>
</html>
posted @ 2024-11-27 22:46  Khru  阅读(19)  评论(0编辑  收藏  举报