整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          這 10 個技巧,助你早日精通 Vue

          我比較喜歡使用 Vue 來開發,所以有時會深入研究其功能和特性。通過這篇文章,向你們介紹十個很酷的竅門和技巧,以幫助大家成為更好的 Vue 開發者。

          插槽語法更漂亮

          隨著Vue 2.6的推出,已經引入了插槽的簡寫方式,之前簡寫可用于事件(例如,@click表示v-on:click事件)或冒號表示方式用于綁定(:src)。例如,如果有一個表格組件,則可以按以下方式使用此功能:

          $on(‘hook:’)

          如果要在created或mounted方法中定義自定義事件偵聽器或第三方插件,并且需要在beforeDestroy方法中將其刪除以免引起任何內存泄漏,則可以使用此功能。使用$on(‘hook:’)方法,我們可以僅使用一種生命周期方法(而不是兩種)來定義/刪除事件。

          prop 驗證

          你可能已經知道可以將props驗證為原始類型,例如字符串,數字甚至對象。我們還可以使用自定義驗證器,例如,如果要針對字符串列表進行驗證:

          動態指令參數

          Vue 2.6 的最酷功能之一是可以將指令參數動態傳遞給組件。假設有一個按鈕組件,并且在某些情況下想監聽單擊事件,而在其他情況下想監聽雙擊事件。這就是動態指令派上用場的地方了:

          重用同一路由的組件

          有時,我們不同路由共用某些時,如果在這些路由之間切換,則默認情況下,共享組件將不會重新渲染,因為Vue 出于性能原因會重用該組件。但是,如果我們仍然希望重新渲染這些組件,則可以通過在路由器視圖組件中提供:key屬性來實現重新渲染。

          從父類到子類的所有 props

          這是一個非常酷的功能,可將所有prop從父組件傳遞到子組件。如果我們有另一個組件的包裝器組件,這將特別方便。因為,我們不必一個一個將prop傳遞給子組件,而是一次傳遞所有prop:

          上面的可以代替下面的做法

          從父類到子類的所有事件偵聽器

          如果子組件不在父組件的根目錄下,則可以將所有事件偵聽器從父組件傳遞到子組件,如下所示:

          如果子組件位于其父組件的根目錄下,則默認情況下它將獲得那些組件,因此不需要此小技巧。

          $createElement

          默認情況下,每個Vue實例都可以訪問$createElement方法來創建和返回虛擬節點。例如,可以利用它在可以通過v-html指令傳遞的方法中使用標記。在函數組件中,可以將此方法作為渲染函數中的第一個參數訪問。

          使用 JSX

          由于Vue CLI 3默認支持使用JSX,因此現在(如果愿意)我們可以使用JSX編寫代碼(例如,可以方便地編寫函數組件)。如果尚未使用Vue CLI 3,則可以使用babel-plugin-transform-vue-jsx獲得JSX支持。

          自定義 v-model

          默認情況下,v-model是@input事件監聽器和:value props上的語法糖。但是,我們可以在Vue組件中指定一個模型屬性,以定義使用什么事件和值

          總結

          希望這些竅門和技巧對你有所幫助,如果你也知道哪些技巧,歡迎留言。


          原文:https://www.telerik.com/blogs/12-tips-and-tricks-to-improve-your-vue-projects

          前端開發中,React 組件是我們日常開發的基礎,而使用 TypeScript 泛型能讓這些組件更加靈活和可重用。今天我們就來聊聊如何利用 TypeScript 泛型創建可重用的 React 組件。

          在深入具體操作之前,先簡單介紹一下泛型的概念。泛型允許你在定義組件時不指定具體的數據類型,而是在使用組件時再指定具體的類型。這樣一來,我們的組件就能夠適應多種數據類型,不必為每種數據類型分別創建不同的組件。

          市面上已經有很多關于 TypeScript 泛型的文章和教程,所以本文將聚焦于如何在 React 組件中使用泛型,讓你的組件變得更加靈活和可重用。

          接下來,我們將通過實例代碼一步步展示如何實現這一目標,讓你能夠輕松掌握這項技能,并應用到實際項目中去。無論你是剛入門的新手,還是有一定經驗的開發者,相信都能從中受益。準備好了嗎?讓我們開始吧!

          一、利用 TypeScript 泛型創建簡單的可重用 React 組件

          創建一個簡單的泛型 React 組件

          首先,我們來創建一個泛型 React 組件,它可以接受任何類型的數據并通過一個渲染函數將數據展示出來。

          // 定義一個泛型類型的 props
          type Props<T> = {
            data: T
            render: (data: T) => React.ReactNode
          }
          
          // 創建一個泛型 React 組件
          export function GenericComponent<T>({ data, render }: Props<T>) {
            return <div>{render(data)}</div>
          }

          在這個例子中,GenericComponent 接受一個 render 屬性,這個屬性是一個函數,它接收類型為 T 的數據并返回一個 React.ReactNode。這種模式通常被稱為“render props”,它可以讓你更靈活地控制數據的渲染方式。

          使用泛型組件渲染字符串

          接下來,我們用一個字符串類型的數據來使用這個泛型組件。

          import GenericComponent from './GenericComponent'
          
          function RenderString() {
            return (
              <GenericComponent<string> 
                data="Hello, world!" 
                render={(data) => <span>{data.toUpperCase()}</span>} 
              />
            )
          }

          在這個例子中,我們明確地告訴 GenericComponent 預期接收一個字符串類型的數據。渲染函數將字符串轉換為大寫,并且 TypeScript 確保了在 render 屬性中進行的操作是對字符串類型數據有效的。

          使用自定義類型的數據

          現在我們用一個自定義類型的數據來使用泛型組件。

          type Person = {
            name: string
            age: number
          }
          
          import GenericComponent from './GenericComponent'
          
          function RenderPerson() {
            return (
              <GenericComponent<Person>
                data={{ name: 'Alice', age: 30 }}
                render={(data) => (
                  <span>
                    {data.name} is {data.age} years old
                  </span>
                )}
              />
            )
          }

          在這個例子中,TypeScript 確保 data 屬性的數據類型與 render 函數中預期的類型匹配。

          使用泛型組件渲染任務列表

          最后,我們來看看如何用泛型組件渲染一個任務列表。

          import { useState } from 'react'
          import GenericComponent from './GenericComponent'
          
          interface TodoItem {
            id: number
            title: string
            completed: boolean
          }
          
          export function TodoList() {
            // 初始任務列表
            const initialTodos: TodoItem[] = [
              { id: 1, title: 'Learn React', completed: false },
              { id: 2, title: 'Write blog post', completed: true },
              { id: 3, title: 'Study TypeScript', completed: false },
            ]
          
            // 用于追蹤任務列表的狀態
            const [todos, setTodos] = useState<TodoItem[]>(initialTodos)
          
            // 切換任務完成狀態的函數
            function toggleTodoCompletion(id: number) {
              const updatedTodos = todos.map((todo) => 
                (todo.id === id ? { ...todo, completed: !todo.completed } : todo))
              setTodos(updatedTodos)
            }
          
            // 任務列表的復雜渲染函數
            function renderTodos(todos: TodoItem[]) {
              return (
                <ul>
                  {todos.map((todo) => (
                    <li
                      key={todo.id}
                      style={{ textDecoration: todo.completed ? 'line-through' : 'none', cursor: 'pointer' }}
                      onClick={() => toggleTodoCompletion(todo.id)}
                    >
                      {todo.title}
                    </li>
                  ))}
                </ul>
              )
            }
          
            return <GenericComponent<TodoItem[]>  
              data={todos} 
              render={renderTodos} 
            />
          }

          在這個例子中,我們創建了一個 TodoList 組件,它使用 GenericComponent 渲染一個任務列表。渲染函數更加復雜,因為它需要處理一個項目列表。TypeScript 確保 data 屬性的數據類型與 render 函數中預期的類型匹配。

          二、使用泛型在 React 組件中展示數據

          在實際開發中,很多時候我們需要從 API 獲取數據并展示在頁面上。利用 TypeScript 泛型,我們可以創建一個通用的 React 組件來處理這種情況。這樣不僅能提高代碼的可重用性,還能使組件更加靈活。今天我們就通過一個例子來展示如何實現這一目標。

          創建一個用于獲取數據的泛型 React 組件

          首先,我們創建一個泛型組件 FetchAndDisplay,它可以從指定的 URL 獲取數據,并通過一個渲染函數將數據展示出來。

          import { useEffect, useState } from 'react'
          
          // 定義一個泛型類型的 props
          type Props<T> = {
            url: string
            render: (data: T) => React.ReactNode
          }
          
          // 創建一個泛型 React 組件
          export function FetchAndDisplay<T>({ url, render }: Props<T>) {
            const [data, setData] = useState<T | null>(null)
            const [loading, setLoading] = useState(true)
            const [error, setError] = useState<Error | null>(null)
          
            useEffect(() => {
              const fetchData = async () => {
                try {
                  const response = await fetch(url)
                  if (!response.ok) {
                    throw new Error('Failed to fetch data')
                  }
                  const json = await response.json()
                  setData(json)
                } catch (error) {
                  setError(error)
                } finally {
                  setLoading(false)
                }
              }
              fetchData()
            }, [url])
          
            if (loading) {
              return <div>Loading...</div>
            }
          
            if (error) {
              return <div>Error: {error.message}</div>
            }
          
            if (data) {
              return <div>{render(data)}</div>
            }
          
            return null
          }

          在這個例子中,FetchAndDisplay 是一個泛型組件,它接受一個 URL 和一個渲染函數。組件使用 fetch 方法從指定的 URL 抓取數據,并在抓取成功后調用渲染函數來展示數據。同時,組件還處理了加載和錯誤狀態。

          使用 FetchAndDisplay 組件獲取和展示帖子

          接下來,我們使用 FetchAndDisplay 組件來取取并展示一組帖子數據。

          import { FetchAndDisplay } from './FetchAndDisplay'
          
          type Post = {
            userId: number
            id: number
            title: string
            body: string
          }
          
          function RenderPosts(posts: Post[]) {
            return (
              <ul>
                {posts.map((post) => (
                  <li key={post.id}>
                    <h3>{post.title}</h3>
                    <p>{post.body}</p>
                  </li>
                ))}
              </ul>
            )
          }
          
          export function PostList() {
            return <FetchAndDisplay<Post[]> 
              url='https://jsonplaceholder.typicode.com/posts'  
              render={RenderPosts} 
            />
          }

          在這個例子中,我們使用 FetchAndDisplay 組件從 JSONPlaceholder API 獲取一組帖子數據,并通過 RenderPosts 函數將其展示出來。

          使用 FetchAndDisplay 組件獲取和展示用戶

          同樣地,我們可以使用同一個 FetchAndDisplay 組件來抓取和展示用戶數據。

          import { FetchAndDisplay } from './FetchAndDisplay'
          
          type User = {
            id: number
            name: string
            email: string
          }
          
          function RenderUsers(users: User[]) {
            return (
              <ul>
                {users.map((user) => (
                  <li key={user.id}>
                    <h3>{user.name}</h3>
                    <p>{user.email}</p>
                  </li>
                ))}
              </ul>
            )
          }
          
          export function UserList() {
            return <FetchAndDisplay<User[]> 
              url='https://jsonplaceholder.typicode.com/users' 
              render={RenderUsers} 
            />
          }

          在這個例子中,我們使用 FetchAndDisplay 組件從 JSONPlaceholder API 獲取一組用戶數據,并通過 RenderUsers 函數將其展示出來。這展示了泛型在 React 組件中的強大作用,我們可以用同一個組件處理不同類型的數據獲取和展示。

          三、使用泛型創建通用的 React 表單組件

          在實際開發中,表單是我們常用的組件之一。為了提升代碼的復用性和靈活性,我們可以使用 TypeScript 泛型創建一個通用的表單組件。盡管在實際項目中我們通常會使用像 Formik 或 react-hook-form 這樣的庫來處理表單,但為了演示泛型的強大之處,我們將從頭開始創建一個簡單的表單組件。

          定義表單字段和組件的類型

          首先,我們定義一些 TypeScript 類型,用來指定表單字段的結構以及我們的通用表單組件將接受的 props。這些類型確保了類型安全,并幫助我們管理表單的狀態和行為。

          type FormField = {
            name: string
            label: string
            type: 'text' | 'email' | 'password' // 可以根據需要擴展
          }
          
          type GenericFormProps<T> = {
            fields: FormField[]
            initialValues: T
            onSubmit: (values: T) => void
          }

          創建通用表單組件

          接下來,我們創建一個函數組件,它接受字段、初始值和一個提交處理函數作為參數。

          import { useState } from 'react'
          
          export function GenericForm<T>({ fields, initialValues, onSubmit }: GenericFormProps<T>) {
            const [values, setValues] = useState<T>(initialValues)
          
            function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
              const { name, value } = e.target
              setValues((prevValues) => ({ ...prevValues, [name]: value }))
            }
          
            function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
              e.preventDefault()
              onSubmit(values)
            }
          
            return (
              <form onSubmit={handleSubmit}>
                {fields.map((field) => (
                  <div key={field.name}>
                    <label htmlFor={field.name}>{field.label}</label>
                    <input type={field.type} name={field.name} 
                           value={(values as any)[field.name]} 
                           onChange={handleChange} />
                  </div>
                ))}
                <button type='submit'>Submit</button>
              </form>
            )
          }

          使用通用表單組件

          最后,我們使用通用表單組件,并指定具體的表單字段和初始值。

          type UserFormValues = {
            name: string
            email: string
            password: string
          }
          
          const userFormFields: FormField[] = [
            { name: 'name', label: 'Name', type: 'text' },
            { name: 'email', label: 'Email', type: 'email' },
            { name: 'password', label: 'Password', type: 'password' },
          ]
          
          const initialValues: UserFormValues = {
            name: '',
            email: '',
            password: '',
          }
          
          function App() {
            const handleSubmit = (values: UserFormValues) => {
              console.log('Form Submitted', values)
            }
          
            return (
              <div>
                <h1>User Registration</h1>
                <GenericForm 
                  fields={userFormFields} 
                  initialValues={initialValues} 
                  onSubmit={handleSubmit} 
                />
              </div>
            )
          }

          在這個例子中,如果不使用泛型,你需要為每種類型的表單分別創建一個表單組件。使用泛型后,你可以創建一個通用的表單組件,可以用于任何類型的表單字段。這展示了泛型在 React 組件中的強大作用,使得我們的組件更加靈活和可復用。

          附加示例:使用泛型創建通用的表格組件

          在開發中,表格組件是一個常見的需求。為了使表格組件更加靈活和可重用,我們可以使用 TypeScript 泛型來創建一個通用的表格組件。通過這種方式,我們可以確保數據類型的一致性,并能夠輕松地渲染不同類型的數據。

          創建通用表格組件

          首先,我們定義一個通用表格組件 Table,它接受一組行數據和一個用于渲染行的函數。

          import React from 'react'
          
          const Table = <TRow extends Record<string, any>>(props: {
            rows: TRow[];
            renderRow: React.FC<TRow>;
          }) => {
            return (
              <table>
                <tbody>
                  {props.rows.map((row, index) => (
                    <props.renderRow key={index} {...row} />
                  ))}
                </tbody>
              </table>
            )
          }

          在這個例子中,Table 組件接受一個泛型參數 TRow,它表示表格中每一行的數據類型。組件接收一個 rows 數組和一個 renderRow 函數。renderRow 函數負責渲染每一行的數據。

          使用通用表格組件

          接下來,我們使用 Table 組件來渲染一個包含姓名和年齡的表格。

          import React from 'react'
          import { Table } from './Table'
          
          type Person = {
            name: string
            age: number
          }
          
          const people: Person[] = [
            { name: 'Alice', age: 30 },
            { name: 'Bob', age: 40 },
          ]
          
          const RenderPersonRow: React.FC<Person> = ({ name, age }) => (
            <tr>
              <td>{name}</td>
              <td>{age}</td>
            </tr>
          )
          
          const App = () => {
            return (
              <div>
                <h1>People Table</h1>
                <Table rows={people} renderRow={RenderPersonRow} />
              </div>
            )
          }
          
          export default App

          在這個例子中,我們定義了一個 Person 類型,它包含 name 和 age 兩個屬性。然后我們創建了一個 people 數組,包含兩個人的姓名和年齡。RenderPersonRow 是一個用于渲染每行數據的組件,它接受 Person 類型的屬性并返回一個表格行。

          我們在 App 組件中使用 Table 組件,將 people 數組作為 rows 傳遞,并將 RenderPersonRow 作為 renderRow 函數傳遞給 Table 組件。這樣,表格組件就會渲染包含兩行數據的表格,每行數據對應一個人的姓名和年齡。

          結束

          TypeScript 的泛型是一項強大的功能,能夠使你的 React 組件更加靈活和可重用。通過使用泛型,你可以創建適用于任何數據類型的組件,這在處理各種數據類型的實際應用中尤為有用。

          如何避免el-form中el-input輸入框回車鍵導致頁面刷新的痛點問題

          ## 引言:問題起源與影響

          在使用Element UI進行Web前端開發時,我們經常遇到一個常見的痛點問題:在`el-form`組件中的`el-input`輸入框內按回車鍵時,頁面會意外地刷新,這并非預期行為,尤其是在表單填寫場景下,用戶希望的是提交表單而非刷新整個頁面。本文將深入探討這個問題,并給出詳盡的解決方案。

          ### 段落一:問題現象剖析

          問題重現

          html
          <el-form>
            <el-form-item label="用戶名">
              <el-input v-model="username"></el-input>
            </el-form-item>
            <!-- 其他表單元素... -->
          </el-form>
          

          在上述代碼中,當我們在`el-input`中輸入內容并按下回車鍵時,頁面會發生刷新,這主要是因為瀏覽器默認對`<form>`標簽或可輸入元素(如`<input>`)的回車鍵事件處理為提交表單,而提交操作通常會導致頁面刷新。

          ### 段落二:解決思路與方法

          阻止默認行為

          要解決此問題,我們可以采用兩種主要策略:

          1.

          阻止回車鍵默認提交行為

          javascript
          export default {
            methods: {
              preventFormSubmit(e) {
                if (e.keyCode === 13) { // keyCode 13代表回車鍵
                  e.preventDefault(); // 阻止默認提交動作
                  // 這里可以添加自定義的回車鍵觸發邏輯,例如提交表單
                }
              }
            },
            mounted() {
              document.addEventListener('keydown', this.preventFormSubmit);
            },
            beforeDestroy() {
              document.removeEventListener('keydown', this.preventFormSubmit);
            }
          }
          

          2.

          局部處理el-input回車事件

          html
          <el-form @submit.prevent>
            <el-form-item label="用戶名">
              <el-input v-model="username" @keyup.enter.native.prevent></el-input>
            </el-form-item>
            <!-- 其他表單元素... -->
          </el-form>
          

          在上述代碼中,`.native`修飾符用于監聽原生DOM事件,`@keyup.enter.prevent`表示監聽輸入框的回車鍵按下事件并阻止其默認行為。

          自定義回車鍵功能

          javascript
          // 在main.js或者其他全局引入的文件中
          Vue.directive('prevent-form-submit', {
            inserted(el, binding, vnode) {
              el.addEventListener('keydown', (e) => {
                if (e.target.tagName === 'INPUT' && e.keyCode === 13) {
                  e.preventDefault();
                  const form = vnode.context.$refs[binding.value];
                  if (form && typeof form.validate === 'function') {
                    form.validate((valid) => {
                      if (valid) {
                        // 觸發表單提交邏輯
                        form.submit();
                      }
                    });
                  }
                }
              });
            }
          });
          
          // 在模板中應用全局指令
          <el-form ref="myForm" @submit.prevent v-prevent-form-submit="'myForm'">
            <!-- 表單元素... -->
          </el-form>
          

          總結起來,解決`el-form`中`el-input`回車鍵導致頁面刷新的問題,關鍵在于理解和利用Vue事件系統以及原生DOM事件的處理機制,通過適當的事件監聽和阻止默認行為,我們可以輕松定制回車鍵的行為,提升用戶體驗,同時避免了不必要的頁面刷新。希望本篇文章能幫助開發者更好地掌握這一技巧,并應用于實際項目中。


          主站蜘蛛池模板: 国产精品va一区二区三区| 国产怡春院无码一区二区| 亚洲综合无码一区二区三区 | 一本一道波多野结衣一区| 日韩精品一区二区午夜成人版 | 无码少妇丰满熟妇一区二区| 国产在线无码视频一区二区三区| 综合一区自拍亚洲综合图区| 中文字幕视频一区| 一区二区三区四区免费视频| 狠狠综合久久AV一区二区三区 | 成人国内精品久久久久一区| 日本精品一区二区三区视频| 亚洲综合一区国产精品| 中文字幕乱码亚洲精品一区| 91一区二区三区四区五区| 国产爆乳无码一区二区麻豆| 狠狠色婷婷久久一区二区| 在线精品亚洲一区二区小说| 伦理一区二区三区| 免费无码一区二区三区蜜桃| 中文字幕一区二区三区四区| 精品国产一区二区三区久久蜜臀| 国产成人片视频一区二区| 亚洲国产精品第一区二区三区| 日本一区二区三区免费高清在线| 视频一区二区三区在线观看| 免费国产在线精品一区| 精品国产一区二区三区久久蜜臀 | 精品一区二区三区高清免费观看| 日本精品一区二区久久久| 久久无码一区二区三区少妇| 中文字幕精品一区二区精品| 国产品无码一区二区三区在线蜜桃 | 精品无码国产一区二区三区麻豆| 在线精品自拍亚洲第一区| 综合激情区视频一区视频二区| 亚洲AV成人精品日韩一区18p| 免费一区二区无码东京热| 麻豆aⅴ精品无码一区二区| 中文字幕av人妻少妇一区二区|