VUE3 语法教程

vue3 起步

刚开始学习 Vue,我们不推荐使用 vue-cli 命令行工具来创建项目,更简单的方式是直接在页面引入 vue.global.js 文件来测试学习。

Vue3 中的应用是通过使用 createApp 函数来创建的,语法格式如下:

const app = Vue.createApp({ /* 选项 */ })

传递给 createApp 的选项用于配置根组件。在使用 mount() 挂载应用时,该组件被用作渲染的起点。

一个简单的实例:

Vue.createApp(HelloVueApp).mount(‘#hello-vue’)
createApp 的参数是根组件(HelloVueApp),在挂载应用时,该组件是渲染的起点。

一个应用需要被挂载到一个 DOM 元素中,以上代码使用 mount(‘#hello-vue’) 将 Vue 应用 HelloVueApp 挂载到

中。

接下来我们从 Hello Vue!! 的代码开始学起。

Vue 3.0 实例

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="hello-vue" class="demo">
  {{ message }}
</div>

<script>
const HelloVueApp = {
  data() {
    return {
      message: 'Hello Vue!!'
    }
  }
}

Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
</body>
</html>

以上实例中,我们先在 HTML 页面中引入 Vue 的 JS 文件:

<script src="https://unpkg.com/vue@next"></script>

HTML 页面中有一个 div 元素:

<div id="hello-vue" class="demo">
  {{ message }}
</div>

mount(‘#hello-vue’) 将 Vue 应用 HelloVueApp 挂载到

中。

{{ }} 用于输出对象属性和函数返回值。

{{ message }} 对应应用中 message 的值。

data 选项

data 选项是一个函数。Vue 在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后 Vue 会通过响应性系统将其包裹起来,并以 $data 的形式存储在组件实例中。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app" class="demo"></div>

<script>
const app = Vue.createApp({
  data() {
    return { count: 4 }
  }
})

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

document.write(vm.$data.count) // => 4
document.write("<br>")
document.write(vm.count)       // => 4
document.write("<br>")
// 修改 vm.count 的值也会更新 $data.count
vm.count = 5
document.write(vm.$data.count) // => 5
document.write("<br>")
// 反之亦然
vm.$data.count = 6
document.write(vm.count) // => 6
</script>
</body>
</html>

以上实例属性仅在实例首次创建时被添加,所以你需要确保它们都在 data 函数返回的对象中。

方法

我们可以在组件中添加方法,使用 methods 选项,该选项包含了所需方法的对象。

以下实例我们添加了 methods 选项,选项中包含了 increment() 方法:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app" class="demo"></div>

<script>
const app = Vue.createApp({
  data() {
    return { count: 4 }
  },
  methods: {
    increment() {
      // `this` 指向该组件实例
      this.count++
    }
  }
})

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

document.write(vm.count) // => 4
document.write("<br>")
vm.increment()

document.write(vm.count) // => 5
</script>
</body>
</html>

Vue3 指令

Vue 指令(Directives)是 Vue.js 的一项核心功能,它们可以在 HTML 模板中以 v- 开头的特殊属性形式使用,用于将响应式数据绑定到 DOM 元素上或在 DOM 元素上进行一些操作。

Vue 指令是带有前缀 v- 的特殊 HTML 属性,它赋予 HTML 标签额外的功能。

与传统的 JavaScript 方法相比,使用 Vue 创建响应式页面要容易得多,并且需要的代码更少。

以下是几个常用的 Vue 指令:

指令描述
v-bind用于将 Vue 实例的数据绑定到 HTML 元素的属性上。
v-if用于根据表达式的值来条件性地渲染元素或组件。
v-showv-show 是 Vue.js 提供的一种指令,用于根据表达式的值来条件性地显示或隐藏元素。
v-for用于根据数组或对象的属性值来循环渲染元素或组件。
v-on用于在 HTML 元素上绑定事件监听器,使其能够触发 Vue 实例中的方法或函数。
v-model用于在表单控件和 Vue 实例的数据之间创建双向数据绑定。

除了这些常用的指令,Vue 还提供了一些其他的指令,如 v-text、v-html 等,以及自定义指令,让开发者能够更加灵活地操作 DOM 元素。

Vue3 模板语法

Vue 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。

Vue 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。

结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。

插值

  • 文本

数据绑定最常见的形式就是使用 {{…}}(双大括号)的文本插值:

文本插值

<div id="app">
  <p>{{ message }}</p>
</div>

{{…}} 标签的内容将会被替代为对应组件实例中 message 属性的值,如果 message 属性的值发生了改变,{{…}} 标签内容也会更新。

如果不想改变标签的内容,可以通过使用 v-once 指令执行一次性地插值,当数据改变时,插值处的内容不会更新。

<span v-once>这个将不会改变: {{ message }}</span>

用户输入

在 input 输入框中我们可以使用 v-model 指令来实现双向数据绑定:

双向数据绑定

<div id="app">
    <p>{{ message }}</p>
    <input v-model="message">
</div>
 
<script>
const app = {
  data() {
    return {
      message: 'Runoob!'
    }
  }
}
 
Vue.createApp(app).mount('#app')
</script>

v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

按钮的事件我们可以使用 v-on 监听事件,并对用户的输入进行响应。

以下实例在用户点击按钮后对字符串进行反转操作:

字符串反转

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">反转字符串</button>
</div>
    
<script>
const app = {
  data() {
    return {
      message: 'Runoob!'
    }
  },
  methods: {
    reverseMessage() {
      this.message = this.message
        .split('')
        .reverse()
        .join('')
    }
  }
}
 
Vue.createApp(app).mount('#app')
</script>

缩写

  • v-bind 缩写

Vue.js 为两个最为常用的指令提供了特别的缩写:

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
  • v-on 缩写
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>

Vue3 组件

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:

每个 Vue 应用都是通过用 createApp 函数创建的,传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。

一个应用需要被挂载到一个 DOM 元素中。

以下实例我们将 Vue 应用挂载到

,应该传入 #app:

const RootComponent = { /* 选项 */ }
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')

注册一个全局组件语法格式如下:

const app = Vue.createApp({...})

app.component('my-component-name', {
  /* ... */
})

my-component-name 为组件名,/* … */ 部分为配置选项。注册后,我们可以使用以下方式来调用组件:

<my-component-name></my-component-name>

一个简单的 Vue 组件的实例:

全局组件实例
注册一个简单的全局组件 runoob,并使用它:

<div id="app">
    <runoob></runoob>
</div>
 
<script>
// 创建一个Vue 应用
const app = Vue.createApp({})
 
// 定义一个名为 runoob的新全局组件
app.component('runoob', {
    template: '<h1>自定义组件!</h1>'
})
 
app.mount('#app')
</script>

接下来我们再注册一个 button-counter 组件,在每次点击后,计数器会加 1:

// 创建一个Vue 应用
const app = Vue.createApp({})

// 定义一个名为 button-counter 的新全局组件
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      点了 {{ count }} 次!
    </button>`
})
app.mount('#app')
</script>

注意:template 中 ` 是反引号,不是单单引号 '。

组件的复用

你可以将组件进行任意次数的复用:

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

全局组件

以上的实例中我们的组件都只是通过 component 全局注册的。

全局注册的组件可以在随后创建的 app 实例模板中使用,也包括根实例组件树中的所有子组件的模板中。

全局组件实例
注册一个简单的全局组件 runoob,并使用它:

<div id="app">
    <runoob></runoob>
</div>
 
<script>
// 创建一个Vue 应用
const app = Vue.createApp({})
 
// 定义一个名为 runoob 的新全局组件
app.component('runoob', {
    template: '<h1>自定义组件!</h1>'
})
 
app.mount('#app')
</script>

局部组件

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

const ComponentA = {
  /* ... */
}
const ComponentB = {
  /* ... */
}
const ComponentC = {
  /* ... */
}

然后在 components 选项中定义你想要使用的组件:

const app = Vue.createApp({
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字(component-a、component-b),其属性值就是这个组件的选项对象(ComponentA、ComponentB)。

我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:

局部组件实例
注册一个简单的局部组件 runoobA,并使用它:

<div id="app">
    <runoob-a></runoob-a>
</div>
<script>
var runoobA = {
  template: '<h1>自定义组件!</h1>'
}
 
const app = Vue.createApp({
  components: {
    'runoob-a': runoobA
  }
})
 
app.mount('#app')
</script>

Prop

prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。

父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”:

Prop 实例

<div id="app">
  <site-name title="Google"></site-name>
  <site-name title="Runoob"></site-name>
  <site-name title="Taobao"></site-name>
</div>
 
<script>
const app = Vue.createApp({})
 
app.component('site-name', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})
 
app.mount('#app')
</script>

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

动态 Prop

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:

Prop 实例

<div id="app">
  <site-info
    v-for="site in sites"
    :id="site.id"
    :title="site.title"
  ></site-info>
</div>
 
<script>
const Site = {
  data() {
    return {
      sites: [
        { id: 1, title: 'Google' },
        { id: 2, title: 'Runoob' },
        { id: 3, title: 'Taobao' }
      ]
    }
  }
}
 
const app = Vue.createApp(Site)
 
app.component('site-info', {
  props: ['id','title'],
  template: `<h4>{{ id }} - {{ title }}</h4>`
})
 
app.mount('#app')
</script>

Prop 验证

组件可以为 props 指定验证要求。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

type 可以是下面原生构造器:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

type 也可以是一个自定义构造器,使用 instanceof 检测。

Vue3 计算属性

计算属性关键词: computed。

计算属性在处理一些复杂逻辑时是很有用的。

可以看下以下反转字符串的例子:

<div id="app">
  {{ message.split('').reverse().join('') }}
</div>

实例 1 中模板变的很复杂起来,也不容易看懂理解。

接下来我们看看使用了计算属性的实例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/3.0.5/vue.global.js"></script>
</head>
<body>
<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
    
<script>
const app = {
  data() {
    return {
      message: 'RUNOOB!!'
    }
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
}
 
Vue.createApp(app).mount('#app')
</script>
</body>
</html>

实例 2 中声明了一个计算属性 reversedMessage 。

提供的函数将用作属性 vm.reversedMessage 的 getter 。

vm.reversedMessage 依赖于 vm.message,在 vm.message 发生改变时,vm.reversedMessage 也会更新。

computed vs methods

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

methods: {
  reversedMessage2: function () {
    return this.message.split('').reverse().join('')
  }
}

可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。

computed setter

computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

const app = {
  data() {
    return {
      name: 'Google',
      url: 'http://www.google.com'
    }
  },
  computed: {
    site: {
      // getter
      get: function () {
        return this.name + ' ' + this.url
      },
      // setter
      set: function (newValue) {
        var names = newValue.split(' ')
        this.name = names[0]
        this.url = names[names.length - 1]
      }
    }
  }
}
vm = Vue.createApp(app).mount('#app')
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);
document.write('<br>------ 更新数据 ------<br>');
// 调用 setter, vm.name 和 vm.url 也会被对应更新
vm.site = '菜鸟教程 https://www.runoob.com';
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);

从实例运行结果看在运行 vm.site = ‘菜鸟教程 http://www.runoob.com’; 时,setter 会被调用, vm.name 和 vm.url 也会被对应更新。

Vue3 监听属性

本章节,我们将为大家介绍 Vue3 监听属性 watch,我们可以通过 watch 来响应数据的变化。

以下实例通过使用 watch 实现计数器:

<div id = "app">
    <p style = "font-size:25px;">计数器: {{ counter }}</p>
    <button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
   
<script>
const app = {
  data() {
    return {
      counter: 1
    }
  }
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('counter', function(nval, oval) {
    alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
</script>

以下实例进行千米与米之间的换算:

<div id = "app">
    千米 : <input type = "text" v-model = "kilometers"  @focus="currentlyActiveField = 'kilometers'">
    米 : <input type = "text" v-model = "meters" @focus="currentlyActiveField = 'meters'">
</div>
<p id="info"></p>    
<script>
const app = {
  data() {
    return {
      kilometers : 0,
      meters:0
    }
  },
  watch : {
    kilometers:function(newValue, oldValue) {
      // 判断是否是当前输入框
      if (this.currentlyActiveField === 'kilometers') {
        this.kilometers = newValue;
        this.meters = newValue * 1000
      }
    },
    meters : function (newValue, oldValue) {
      // 判断是否是当前输入框
      if (this.currentlyActiveField === 'meters') {
        this.kilometers = newValue/ 1000;
        this.meters = newValue;
      }
    }
  }
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('kilometers', function (newValue, oldValue) {
  // 这个回调将在 vm.kilometers 改变后调用
  document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>

点击 “尝试一下” 按钮查看在线实例

以上代码中我们创建了两个输入框,data 属性中, kilometers 和 meters 初始值都为 0。watch 对象创建了 data 对象的两个监控方法: kilometers 和 meters。

当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值。

异步加载中使用 watch

异步数据的加载 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。

以下实例我们使用 axios 库,后面会具体介绍。

<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.staticfile.org/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/3.2.37/vue.global.min.js"></script>
<script>
  const watchExampleVM = Vue.createApp({
    data() {
      return {
        question: '',
        answer: '每个问题结尾需要输入 ? 号。'
      }
    },
    watch: {
      // 每当问题改变时,此功能将运行,以 ? 号结尾,兼容中英文 ?
      question(newQuestion, oldQuestion) {
        if (newQuestion.indexOf('?') > -1 || newQuestion.indexOf('?') > -1) {
          this.getAnswer()
        }
      }
    },
    methods: {
      getAnswer() {
        this.answer = '加载中...'
        axios
          .get('/try/ajax/json_vuetest.php')
          .then(response => {
            this.answer = response.data.answer
          })
          .catch(error => {
            this.answer = '错误! 无法访问 API。 ' + error
          })
      }
    }
  }).mount('#watch-example')
</script>

Vue3 样式绑定

Vue.js class

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。

v-bind 在处理 class 和 style 时, 表达式除了可以使用字符串之外,还可以是对象或数组。

v-bind:class 可以简写为 :class。

class 属性绑定

我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:

实例 1
实例中将 isActive 设置为 true 显示了一个绿色的 div 块,如果设置为 false 则不显示:

<div :class="{ 'active': isActive }"></div>

以上实例 div class 渲染结果为:

<div class="active"></div>

我们也可以在对象中传入更多属性用来动态切换多个 class 。

此外,:class 指令也可以与普通的 class 属性共存。

实例 2
text-danger 类背景颜色覆盖了 active 类的背景色:

<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }">
</div>

以上实例 div class 渲染结果为:

<div class="static text-danger"></div>

当 isActive 或者 hasError 变化时,class 属性值也将相应地更新。例如,如果 active 的值为 true,class 列表将变为 “static active text-danger”。

我们也可以直接绑定数据里的一个对象:

实例 3
text-danger 类背景颜色覆盖了 active 类的背景色:

<div id="app">
    <div class="static" :class="classObject"></div>
</div>

实例 3 与 实例 2 的渲染结果是一样的。

此外,我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:

实例 4

data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

数组语法

我们可以把一个数组传给 v-bind:class ,实例如下:

实例 5

<div class="static" :class="[activeClass, errorClass]"></div>

以上实例 div class 渲染结果为:

<div class="static active text-danger"></div>

我们还可以使用三元表达式来切换列表中的 class :

实例 6
errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类:

<div id="app">
    <div class="static" :class="[isActive ? activeClass : '', errorClass]"></div>
</div>

以上实例 div class 渲染结果为:

<div class="static text-danger"></div>

Vue.js style(内联样式)

我们可以在 v-bind:style 直接设置样式,可以简写为 :style:

实例 7

<div id="app">
    <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>

以上实例 div style 渲染结果为:

<div style="color: red; font-size: 30px;">菜鸟教程</div>

也可以直接绑定到一个样式对象,让模板更清晰:

实例 8

<div id="app">
  <div :style="styleObject">菜鸟教程</div>
</div>

v-bind:style 可以使用数组将多个样式对象应用到一个元素上:

实例 9

<div id="app">
  <div :style="[baseStyles, overridingStyles]">菜鸟教程</div>
</div>

注意:当 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform ,Vue.js 会自动侦测并添加相应的前缀。

多重值

可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。

组件上使用 class 属性

当你在带有单个根元素的自定义组件上使用 class 属性时,这些 class 将被添加到该元素中。此元素上的现有 class 将不会被覆盖。

实例 10

<div id="app">
    <runoob class="classC classD"></runoob>
</div>
 
<script>
// 创建一个Vue 应用
const app = Vue.createApp({})
 
// 定义一个名为 runoob的新全局组件
app.component('runoob', {
    template: '<h1 class="classA classB">I like runoob!</h1>'
})
 
app.mount('#app')
</script>

以上实例 div class 渲染结果为:

<h1 class="classA classB classC classD">I like runoob!</h1>

对于带数据绑定 class 也同样适用:

<my-component :class="{ active: isActive }"></my-component>

当 isActive 为 true 时,HTML 将被渲染成为:

<p class="active">Hi</p>

如果你的组件有多个根元素,你需要定义哪些部分将接收这个类。可以使用 $attrs 组件属性执行此操作:

实例 11

<div id="app">
    <runoob class="classA"></runoob>
</div>
 
<script>
const app = Vue.createApp({})
 
app.component('runoob', {
  template: `
    <p :class="$attrs.class">I like runoob!</p>
    <span>这是一个子组件</span>
  `
})
 
app.mount('#app')
</script>

注意:template 中 ` 是反引号,不是单引号 '。

以上实例 div class 渲染结果为:

<div id="app" data-v-app=""><p class="classA">I like runoob!</p><span>这是一个子组件</span></div>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/42842.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode每日一题合集】2023.7.17-2023.7.23(离线算法 环形子数组的最大和 接雨水)

文章目录 415. 字符串相加&#xff08;高精度计算、大数运算&#xff09;1851. 包含每个查询的最小区间⭐⭐⭐⭐⭐解法1——按区间长度排序 离线询问 并查集解法2——离线算法 优先队列 874. 模拟行走机器人&#xff08;哈希表 方向数组&#xff09;918. 环形子数组的最大和…

ts中setState的类型

两种方法: 例子: 父组件 const [value, setValue] useState(); <ChildsetValue{setValue} />子组件 interface Ipros {setValue: (value: string) > void } const Child: React.FC<Ipros> (props) > {}

(css)清除el-table背景色

(css)清除el-table背景色 效果&#xff1a; <el-table:data"gridData":header-cell-style"{text-align:center,color: #fff}":cell-style"{text-align:center,color: #fff }" ><el-table-column type"index" label"序号…

Linux QT通过NFS挂载到Linux开发板上

Linux QT通过NFS挂载到Linux开发板上 说明&#xff1a;这里使用的Linux开发板是正点原子的阿尔法开发板 创建NFS 环境 NFS简介 网络文件系统&#xff0c;英文 Network File System(NFS)&#xff0c;是由 SUN 公司研制的 UNIX 表示层协议 (presentation layer protocol)&…

Spring Security 构建基于 JWT 的登录认证

一言以蔽之&#xff0c;JWT 可以携带非敏感信息&#xff0c;并具有不可篡改性。可以通过验证是否被篡改&#xff0c;以及读取信息内容&#xff0c;完成网络认证的三个问题&#xff1a;“你是谁”、“你有哪些权限”、“是不是冒充的”。 为了安全&#xff0c;使用它需要采用 …

【JavaEE】Spring中注解的方式去存储Bean对象

Spring的开发要点总结 文章目录 【JavaEE】Spring的开发要点总结&#xff08;2&#xff09;1. 通过类注解的方式存储Bean对象1.1 五大 类注解1.1.1 Controller 控制器存储1.1.2 Service 服务存储1.1.3 Repository 仓库存储1.1.4 Component 组件存储1.1.5 Configuration 配置存储…

iview的表格添加筛选功能需要注意的问题

给table的某列添加筛选功能 在table中通过给columns数据的项&#xff0c;设置 filters&#xff0c;可进行筛选&#xff0c;filters 接收一个数组。 然后再指定一个筛选函数 filterMethod 才可以进行筛选&#xff0c;filterMethod 传入两个参数value和 row。 如果指定 filter…

Ubuntu linux安装搜狗输入法

效果图&#xff1a; 一、首先要卸载掉自带的输入法 1、以root 身份登录系统并打开终端输入&#xff1a; apt-get remove ibus-pinyin 2、如果卸载后还需要使用&#xff0c;可通过如下方法安装 以root 身份登录系统并打开终端输入&#xff1a; apt-get install ibus-pinyin …

Matlab的GUI设计

文章目录 AppDesigner各个版本的特点mlapp文件基本格式AppDesigner的回调函数常见控件的属性MVC模式MVC模式设计GUIMVC简单使用 其他让app designer置顶将Guide的GUI导出为m文件将app编译为exe将app中的多个控件组合在一起 AppDesigner 20200328 各个版本的特点 在2017b版本中…

^(按位异或)操作符详解

因为未知&#xff0c;所以全力以赴 目录 例1.实现两个数的交换 例2.找出单身狗 1.简单版 2.进阶版 大家好&#xff0c;我是纪宁。这篇博客介绍^操作符及使用案例。 位操作符是对操作数的二进制补码进行操作。^就是位操作符的一种&#xff0c;叫按位异或操作符。计算结果是…

《零基础入门学习Python》第055讲:论一只爬虫的自我修养3:隐藏

0. 请写下这一节课你学习到的内容&#xff1a;格式不限&#xff0c;回忆并复述是加强记忆的好方式&#xff01; 上节课我们说过了&#xff0c;有一些网站比较痛恨爬虫程序&#xff0c;它们不喜欢被程序所访问&#xff0c;所以它们会检查链接的来源&#xff0c;如果说来源不是正…

【CN-Docker】window11下Docker下开启kubernetes

1. 安装Docker 安装docker步骤如下&#xff1a; 下载Docker启用hyper-v 2.1.powershell&#xff0c;管理员运行Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All安装wsl配置Docker镜像加速地址(阿里云) 4.1. "registry-mirrors": [&quo…

让GPT人工智能变身常用工具-上

1.密码生成器:GPT为您创建安全密码 想象GPT作为您的个人密码生成器,负责从头到尾为您创建复杂且安全的密码。您只需要告诉他您的密码需求,比如密码的长度,是否包含大写字母、小写字母、数字或特殊字符,他会立即为您生成一个复杂但经过深度设计的密码。 例子: 我希望您…

Selenium 修改 HTTP 请求头三种方式

目录 前言&#xff1a; 什么是 HTTP 请求头 需要更改 HTTP 请求请求头 Selenium 修改请求头 Java HTTP 请求框架 代码实战 使用反向代理 使用 Firefox 扩展 下载火狐浏览器扩展 加载火狐扩展 设置扩展首选项 设置所需的功能 完整自动化用例 前言&#xff1a; Sele…

内存函数及其模拟实现

身体扛不住的时候&#xff0c;意志会带你杀出重围 文章目录 一、memcpy函数 函数介绍 模拟实现 二、memmove函数 函数介绍 模拟实现 三、memset函数 函数介绍 模拟实现 大家好&#xff0c;我是纪宁。这篇文章给大家介绍C语言中常见的内存处理函数。 一、memcpy函数 …

blender 基础材质篇

材质展示 材质背景介绍 什么是PBR&#xff1f; PBR 全称为 Physically Based Rendering&#xff0c;译为基于物理属性的引擎渲染&#xff0c;也就是说会把物质的颜色、粗糙度、高光属性等进行分别处理&#xff0c;使物质体现出更真实的感觉&#xff1b; 什么是BRDF&#xff…

Vue.js基础简答题

系列文章目录 后续补充 文章目录 系列文章目录前言一、库与框架的区别是什么&#xff1f;二、Vue.js 的核心特性有哪些&#xff1f;三、什么是数据驱动视图&#xff1f;四、MVVM 模型各部分含义是什么&#xff0c;在 Vue.js 中分别对应哪些功能&#xff1f;五、el 选项的作用是…

安全开发-JS应用原生开发JQuery库Ajax技术加密编码库断点调试逆向分析元素属性操作

文章目录 JS原生开发-文件上传-变量&对象&函数&事件JS导入库开发-登录验证-JQuery库&Ajax技术JS导入库开发-编码加密-逆向调试 JS原生开发-文件上传-变量&对象&函数&事件 1、布置前端页面 2、JS获取提交数据 3、JS对上传格式判断 <script>…

数据仓库发展历史

数据仓库发展历史 一、演变 数据仓库是企业中用于存储、整合和分析数据的关键组件。随着时间的推移&#xff0c;数据仓库经历了三代演化&#xff1a;从需求驱动到平台化、从平台化到智能&#xff08;AI&#xff09;化 二、第一代&#xff08;过时&#xff09; 第一代数据仓…

第四讲:MySQL中DDL一些基本数据类型及表的创建、查询

目录 1、创建表:2、DDL一些基本数据类型&#xff1a; 1、创建表: 部分单词及解析&#xff1a; 1、tables:表 2、comment:评论&#xff0c;解释 3、gender:性别 4、neighbor&#xff1a;邻居 1、创建表&#xff1a;&#xff08;注&#xff1a;在自定义数据库操作&#xff0c;…