<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # vue3 · api ## 文件結構 ``` <template> // ... </template> <script setup> // ... </script> <style lang="scss" scoped> // 支持CSS變量注入v-bind(color) </style> ``` ## 數據 ``` <script setup> import { reactive, ref, toRefs } from 'vue' // ref聲明響應式數據,用于聲明基本數據類型 const name = ref('Jerry') // 修改 name.value = 'Tom' // reactive聲明響應式數據,用于聲明引用數據類型 const state = reactive({ name: 'Jerry', sex: '男' }) // 修改 state.name = 'Tom' // 使用toRefs解構 const {name, sex} = toRefs(state) // template可直接使用{{name}}、{{sex}} </script> ``` ## 方法 ``` <template> // 調用方法 <button @click='changeName'>按鈕</button> </template> <script setup> import { reactive } from 'vue' const state = reactive({ name: 'Jery' }) // 聲明method方法 const changeName = () => { state.name = 'Tom' } </script> ``` ## 計算屬性 ``` <script setup> import { computed, ref } from 'vue' const count = ref(1) // 通過computed獲得doubleCount const doubleCount = computed(() => { return count.value * 2 }) // 獲取 console.log(doubleCount.value) </script> ``` ## watch 監聽 ``` <script setup> import { watch, reactive } from 'vue' const state = reactive({ count: 1 }) // 聲明方法 const changeCount = () => { state.count = state.count * 2 } // 監聽count watch( () => state.count, (newVal, oldVal) => { console.log(state.count) console.log(`watch監聽變化前的數據:${oldVal}`) console.log(`watch監聽變化后的數據:${newVal}`) }, { immediate: true, // 立即執行 deep: true // 深度監聽 } ) </script> ``` ## props父傳子 ### 子組件 ``` <template> <span>{{props.name}}</span> // 可省略【props.】 <span>{{name}}</span> </template> <script setup> // import { defineProps } from 'vue' // defineProps在<script setup>中自動可用,無需導入 // 需在.eslintrc.js文件中【globals】下配置【defineProps: true】 // 聲明props const props = defineProps({ name: { type: String, default: '' } }) </script> ``` ### 父組件 ``` <template> <child name='Jerry'/> </template> <script setup> // 引入子組件 import child from './child.vue' </script> ``` ## emit子傳父 ### 子組件 ``` <template> <span>{{props.name}}</span> // 可省略【props.】 <span>{{name}}</span> <button @click='changeName'>更名</button> </template> <script setup> // import { defineEmits, defineProps } from 'vue' // defineEmits和defineProps在<script setup>中自動可用,無需導入 // 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】 // 聲明props const props = defineProps({ name: { type: String, default: '' } }) // 聲明事件 const emit = defineEmits(['updateName']) const changeName = () => { // 執行 emit('updateName', 'Tom') } </script> ``` ### 父組件 ``` <template> <child :name='state.name' @updateName='updateName'/> </template> <script setup> import { reactive } from 'vue' // 引入子組件 import child from './child.vue' const state = reactive({ name: 'Jerry' }) // 接收子組件觸發的方法 const updateName = (name) => { state.name = name } </script> ``` ## v-model 支持綁定多個`v-model`,`v-model`是`v-model:modelValue`的簡寫 綁定其他字段,如:`v-model:name` ### 子組件 ``` <template> <span @click="changeInfo">我叫{{ modelValue }},今年{{ age }}歲</span> </template> <script setup> // import { defineEmits, defineProps } from 'vue' // defineEmits和defineProps在<script setup>中自動可用,無需導入 // 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】 defineProps({ modelValue: String, age: Number }) const emit = defineEmits(['update:modelValue', 'update:age']) const changeInfo = () => { // 觸發父組件值更新 emit('update:modelValue', 'Tom') emit('update:age', 30) } </script> ``` ### 父組件 ``` <template> // v-model:modelValue簡寫為v-model // 可綁定多個v-model <child v-model="state.name" v-model:age="state.age" /> </template> <script setup> import { reactive } from 'vue' // 引入子組件 import child from './child.vue' const state = reactive({ name: 'Jerry', age: 20 }) </script> ``` ## nextTick ``` <script setup> import { nextTick } from 'vue' nextTick(() => { // ... }) </script> ``` ## ref子組件實例和defineExpose * 在標準組件寫法里,子組件的數據都是默認隱式暴露給父組件的,但在 script-setup 模式下,所有數據只是默認 return 給 template 使用,不會暴露到組件外,所以父組件是無法直接通過掛載 ref 變量獲取子組件的數據。 * 如果要調用子組件的數據,需要先在子組件顯示的暴露出來,才能夠正確的拿到,這個操作,就是由 defineExpose 來完成。 ### 子組件 ``` <template> <span>{{state.name}}</span> </template> <script setup> import { reactive, toRefs } from 'vue' // defineExpose無需引入 // import { defineExpose, reactive, toRefs } from 'vue' // 聲明state const state = reactive({ name: 'Jerry' }) // 將方法、變量暴露給父組件使用,父組件才可通過ref API拿到子組件暴露的數據 defineExpose({ // 解構state ...toRefs(state), // 聲明方法 changeName () { state.name = 'Tom' } }) </script> ``` ### 父組件 #### 1. 獲取一個子組件實例 ``` <template> <child ref='childRef'/> </template> <script setup> import { ref, nextTick } from 'vue' // 引入子組件 import child from './child.vue' // 子組件ref(TypeScript語法) const childRef = ref<InstanceType<typeof child>>() // nextTick nextTick(() => { // 獲取子組件name console.log(childRef.value.name) // 執行子組件方法 childRef.value.changeName() }) </script> ``` #### 2. 獲取多個子組件實例:在 v-for 中獲取子組件實例 這種情況僅適用于 v-for`循環數是固定的情況`,因為如果 v-for`循環數`在初始化之后發生改變,那么就會導致 childRefs 再一次重復添加,childRefs 中會出現重復的子組件實例 ``` <template> <div v-for="item in 3" :key="item"> <child :ref='addChildRef'/> </div> </template> <script setup> // 省略... // 子組件實例數組 const childRefs = ref([]) // 通過 addChildRef 方法向 childRefs 添加子組件實例 const addChildRef = (el) => { childRefs.value.push(el) } </script> ``` #### 3. 獲取多個子組件實例:動態 v-for 獲取子組件實例 通過下標來向 childRefs 添加/修改,初始化之后,動態修改 v-for 循環數,會自動根據下標重新修改該下標對應的數據 ``` <template> <button @click='childNums++'></button> <div v-for="(item, i) in childNums" :key="item"> // 通過下標向 childRefs 動態添加子組件實例 <child :ref='(el) => childRefs[i] = el'/> </div> <button @click='childNums--'></button> </template> <script setup> // 省略... // 子組件數量 const childNums = ref(1) // 子組件實例數組 const childRefs = ref([]) </script> ``` ## 插槽slot ### 子組件 ``` <template> // 匿名插槽 <slot/> // 具名插槽 <slot name='title'/> // 作用域插槽 <slot name="footer" :scope="state" /> </template> <script setup> import { useSlots, reactive } from 'vue' const state = reactive({ name: '張三', age: '25歲' }) const slots = useSlots() // 匿名插槽使用情況 const defaultSlot = reactive(slots.default && slots.default().length) console.log(defaultSlot) // 1 // 具名插槽使用情況 const titleSlot = reactive(slots.title && slots.title().length) console.log(titleSlot) // 3 </script> ``` ### 父組件 ``` <template> <child> // 匿名插槽 <span>我是默認插槽</span> // 具名插槽 <template #title> <h1>我是具名插槽</h1> <h1>我是具名插槽</h1> <h1>我是具名插槽</h1> </template> // 作用域插槽 <template #footer="{ scope }"> <footer>作用域插槽——姓名:{{ scope.name }},年齡{{ scope.age }}</footer> </template> </child> </template> <script setup> // 引入子組件 import child from './child.vue' </script> ``` ## 路由useRoute和useRouter ``` <script setup> import { useRoute, useRouter } from 'vue-router' // 必須先聲明調用 const route = useRoute() const router = useRouter() // 路由信息 console.log(route.query) // 路由跳轉 router.push('/newPage') </script> ``` ## 路由導航守衛 ``` <script setup> import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' // 添加一個導航守衛,在當前組件將要離開時觸發。 onBeforeRouteLeave((to, from, next) => { next() }) // 添加一個導航守衛,在當前組件更新時觸發。 // 在當前路由改變,但是該組件被復用時調用。 onBeforeRouteUpdate((to, from, next) => { next() }) </script> ``` ## store ### Vuex ``` <script setup> import { useStore } from 'vuex' import { key } from '../store/index' // 必須先聲明調用 const store = useStore(key) // 獲取Vuex的state store.state.xxx // 觸發actions的方法 store.commit('fnName') // 觸發actions的方法 store.dispatch('fnName') // 獲取Getters store.getters.xxx </script> ``` ### Pinia * 同時支持 Composition Api 和 Options api 的語法; * 去掉 mutations ,只有 state 、getters 和 actions ; * 不支持嵌套的模塊,通過組合 store 來代替; * 更完善的 Typescript 支持; * 清晰、顯式的代碼拆分; #### 安裝 ``` # 使用 npm npm install pinia # 使用 yarn yarn add pinia ``` #### main.js 引入 ``` import App from './App.vue' import { createApp } from 'vue' import { createPinia } from 'pinia' const app = createApp(App) app.use(createPinia()) app.mount('#app') ``` #### 配置 store.js ``` import { defineStore } from 'pinia' // defineStore 調用后返回一個函數,調用該函數獲得 Store 實體 export const useStore = defineStore({ // id: 必須,在所有 Store 中唯一 id: 'globalState', // state: 返回對象的函數 state: () => ({ count: 1, data: { name: 'Jerry', sex: '男' } }), // getter 第一個參數是 state,是當前的狀態,也可以使用 this 獲取狀態 // getter 中也可以訪問其他的 getter,或者是其他的 Store getters: { // 通過 state 獲取狀態 doubleCount: (state) => state.count * 2, // 通過 this 獲取狀態(注意this指向) tripleCount() { return this.count * 3 } }, actions: { updateData (newData, count) { // 使用 this 直接修改 this.data = { ...newData } this.count = count // 使用 $patch 修改多個值 this.$patch({ data: { ...newData }, count }) } } }) ``` #### 使用 store ``` <template> // 獲取 store 的 state <p>姓名:{{store.data.name}}</p> <p>性別:{{store.data.sex}}</p> // 調用 actions 方法 / 修改 store <button @click='update'>修改用戶信息</button> // 獲取 getter <p>獲取getter:{{store.doubleCount}}</p> </template> <script setup> import { useStore } from '@store/store.js' const store = useStore() function update () { // 通過 actions 定義的方法修改 state store.updateData({ name: 'Tom', sex: '女' }) // 通過 store 直接修改 store.data = { name: 'Tom', sex: '女' } // 同時改變多個狀態 store.$patch((state) => { state.data = { name: 'Tom', sex: '女' } state.count = 2 }) } </script> <style lang="scss" scoped> </style> ``` #### 其他方法 **替換整個 state** `$state`可以讓你通過將`store`的屬性設置為新對象來替換`store`的整個`state` ``` const store = useStore() store.$state = { name: 'Bob', sex: '男' } ``` **重置狀態** 調用`store`上的`$reset()`方法將狀態重置為初始值 ``` const store = useStore() store.$reset() ``` ## 生命周期 通過在生命周期鉤子前面加上 “on” 來訪問組件的生命周期鉤子。 下表包含如何在 Option API 和 setup() 內部調用生命周期鉤子 <table><thead><tr><th><strong>Option API</strong></th><th><strong>setup中</strong></th></tr></thead><tbody><tr><td>beforeCreate</td><td>不需要</td></tr><tr><td>created</td><td>不需要</td></tr><tr><td>beforeMount</td><td>onBeforeMount</td></tr><tr><td>mounted</td><td>onMounted</td></tr><tr><td>beforeUpdate</td><td>onBeforeUpdate</td></tr><tr><td>updated</td><td>onUpdated</td></tr><tr><td>beforeUnmount</td><td>onBeforeUnmount</td></tr><tr><td>unmounted</td><td>onUnmounted</td></tr><tr><td>errorCaptured</td><td>onErrorCaptured</td></tr><tr><td>renderTracked</td><td>onRenderTracked</td></tr><tr><td>renderTriggered</td><td>onRenderTriggered</td></tr><tr><td>activated</td><td>onActivated</td></tr><tr><td>deactivated</td><td>onDeactivated</td></tr></tbody></table> ## 原型綁定與組件內使用 ### main.js ``` import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) // 獲取原型 const prototype = app.config.globalProperties // 綁定參數 prototype.name = 'Jerry' ``` ### 組件內使用 ~~~javascript <script setup> import { getCurrentInstance } from 'vue' // 獲取原型 const { proxy } = getCurrentInstance() // 輸出 console.log(proxy.name) </script> ~~~ ## v-bind() CSS變量注入 ~~~javascript <template> <span>Jerry</span> </template> <script setup> import { ref, reactive } from 'vue' // prop接收樣式 const props = defineProps({ border: { type: String, default: '1px solid yellow' } }) // 常量聲明樣式 const background = 'red' // 響應式數據聲明樣式 const color = ref('blue') const style = reactive({ opacity: '0.8' }) </script> <style lang="scss" scoped> span { // 使用常量聲明的樣式 background: v-bind(background); // 使用響應式數據聲明的樣式 color: v-bind(color); opacity: v-bind('style.opacity'); // 使用prop接收的樣式 border: v-bind('props.border'); } </style> ~~~ ## provide和inject ### 父組件 ~~~javascript <template> <child/> </template> <script setup> import { ref, watch, provide } from 'vue' // 引入子組件 import child from './child.vue' let name = ref('Jerry') // 聲明provide provide('provideState', { name, changeName: () => { name.value = 'Tom' } }) // 監聽name改變 watch(name, () => { console.log(`name變成了${name}`) setTimeout(() => { console.log(name.value) // Tom }, 1000) }) </script> ~~~ ### 子組件 ~~~javascript <script setup> import { inject } from 'vue' // 注入,第二個參數為默認值 const provideState = inject('provideState', {}) // 子組件觸發name改變 provideState.changeName() </script> ~~~ ## 自定義指令 Vue3相較于Vue2的自定義聲明方法有些不同 ~~~javascript const app = createApp({}) // 使 v-demo 在所有組件中都可用 app.directive('demo', { // 在綁定元素的 attribute 前或事件監聽器應用前調用 created(el, binding, vnode, prevVnode) {}, // 在元素被插入到 DOM 前調用 beforeMount(el, binding, vnode, prevVnode) {}, // 在綁定元素的父組件 // 及他自己的所有子節點都掛載完成后調用 mounted(el, binding, vnode, prevVnode) {}, // 綁定元素的父組件更新前調用 beforeUpdate(el, binding, vnode, prevVnode) {}, // 在綁定元素的父組件 // 及他自己的所有子節點都更新后調用 updated(el, binding, vnode, prevVnode) {}, // 綁定元素的父組件卸載前調用 beforeUnmount(el, binding, vnode, prevVnode) {}, // 綁定元素的父組件卸載后調用 unmounted(el, binding, vnode, prevVnode) {} }) ~~~ 比如實現一個默認密文身份證號,點擊才展示的指令 ~~~javascript app.directive('ciphertext', { created: (el: any) => { console.log(el, 1111) el.style.cursor = 'pointer' const value = el.innerText if (!value || value === 'null' || value === '--') { el.innerText = '--' } else { el.setAttribute('title', '點擊查看') el.innerText = hideText(value) el.addEventListener('click', () => { if (el.innerText.indexOf('*') > -1) { el.innerText = value } else { el.innerText = hideText(value) } }) } } }) <span v-ciphertext>{{idNumber}}</span> ~~~ ## 對 await 的支持 不必再配合 async 就可以直接使用 await 了,這種情況下,組件的 setup 會自動變成 async setup 。 ~~~javascript <script setup> const post = await fetch('/api').then(() => {}) </script> ~~~ ## 定義組件的name 用單獨的`<script>`塊來定義 ~~~javascript <script> export default { name: 'ComponentName', } </script> ~~~ 更優雅的方式,安裝插件:`vite-plugin-vue-setup-extend`,就可以按以下方式定義name了 #### 配置?`vite.config.ts` ~~~javascript import { defineConfig } from 'vite' import VueSetupExtend from 'vite-plugin-vue-setup-extend' export default defineConfig({ plugins: [VueSetupExtend()] }) ~~~ #### 使用 ~~~javascript <script setup name="ComponentName"> // todo </script> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看