使用vue独立开发组件(vue单文件组件的实现)
使用vue独立开发组件
vue单文件组件的实现最近翻阅了一下vue。发觉有一个单文件组件之前基本忽视掉了。vue.js中的单文件组件允许在一个文件中定义一个组件的所有内容。也就是说,一个页面或者是一个组件,我们想将他们捆绑在一起,那么vue的这个单文件组件可以做到。正如vue的官网说的,“在很多 Vue 项目中,我们使用 app.component 来定义全局组件,紧接着用 app.mount('#app') 在每个页面内指定一个容器元素。”这里的组件,都是相对简单的,而面对一个比较复杂的项目,这种方式就行不通。原因如下:
- 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复;
- 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \;
- 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏;
- 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug
- (曾经的 Jade) 和 Babel。
所有这些都可以通过扩展名为 .vue 的 single-file components (单文件组件) 来解决,并且还可以使用 webpack 或 Browserify 等构建工具。
那么vue项目中的单文件组件需要如何创建呢?
npm install -D @vue/compiler-sfc
在控制台上输入上述的代码,然后就会出现一个文件夹和另一个json文件。如下:
我们要构建单文件组件,就要自个制定文件。同时对webpack也要有一定的了解才行。
比如说,我们自己安装一些需要的依赖。比如说,css-loader、css的预编译处理器等等。因为需要项目对vue文件进行解析,那么vue-loader是必须的。
这些文件其实都是vue的简单版本。比如简单版的hello.vue文件,可以如下
由此可以看见: 三个部分组成。而template这个部分是不可缺少的,其它的两个部分,style和script还可以忽略掉。
script让你的页面js可以跟vue完美结合,而style可以使用预处理器来构建简洁和功能更丰富的组件。(这个单文件组件很像最初前端开发中的html文档,它有自己的style标签和script标签,只是表现层使用一个template标签。由于使用了简单的方式,得到一个强大的分层组件(内容/模板:,表现:
可能有的小伙伴喜欢将不同模块拆分开来,也就是vue文档说的关注点分离。那么没有关系,你可以拆开那些文档,将css和js拆开到另一个文件,之后引入进组件中。如下:
<!-- my-component.vue --> <template> <li>This will be pre-compiled</li> </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> <li id="app"></li> <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: /\.jpg" alt="使用vue独立开发组件(vue单文件组件的实现)" border="0" />
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> <li id="app222">test pages</li> <script src="/dist/main.js"></script> </body> </html>
src文件夹里边有三个文件,App.vue main.js 和TodoItem.vue
其中:App.vue
<template> <li 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> </li> </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>
注意
如果不懂得webpack,建议还是按照官网的指示,用vue的脚手架安装基本的工具。
或者是按照我给的pakage.json放到项目上,npm install一下,安装好最基本的环境,然后可以通过npm run dev进行本地开发。
其实,我觉得这个单文件组件用处已经比较小。除非就是一个纯js的项目,用的库和组件都已经非常的古老,那么这个时候用这个单文件组件来进行新的功能开发,效果还是不错的,前提是你要对vue比较熟悉。同时,我建议还是要学习一下webpack。不要对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单文件组件内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- vue中的mapgetter优势(vuex 中辅助函数mapGetters的基本用法详解)
- vue-cli安装教程学习(Vue新手指南之创建第一个vue-cli脚手架程序)
- vue react和angular(详解React Angular Vue三大前端技术)
- vue中怎么触发复选框的点击事件(vue点击弹窗自动触发点击事件的解决办法模拟场景)
- vue 优雅写法(使用vue实现手写签名功能)
- vue做个人页面(vue简易记事本开发详解)
- vue怎么编写规则(vue使用节流函数的踩坑实例指南)
- vue基础语法对象(浅析从面向对象思维理解Vue组件)
- vue项目步骤(Vue项目中常用的实用技巧汇总)
- vue实现一个炫酷的日历组件(vue利用Moment插件格式化时间的实例代码)
- 小白vue教学(尤大大新活petite-vue的实现)
- vue组件开发步骤(解析如何自动化生成vue组件文档)
- vuejs指令解析(Vue.js中的计算属性、监视属性与生命周期详解)
- vue功能测试和生产环境切换(vue 单元测试的推荐插件和使用示例)
- vuex存取修改数据流程(vuex数据持久化的两种实现方案)
- vue应用转flutter(Vue和Flask通信的实现)
- 古代的鸽子是爱情的象征,并非和平的使者(古代的鸽子是爱情的象征)
- 一课译词 放鸽子(一课译词放鸽子)
- 终于来了,淘宝更改账户名测试中,快去看看你能不能修改(淘宝更改账户名测试中)
- 淘宝支持账号名修改,网友 终于可以 重新做人 了(淘宝支持账号名修改)
- 盘点那些年让人称奇的年终奖 最后一个赢辣条毫无悬念(盘点那些年让人称奇的年终奖)
- 你还没有升职吗 他竟因为几套激励理论,升职了(你还没有升职吗)
热门推荐
- pyqt5怎么在pycharm中安装(pycharm+PyQt5+python最新开发环境配置踩坑)
- sqlserver实现登录注册(Sqlserver创建用户并授权的实现步骤)
- thinkphp5框架分析(thinkPHP5框架路由常用知识点汇总)
- docker容器里的容器之间通信(Docker容器连接相互通信的实现)
- php中钩子的理解与实例教程(php中钩子hook的原理与简单应用demo示例)
- mysql的limit的分页使用(获取 MySQL innodb B+tree 的高度的方法)
- laravel关闭错误提示(解决laravel session失效的问题)
- css3结合js制作(CSS3截取字符串实例代码推荐)
- SQL中Union,Intersect,Except
- 怎么用docker中的mysql连接数据库(解决Docker之mysql容器数据库更改不生效的问题)