Vue3 learning

Attribute binding 

<span v-html="rawHtml"></span>

Note that you cannot  v-html concatenate composite templates with , since Vue is not a string-based templating engine. When using Vue, you should use components as the basic unit of UI reuse and composition.

<div v-bind:id="dynamicId"></div>

 v-bind The directive instructs Vue to   match id the attribute of the element with the attribute of the component  . dynamicIdIf the bound value is  null or  undefined, the attribute will be removed from the rendered element.

Because  v-bind it is so common, we provide a specific shorthand syntax:

<div :id="dynamicId"></div>

Another example is  v-on a directive, which will listen to DOM events:

<a v-on:click="doSomething"> ... </a>

<!-- 简写 -->
<a @click="doSomething"> ... </a>

The parameter here is the name of the event to listen to: click. v-on There is a corresponding abbreviation,  @ character.

<button :disabled="isButtonDisabled">Button</button>

When  true or an empty string (i.e.  ), isButtonDisabled the element will contain this   attribute. And when it is other false value attribute will be ignored.<button disabled="">disabled

Binding multiple values

If you have a JavaScript object with multiple attributes like this:

const objectOfAttrs = {
  id: 'container',
  class: 'wrapper'
}

By taking no arguments  v-bind, you can bind them to a single element:

<div v-bind="objectOfAttrs"></div>

Using JavaScript expressions

So far, we have only bound some simple property names in the template. But Vue actually supports full JavaScript expressions in all data bindings:

{
   
   { number + 1 }}

{
   
   { ok ? 'YES' : 'NO' }}

{
   
   { message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

These expressions will be parsed and executed as JavaScript with the scope of the current component instance.

Directives

Directives are  v- special attributes with a prefix. Vue provides a number of built-in directives , including the  v-bind and  v-html.

v-forThe expected value of a directive attribute is a JavaScript expression (with a few exceptions, , v-on and ,  discussed later  v-slot). A directive's job is to reactively update the DOM when the value of its expression changes. Take  v-if  as an example:

<p v-if="seen">Now you see me</p>

Here, v-if the directive  seen removes/inserts the element based on the true or false value of  the expression <p> .

Parameter Arguments

Some commands require a "parameter", which is identified by a colon after the command name. For example to  v-bind reactively update an HTML attribute with a directive:

<a v-bind:href="url"> ... </a>
<!-- 简写 -->
<a :href="url"> ... </a>

Here  href is a parameter, which tells  v-bind the directive to  url bind the value of the expression to the attribute of the element  href .

Dynamic parameters

It is also possible to use a JavaScript expression on the command parameter, which needs to be enclosed in a pair of square brackets:

<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>

<!-- 简写 -->
<a :[attributeName]="url"> ... </a>

Modifiers

Modifiers are special suffixes beginning with a dot that indicate that the directive needs to be bound in some special way. For example  .prevent the modifier tells  v-on the directive to call on the fired event  event.preventDefault():

<form @submit.prevent="onSubmit">...</form>

Declare reactive state

We can   create a reactive object or array using the reactive() function:

import { reactive } from 'vue'

const state = reactive({ count: 0 })

To use reactive state in component templates, it needs to be  setup() defined and returned in a function. 

import { reactive } from 'vue'

export default {
  // `setup` 是一个专门用于组合式 API 的特殊钩子函数
  setup() {
    const state = reactive({ count: 0 })

    function increment() {
      state.count++
    }

    // 暴露state、 increment 函数到模块
    return {
      state,
      increment
    }
  }
}

Exposed methods are typically used as event listeners: 

<button @click="increment">
  {
   
   { state.count }}
</button>

<script setup>

setup() Exposing lots of state and methods manually in  functions is tedious. Fortunately, we can make this easier by using build tools. When using single file components (SFC), we can use  <script setup> to greatly simplify the code.

<script setup>
import { reactive } from 'vue'

const state = reactive({ count: 0 })

function increment() {
  state.count++
}
</script>

<template>
  <button @click="increment">
    {
   
   { state.count }}
  </button>
</template>

reactive() The API has two restrictions: 1. It is only valid for object types (  collection types  such as object, array, Mapand ), but not for  primitive types  such as  ,  and   . 2. Because Vue's reactive system is tracked through property access, we must always keep the same reference to the reactive object. This means that we cannot arbitrarily "replace" a reactive object, as this would cause the reactive connection to the original reference to be lost;Setstringnumberboolean

ref() Define responsive variables with 

 ref()  method to allow us to create reactive  refs that can use any value type :

ref() Wrap the value of the incoming parameter as a  .value ref object with attributes:

const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

TypeScript users see: Annotating types for refs 

Similar to properties of reactive objects, ref  .value properties are also reactive. At the same time, when the value is an object type,  reactive() it will be converted automatically  .value.

Unwrapping ref in template

When refs are accessed as top-level attributes in templates, they are automatically "unwrapped", so they don't need to be used  .value. Here is the previous counter example,  ref() replaced with:

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {
   
   { count }} <!-- 无需 .value -->
  </button>
</template>

ref unwrapping for array and collection types 

Unlike reactive objects, refs  Map are not unwrapped when accessed as elements of a reactive array or like this native collection type.

const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)

const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)

computed property 

Use computed properties to describe complex logic that relies on reactive state;

<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
  <p>Has published books:</p>
  <span>{
   
   { publishedBooksMessage }}</span>
</template>

computed() The method expects to receive a getter function that returns a computed property ref . Similar to other normal refs.

You may have noticed that calling a function in an expression like this also gets the same result as a computed property:

<p>{
   
   { calculateBooksMessage() }}</p>
// 组件中
function calculateBooksMessage() {
  return author.books.length > 0 ? 'Yes' : 'No'
}

If we define the same function as a method instead of a computed property, the two approaches are indeed identical in result, however, the difference is that the computed property value will be cached based on its reactive dependencies. A computed property is only recomputed when its reactive dependencies are updated, so using a computed property is much better than calling a function . This means that as long as  author.books it does not change, no matter how many times it is accessed  publishedBooksMessage , the previous calculation result will be returned immediately without re-executing the getter function.

It's important to keep in mind that getters for computed properties should only do computation and not have any other side effects. For example, don't make asynchronous requests or change the DOM in getters !

warn

 It is not recommended to use both  v-if and  at the same time , because the precedence of the two is not obvious. Please see the style guide for more information.v-for

v-for list rendering

v-for Properties and variables in the parent scope are fully accessible within the block v-for An optional second parameter is also supported to indicate the position index of the current item.

const parentMessage = ref('Parent')
const items = ref([{id:'1', message: 'Foo' }, { id:'2',message: 'Bar' }])
<li v-for="(item, index) in items" :key="item.id">
  {
   
   { parentMessage }} - {
   
   { index }} - {
   
   { item.message }}
</li>
  • Parent - 0 - Foo
  • Parent - 1 - Bar

v-for with the object

You can also use  v-for to iterate over all properties of an object. The order of traversal will  Object.keys() be determined based on the return value of the call on the object.

const myObject = reactive({
  title: 'How to do lists in Vue',
  author: 'Jane Doe',
  publishedAt: '2016-04-10'
})
<ul>
  <li v-for="value in myObject">
    {
   
   { value }}
  </li>
</ul>

You can indicate the property name (such as key) by providing a second parameter:

<li v-for="(value, key) in myObject">
  {
   
   { key }}: {
   
   { value }}
</li>

The third parameter indicates the position index:

<li v-for="(value, key, index) in myObject">
  {
   
   { index }}. {
   
   { key }}: {
   
   { value }}
</li>

<template>on v-for

Similar to templates  v-if , you can also  <template> use it on tags  v-for to render a block containing multiple elements.

<ul>
  <template v-for="item in items">
    <li>{
   
   { item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

v-for It is recommended to provide an  attribute whenever feasible  key , unless the DOM content being iterated is very simple (for example: does not contain components or stateful DOM elements), or you want to use the default behavior intentionally to improve performance

There is no difference between using it on a component  v-for and using it on a normal element (don't forget to provide one  key):

<MyComponent v-for="item in items" :key="item.id" />

However, this does not automatically pass any data to the component, since components have their own separate scope. In order to pass the iterated data into the component, we also need to pass props:

<MyComponent
  v-for="(item, index) in items"
  :item="item"
  :index="index"
  :key="item.id"
/>

The reason for not automatically  item injecting components is that this would  v-for tightly couple the components to how they work. Being explicit about the origin of its data enables components to be reused in other contexts.

Guess you like

Origin blog.csdn.net/xiaoxiong_jiaxin/article/details/130249678