vue 단일 파일 구성 요소 의 실현

12830 단어 vue단일 파일
최근 에 vue 를 뒤 적 였 다.단일 파일 구성 요소 가 발견 되 기 전에 거의 무시 되 었 습 니 다.vue.js 의 단일 파일 구성 요 소 는 한 파일 에서 구성 요소 의 모든 내용 을 정의 할 수 있 습 니 다.즉,하나의 페이지 나 하나의 구성 요소 입 니 다.우 리 는 그들 을 한데 묶 고 싶 습 니 다.그러면 vue 의 이 단일 파일 구성 요 소 는 할 수 있 습 니 다.vue 홈 페이지 에서 말 한 것 처럼"많은 Vue 프로젝트 에서 저 희 는 app.coponent 를 사용 하여 전체 구성 요 소 를 정의 합 니 다.이 어 app.mount('\#app')로 각 페이지 에 용기 요 소 를 지정 합 니 다."이곳 의 구성 요 소 는 모두 상대 적 으로 간단 하지만 비교적 복잡 한 프로젝트 에 직면 하면 이런 방식 은 통 하지 않 는 다.이 유 는 다음 과 같다.
  • 전역 정의(Global definitions)는 모든 component 의 이름 을 중복 하지 않도록 강제 합 니 다.
  • 문자열 템 플 릿(String templates)은 문법 적 하 이 라이트 가 부족 합 니 다.HTML 이 여러 줄 일 때 추 한\를 사용 해 야 합 니 다.
  • CSS(No CSS support)를 지원 하지 않 는 다 는 것 은 HTML 과 JavaScript 가 구성 요소 화 되 었 을 때 CSS 가 뚜렷하게 누락 되 었 음 을 의미 합 니 다.
  • 빌 드 절차(No build step)제한 없 이 HTML 과 ES5 JavaScript 만 사용 할 수 있 으 며,예 를 들 어 Pug
  • 와 같은 예비 프로 세 서 를 사용 할 수 없습니다.
  • (예전 의 Jade)와 바벨.
  • 이 모든 것 은'vue'라 는 확장자 의 single-file components(단일 파일 구성 요소)를 통 해 해결 할 수 있 으 며,웹 팩 이나 Browserify 등 구축 도 구 를 사용 할 수 있 습 니 다.
    그렇다면 vue 프로젝트 의 단일 파일 구성 요 소 는 어떻게 만들어 야 합 니까?
    세우다
    
    npm install -D @vue/compiler-sfc
    콘 솔 에 위 코드 를 입력 하면 폴 더 와 다른 json 파일 이 나타 납 니 다.다음 과 같다.
    在这里插入图片描述
    우 리 는 단일 파일 구성 요 소 를 구축 하려 면 스스로 파일 을 만들어 야 한다.웹 팩 에 대해 서도 어느 정도 알 아야 합 니 다.
    예 를 들 어,우 리 는 스스로 필요 한 의존 도 를 설치 했다.예 를 들 어 css-loader,css 의 사전 컴 파일 프로세서 등 이다.프로젝트 가 vue 파일 을 분석 해 야 하기 때문에 vue-loader 는 필수 입 니 다.
    이 파일 들 은 사실 모두 vue 의 간단 한 버 전이 다.예 를 들 어 간단 한 hello.vue 파일 은 다음 과 같 을 수 있 습 니 다.
    在这里插入图片描述
    이 를 통 해 알 수 있 듯 이 세 부분 으로 구성 된다.한편,template 이 부분 은 없어 서 는 안 될 부분 입 니 다.다른 두 부분 은 style 과 script 은 무시 할 수 있 습 니 다.
    script 은 페이지 js 를 vue 와 완벽 하 게 결합 시 킬 수 있 고 style 은 예비 프로세서 로 간결 하고 기능 이 풍부 한 구성 요 소 를 구축 할 수 있 습 니 다.(이 단일 파일 구성 요 소 는 초기 전단 에서 개발 한 html 문서 와 같 습 니 다.스타일 태그 와 script 태그 가 있 습 니 다.표현 층 만 template 태 그 를 사용 합 니 다.간단 한 방식 을 사 용 했 기 때문에 강력 한 레이 어 링 구성 요소(내용/템 플 릿:,표현:
    在这里插入图片描述
    일부 동료 들 은 서로 다른 모듈 을 분리 하 는 것 을 좋아 할 수 있 습 니 다.즉,vue 문서 가 말 하 는 관심 사 를 분리 하 는 것 입 니 다.그러면 괜 찮 습 니 다.그 문 서 를 뜯 어서 css 와 js 를 다른 파일 로 뜯 어서 구성 요소 에 도입 할 수 있 습 니 다.다음 과 같다.
    
    <!-- my-component.vue -->
    <template>
      <div>This will be pre-compiled</div>
    </template>
    <script src="./my-component.js"></script>
    <style src="./my-component.css"></style>
    
    항목 의 대략적인 목록 은 다음 과 같다.
    在这里插入图片描述
    그 중 index.html
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>Vue Simple Todo App with SFC</title>
        <link
          rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" rel="external nofollow"  rel="external nofollow" 
        />
        <link rel="stylesheet" href="/dist/main.css" rel="external nofollow"  rel="external nofollow"  />
      </head>
      <body>
        <div id="app"></div>
        <script src="/dist/main.js"></script>
      </body>
    </html>
    
    package.json
    
    {
        "private": true,
        "scripts": {
          "dev": "webpack-dev-server",
          "build": "webpack --env.prod"
        },
        "dependencies": {
          "vue": "^3.1.1"
        },
        "devDependencies": {
          "@vue/compiler-sfc": "^3.1.1",
          "css-loader": "^3.5.2",
          "file-loader": "^6.0.0",
          "mini-css-extract-plugin": "^0.9.0",
          "stylus": "^0.54.7",
          "stylus-loader": "^3.0.2",
          "url-loader": "^4.1.0",
          "vue-loader": "^16.0.0-alpha.3",
          "vue-style-loader": "^4.1.2",
          "webpack": "^4.42.1",
          "webpack-cli": "^3.3.11",
          "webpack-dev-server": "^3.10.3"
        },
        "keywords": ["todo", "vue"],
        "name": "vue-todo-list-app-with-single-file-component",
        "description": "A simple todo list application written in Vue with Single File Component (SFC) support."
      }
    
    webpack.config.js
    
    const path = require("path");
    const { VueLoaderPlugin } = require("vue-loader");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = (env = {}) => ({
      mode: env.prod ? "production" : "development",
      devtool: env.prod ? "source-map" : "cheap-module-eval-source-map",
      entry: [
        env.prod ? false : require.resolve(`webpack-dev-server/client`),
        path.resolve(__dirname, "./src/main.js")
      ].filter(Boolean),
      output: {
        path: path.resolve(__dirname, "./dist"),
        publicPath: "/dist/"
      },
      resolve: {
        alias: {
          // this isn't technically needed, since the default `vue` entry for bundlers
          // is a simple `export * from '@vue/runtime-dom`. However having this
          // extra re-export somehow causes webpack to always invalidate the module
          // on the first HMR update and causes the page to reload.
          vue: "@vue/runtime-dom"
        }
      },
      module: {
        rules: [
          {
            test: /\.vue$/,
            use: "vue-loader"
          },
          {
            test: /\.png$/,
            use: {
              loader: "url-loader",
              options: { limit: 8192 }
            }
          },
          {
            test: /\.css$/,
            use: [
              {
                loader: MiniCssExtractPlugin.loader,
                options: { hmr: !env.prod }
              },
              "css-loader"
            ]
          },
          {
            test: /\.stylus$/,
            use: ["vue-style-loader", "css-loader", "stylus-loader"]
          },
          {
            test: /\.pug$/,
            loader: "pug-plain-loader"
          }
        ]
      },
      plugins: [
        new VueLoaderPlugin(),
        new MiniCssExtractPlugin({
          filename: "[name].css"
        })
      ],
      devServer: {
        inline: true,
        hot: true,
        stats: "minimal",
        contentBase: __dirname,
        overlay: true,
        injectClient: false,
        disableHostCheck: true
      }
    });
    
    test.html
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>Vue Simple Todo App with SFC</title>
        <link
          rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" rel="external nofollow"  rel="external nofollow" 
        />
        <link rel="stylesheet" href="/dist/main.css" rel="external nofollow"  rel="external nofollow"  />
      </head>
      <body>
        <div id="app222">test pages</div>
        <script src="/dist/main.js"></script>
      </body>
    </html>
    
    src 폴 더 안에 세 개의 파일 이 있 습 니 다.App.vue main.js 와 TodoItem.vue.
    App.vue
    
    <template>
      <div class="wrapper">
        <h1>My Todo List</h1>
        <form @submit.prevent="addTodo">
          <input type="text" name="todo-text" v-model="newTodoText" placeholder="New todo">
        </form>
        <ul v-if="todos.length">
          <TodoItem v-for="todo in todos" :key="todo.id" :todo="todo" @remove="removeTodo"/>
        </ul>
        <p class="none" v-else>Nothing left in the list. Add a new todo in the input above.</p>
      </div>
    </template>
    
    <script>
    import TodoItem from "./TodoItem.vue"
    
    let nextTodoId = 1
    
    const createTodo = text => ({
      text,
      id: nextTodoId++
    })
    
    export default {
      components: {
        TodoItem
      },
    
      data() {
        return {
          todos: [
            createTodo("Learn Vue"),
            createTodo("Learn about single-file components"),
            createTodo("Fall in love ❤️")
          ],
    
          newTodoText: ""
        }
      },
    
      methods: {
        addTodo() {
          const trimmedText = this.newTodoText.trim()
    
          if (trimmedText) {
            this.todos.push(createTodo(trimmedText))
          }
    
          this.newTodoText = ""
        },
    
        removeTodo(item) {
          this.todos = this.todos.filter(todo => todo !== item)
        }
      }
    }
    </script>
    
    <style lang="stylus">
    *, *::before, *::after 
      box-sizing border-box
    
    html, body
      font 16px/1.2 BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif
      padding 10px
    
    .wrapper
      width 75%
      margin 0 auto
    
    form
      margin-bottom 20px
    
    input[type="text"]
      width 100%
      padding 10px
      border 1px solid #777
    
    ul, li
      margin 0
      padding 0
    
    p.none
      color #888
      font-size small
    </style>
    
    main.js
    
    import { createApp } from 'vue'
    import App from './App.vue'
    
    createApp(App).mount('#app')
    
    TodoItem.vue
    
    <template>
      <li>
        <span>{{ todo.text }}</span>
        <button @click.prevent="$emit('remove', todo)">Remove</button>
      </li>
    </template>
    
    <script>
    export default {
      props: {
        todo: {
          required: true,
          type: Object
        }
      }
    }
    </script>
    
    
    <style lang="stylus" scoped>
    li
      display flex
      margin 5px 0
    
      span
        flex 1
      
      button
        border 1px solid orange
        background orange 
        color white
        font-size 0.8rem
        padding 2px 4px
        cursor pointer
    
        &:hover
          border-color #ff8100
          background #ff8100
    </style>
    
    주의 하 다.
    웹 팩 을 모 르 면 홈 페이지 의 지시 에 따라 vue 의 비계 로 기본 도 구 를 설치 하 는 것 을 권장 합 니 다.
    또는 제 가 준 pakage.json 에 따라 프로젝트 에 올 리 고 npm install 을 통 해 가장 기본 적 인 환경 을 설치 한 다음 에 npm run dev 를 통 해 현지 개발 을 할 수 있 습 니 다.
    사실,나 는 이 단일 파일 구성 요소 의 용도 가 이미 비교적 작다 고 생각한다.순수 js 프로젝트 를 제외 하고 사용 하 는 라 이브 러 리 와 구성 요소 가 매우 오래 되 었 습 니 다.이 럴 때 이 단일 파일 구성 요소 로 새로운 기능 개발 을 진행 하면 효과 가 좋 습 니 다.전 제 는 vue 에 대해 잘 알 아야 한 다 는 것 입 니 다.동시에,나 는 웹 팩 을 좀 배 워 야 한다 고 건의 합 니 다.bable 에 대해 아무것도 모 르 지 말고 node 를 통 해 프로젝트 를 시작 해 야 합 니 다.
    사실 하나의 파일 로 html/css/JavaScript 를 레이 어 링 하여 하나의 파일 로 통일 시 켜 우리 의 프로젝트 를 더욱 조리 있 고 규범 적 으로 보일 수 있 습 니 다.우리 의 jq 시대 에 css 를 html 에 섞 었 기 때문에 간단 한 클릭 사건 은 모두 분리 해 야 합 니 다.이 체험 은 당연히'층 을 나 누 어 치료 하 는 것'만큼 명확 하지 않 습 니 다.
    참고 문헌:
    1、 https://v3.cn.vuejs.org/guide/single-file-component.html#%E5%9C%A8%E7%BA%BF%E6%BC%94%E7%A4%BA
    2、 https://www.cnblogs.com/houxianzhou/p/14510450.html
    vue 단일 파일 구성 요소 의 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 vue 단일 파일 구성 요소 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기