ホームページ  >  記事  >  ウェブフロントエンド  >  糖衣構文とは何ですか? Vue3.2でシンタックスシュガーを使用するにはどうすればよいですか?

糖衣構文とは何ですか? Vue3.2でシンタックスシュガーを使用するにはどうすればよいですか?

青灯夜游
青灯夜游転載
2022-11-28 20:11:241835ブラウズ

Vue で構文シュガーを使用するにはどうすればよいですか?次の記事では、シンタックス シュガーについて説明し、Vue3.2 シンタックス シュガーの使用方法を紹介します。

糖衣構文とは何ですか? Vue3.2でシンタックスシュガーを使用するにはどうすればよいですか?

1. 概要

Vue2 期間では、さまざまな変数、メソッド、および Computed 属性、などは、それぞれ datamethodscomputed、その他のオプションに格納されます。このように書かれたコードは、後で参照するのに便利ではありません。論理的には、オプション間を行き来する必要があります。 vue3.0Combined APIsetup 関数は、この問題を解決するために開始されました。これにより、論理的な焦点がより集中し、構文がより合理化されますが、vue3 の構文を使用すると、 .0 は、コンポーネントを構築するときに、外部で定義されたメソッド変数を d477f9ce7bf77f53fbcf36bec1b69b7a で使用する前に常に返す必要があり、少し面倒です。 . 2 糖衣構文といくつかの新しい API の登場により、コードがさらに簡素化されました。 [学習ビデオ共有: vue ビデオ チュートリアル Web フロントエンド ビデオ ]

構文糖衣とは何ですか?

シンタクティック シュガー (英語: Syntactic Sugar) は、イギリスのコンピュータ科学者 ピーター ランディングによって発明された用語で、ある特定のことを指します。言語の機能には影響を与えませんが、プログラマにとってはより便利な構文が追加されました。構文シュガーを使用すると、プログラムがより簡潔になり、読みやすくなります。

Vue3.2構文シュガー

vue3.0vue3.2

  • vue3.0 コンポーネント
  • <template>
        <div>
        </div>
    </template>
    <script>
    export default {
        components: {
        },
        props: {
        },
        setup () {
            return {}
        }
    }
    </script>
    <style scoped>
    </style>
    # の単一ファイル コンポーネント (SFC、.vue ファイル) の構造比較
    ##vue3.2
  • コンポーネント
    <template>
        <MyTestVue :title="title" @click="changeTitle" />
    </template>
    <script setup>
    import MyTestVue from &#39;./MyTest.vue&#39;;
    import { ref } from &#39;vue&#39;;
    const title = ref(&#39;测试一下&#39;)
    const changeTitle = () => {
        title.value = &#39;Hello,World&#39;
    }
    </script>
    <style scoped>
    </style>
    比較
  • vue3.0

    vue3.2 コンポーネント テンプレートのバージョンの主な変更点は、setup 関数が 3.2 ではなくなり、script タグに配置されたことです。

  • 定義したプロパティとメソッドは返す必要はなく、テンプレート構文で直接使用できます。 ...
  • これらは直感的な変更です。次に、具体的な使用方法を学びましょう。

  • #2. 使用方法の紹介

#1. コンポーネントの登録

vue3.0

でコンポーネントを使用する場合は、コンポーネント オプションを使用して明示的に登録する必要があります。

<script>
import ComponentA from &#39;./ComponentA.js&#39;

export default {
  components: {
    ComponentA
  },
  setup() {
    // ...
  }
}
</script>
vue3.2

5101c0cdbdc49998c642c71f6b6410a8 単一ファイル コンポーネントでは、インポートされたコンポーネントをテンプレートで直接使用できます。コンポーネントは自動的に登録され、現在のコンポーネントの名前を指定する必要はありません。ファイルに基づいて自動的に登録されます。 name。これは、name 属性を記述する必要がないことを意味します。

<script setup>
import ComponentA from &#39;./ComponentA.vue&#39;
</script>

<template>
  <ComponentA />
</template>

2.Props ステートメント

vue3.0

では、

prop が使用できますprops 宣言するオプション

<script>
export default {
  props: [&#39;foo&#39;],
  // 或者用这种方式指类型与默认值
  // props: {
  //   foo:{
  //     type: String,
  //     default: &#39;&#39;
  //   },
  // },
  setup(props) {
    // setup() 接收 props 作为第一个参数
    console.log(props.foo)
  }
}
</script>
vue3.2

コンポーネントでは、

defineProps()## を使用して props を宣言できます。 # マクロ <pre class="brush:js;toolbar:false;">&lt;script setup&gt; const props = defineProps([&amp;#39;foo&amp;#39;]) // 或者 const propsOther = defineProps({ title: String, likes: Number }) console.log(props.foo) &lt;/script&gt;</pre>注: すべてのプロパティは一方向バインディングの原則に従います。プロパティは親コンポーネントの更新によって変更され、新しい状態は子コンポーネントに入ることなく自然に下方に流れます。 reverse. パッシブ、これは子コンポーネント内の prop を変更すべきではないことを意味します。

3. 計算プロパティ

通常、リアクティブ状態に依存する複雑なロジックを記述するために計算プロパティを使用します。率直に言うと、この計算されたプロパティの値は他の応答プロパティの値に依存します。依存するプロパティが変更されると、この計算されたプロパティの値は再計算されます。
<script setup>
import { ref, computed } from &#39;vue&#39;

const firstName = ref(&#39;John&#39;)
const lastName = ref(&#39;Doe&#39;)

const fullName = computed({
  // getter
  get() {
    return firstName.value + &#39; &#39; + lastName.value
  },
  // setter
  set(newValue) {
    // 注意:我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(&#39; &#39;)
  }
})
</script>

fullName.value = 'John Doe'

が呼び出されると、

setter

が呼び出され、firstNamelastName は更新されます。vue3.2 では、d477f9ce7bf77f53fbcf36bec1b69b7a タグ内で直接使用できるため、戻る必要はなくなりました。 <blockquote><ul> <li>不要在计算函数中做异步请求或者更改 DOM!</li> <li>一个计算属性仅会在其响应式依赖更新时才重新计算,如果他依赖的是个非响应式的依赖,及时其值发生变化,计算属性也不会更新。</li> <li>相比于方法而言,计算属性值会基于其响应式依赖被缓存,一个计算属性仅会在其响应式依赖更新时才重新计算</li> </ul></blockquote> <h4 data-id="heading-7"><span style="font-size: 18px;"><strong>4. watch</strong></span></h4> <p>在组合式API中,我们可以使用<code>watch函数在每次响应式状态发生变化时触发回调函数,watch的第一个参数可以是不同形式的“数据源”:它可以是一个 ref(包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:watch()是懒执行的:仅当数据源变化时,才会执行回调,例如:

<script setup>
import { ref,watch } from &#39;vue&#39;;

const props = defineProps({
    title: String,
    itemList: {
        type: Array,
        default: () => [{
            text: &#39;title&#39;,
            value: 0
        }]
    }
})

watch(() => props.itemList.length,(newValue,oldValue) => {
    console.log(&#39;newValue===&#39;,newValue);
    console.log(&#39;oldValue===&#39;,oldValue);
})
</script>

这里监听props.itemList.length,当传入的itemList数量发生变化时,后面的回调方法会被调用。当然wacth()还有第三个可选参数:否开启深监听(deep), 如果这里这样写:

<script setup>
import { ref,watch } from &#39;vue&#39;;
...
watch(() => props.itemList,(newValue,oldValue) => {
    console.log(&#39;newValue===&#39;,newValue);
    console.log(&#39;oldValue===&#39;,oldValue);
})
</script>

当传入的itemList数量发生改变时,回调函数不会触发,正确的写法是加上其第三个参数deep:true

<script setup>
import { ref,watch } from &#39;vue&#39;;
...
watch(() => props.itemList,(newValue,oldValue) => {
    console.log(&#39;newValue===&#39;,newValue);
    console.log(&#39;oldValue===&#39;,oldValue);
},{deep:true})
</script>

watch也可以同时监听多个属性:

<script setup>
import { ref,watch } from &#39;vue&#39;;

const props = defineProps({
    title: String,
    itemList: {
        type: Array,
        default: () => [{
            text: &#39;title&#39;,
            value: 0
        }]
    }
})
// 同时监听多个属性
watch(() => [props.itemList,props.title],(newValue,oldValue) => {
    console.log(&#39;newValue===&#39;,newValue);
    console.log(&#39;oldValue===&#39;,oldValue);
},{deep:true})
  
</script>

5. watchEffect()

watch()的懒执行不同的是,watchEffect()会立即执行一遍回调函数,如果这时函数产生了副作用,Vue会自动追踪副作用的依赖关系,自动分析出响应源。上面的例子可以重写为:

<script setup>
  ...
watchEffect(() => {
    console.log(&#39;itemList===&#39;,props.itemList.length);
    console.log(&#39;title===&#39;,props.title);
})
</script>

这个例子中,回调会立即执行。在执行期间,它会自动追踪props.itemList.length作为依赖(和计算属性的行为类似)。每当传入的itemList.length变化时,回调会再次执行。

如果要清除watchEffect()的的监听,只需要显示的调用watchEffect()的返回函数就可以了,例如:

<script setup>
  ...
const stopEffect = watchEffect(() => {
    console.log(&#39;itemList===&#39;,props.itemList.length);
    console.log(&#39;title===&#39;,props.title);
})
stopEffect()
</script>

watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。我们能更加精确地控制回调函数的触发时机。 watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。

6.组件的事件调用

6.1 子组件调用父组件的方法

vue3.0中如果我们的子组件触发父组件的方法,我们的做法:

子组件
<script>
export default {
  emits: [&#39;inFocus&#39;, &#39;submit&#39;],
  setup(props, ctx) {
    ctx.emit(&#39;submit&#39;,params)
  }
}
// 或者将可以将emit解构使用
export default {
    setup(props,{emit}) {
    emit(&#39;submit&#39;,params)
  }
}
</script>
父组件
<template>
    <Children @submit="submitHandel"/>
  </div>
</template>

<script>
export default {
  name: &#39;TodoItem&#39;,
  setup(props, { emit }) {
    const submitHandel = () => {
      console.log(&#39;子组件调用了父组件的submitHandel方法&#39;);
    }
    return {
      submitHandel,
    }
  }
};
</script>

vue3.2语法糖中,子组件要触发的事件需要显式地通过 defineEmits() 宏来声明

子组件
<script setup>
const emit = defineEmits([&#39;inFocus&#39;, &#39;submit&#39;])

function buttonClick(parmas) {
  emit(&#39;submit&#39;, parmas)
}
</script>
父组件
<template>
    <Children @submit="submitHandel"/>
  </div>
</template>

<script setup>
  const submitHandel = () => {
    console.log(&#39;子组件调用了父组件的submitHandel方法&#39;);
  }
};
</script>
6.2 父组件调用子组件的方法或是属性

vue3.0中如果父组件触发子组件的方法或是属性,直接在return函数中返回就可以,数据都是默认隐式暴露给父组件的。

<script>
// 子组件
setup(props, { emit }) {
  const isShow = ref(false)
  // 父组件调用这个方法
  const showSubComponent = () => {
    isShow.value = !isShow.value
  }
  return {
      // return 返回
      showSubComponent,
    }
  }
</script>

父组件中通过ref获取到子组件,并对子组件暴露的方法进行访问

父组件
<template>
  <div class="todo-list">
    <TodoItemVue :itemList="itemList" @clickItemHandel="clickItemHandel" ref="todoItemVueRef" />
  </div>
</template>
<script>
  import { ref } from &#39;vue&#39;;
  export default {
  setup(props, { emit }) {
    //获取子组件ref
    const todoItemVueRef = ref(null)
    // 调用子组件的方法
    const callItemFuncHandel = () => {
        todoItemVueRef.value.showSubComponent()
    }
    return {
     todoItemVueRef
    }
  }
};
</script>

vue3.2语法中,父组件的调用方式相同,子组件通过defineExpose()将方法或是属性暴露出去

子组件
<script setup>
const isShow = ref(false)
// 父组件调用这个方法
const showSubComponent = () => {
    isShow.value = !isShow.value
}
// 通过defineExpose将方法暴露出去
defineExpose({
    showSubComponent
})
</script> 
父组件
<template>
  <div class="todo-list">
    <TodoItemVue :itemList="itemList" @clickItemHandel="clickItemHandel" ref="todoItemVueRef" />
  </div>
</template>
<script setup>
  import { ref } from &#39;vue&#39;;
  //获取子组件ref
  const todoItemVueRef = ref(null)
  // 调用子组件的方法
  const callItemFuncHandel = () => {
      todoItemVueRef.value.showSubComponent()
  }
</script>

7.Vuex的使用

vue3.0vue3.2中创建Vuex没有区别,只不过在d477f9ce7bf77f53fbcf36bec1b69b7a模板中使用Vuex的store有细微差别。

import { createStore } from &#39;vuex&#39;;
import { ADD_ITEM_LIST, REDUCE_ITEM_LIST, CHANGE_ITEM_LIST_ASYNC } from &#39;./constants&#39;;

export default createStore({
  state: {
    itemList: [
      { text: &#39;Learn JavaScript&#39;, done: true },
      { text: &#39;Learn Vue&#39;, done: false },
      { text: &#39;Build something awesome&#39;, done: false },
    ],
  },
  getters: {
    doneItemList: (state) => state.itemList.filter((todo) => todo.done),
  },
  mutations: {
    // 使用ES2015风格的计算属性命名功能 来使用一个常量作为函数名
    [ADD_ITEM_LIST](state, item) {
      console.log(&#39;增加数据&#39;, item);
      state.itemList.push(item);
    },
    [REDUCE_ITEM_LIST](state) {
      console.log(&#39;减少数据&#39;);
      state.itemList.pop();
    },
  },
  actions: {
    [CHANGE_ITEM_LIST_ASYNC]({ commit, state }, todoItem) {
      /// 模拟网络请求
      setTimeout(() => {
        commit(ADD_ITEM_LIST, todoItem);
        console.log(&#39;state===&#39;, state);
      }, 1000);
    },
  },
  modules: {
  },
});

vue3.0中我们一般在return中对store.state进行解构,然后可以直接在d477f9ce7bf77f53fbcf36bec1b69b7a中使用state中的值

<template>
  <div class="todo-item">
    <ol>
      <li v-for="(item,index) in itemList" :key="index" class="todos" @click="clickItem(index)">
        {{ item.text }}
      </li>
    </ol>
  </div>
</template>
<script>
  export default {
  name: &#39;TodoItem&#39;,
  setup(props, { emit }) {
    return {
      // 对store.state进行解构
      ...store.state,
      clickItem,
      count,
      isShow,
      showSubComponent,
    }
  }
};
</script>

vue3.2中没有了return,需要我们显示的获取要使用的stare的值

<template>
  <div class="todo-item">
    <ol>
      <li v-for="(item,index) in itemList" :key="index" class="todos" @click="clickItem(index)">
        {{ item.text }}
      </li>
    </ol>
  </div>
</template>
<script setup>
import { useStore } from &#39;vuex&#39;;
const store = useStore()
// 获取后在<template>中使用
const itemList = store.state.itemList
</script>

8. <span style="font-size: 18px;">c9ccee2e6ea535a969eb3f532ad9fe89</span>中的 v-bind

c9ccee2e6ea535a969eb3f532ad9fe89中的 v-bind: 用于在 SFC c9ccee2e6ea535a969eb3f532ad9fe89 标签中启用组件状态驱动的动态 CSS 值

<script setup>
import { ref, watchEffect } from &#39;vue&#39;;
const color = ref(&#39;black&#39;)
const callChangeColorHandel = () => {
  if(color.value === &#39;black&#39;) {
    color.value = &#39;red&#39;
  }else {
    color.value = &#39;black&#39;
  }
}
</script>
<style lang="scss" scoped>
.todo-list {
  color: v-bind(color);
}
</style>

触发callChangeColorHandel 函数,在c9ccee2e6ea535a969eb3f532ad9fe89中的v-bind指令可以动态绑定的响应式状态。

3. 概要

全体として、セットアップ構文シュガーの導入により、Composition API を使用する際の長いテンプレート コードが簡素化され、コードがより簡潔になります。可読性も高くなります。そして、正式な導入vue3.2は、インターフェイスのレンダリング速度とメモリ使用量の点で最適化されています。この記事では、構文糖衣のセットアップの一般的な方法のみを要約しています。詳細vue3.2新機能公式ドキュメントで確認できます。

(学習ビデオ共有: Web フロントエンド開発基本プログラミング ビデオ)

以上が糖衣構文とは何ですか? Vue3.2でシンタックスシュガーを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。