vue学习

ToDo项目

参考

慕课网视频教程链接
视频代码git
参考链接


一、项目创建

  1. 新建文件夹 ToDo,进入文件夹 ToDo
  2. npm 初始化
# 命令会在当前目录线新建 package.json 文件
npm init

package.json 内容如下:

{
  "name": "npminstal",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
  1. npm 安装依赖,
# 提示依赖其他包,则安装提示的包
npm i vue vue-loader vue-template-compiler css-loader style-loader
  1. 新建src文件夹,新建src/App.vue文件。内容如下:
<template>
    <div id="app">hello {{name}}!</div>
</template>

<script>
	export default {
	    data(){
	        return {
	            name:"world"
	        }
	    }
	}
</script>

<style scoped>
	#app{
	    color: red
	}
</style>

  1. 新建index.js,内容如下
import Vue from 'vue'
import App from './App.vue'

const root = document.createElement("div");
document.body.appendChild(root)
 new Vue({
    render:(h)=>h(App)
}).$mount(root)
  1. 新建webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
    entry:path.join(__dirname,"src/index.js"),
    output:{
        filename:"bundle.js",
        path:path.join(__dirname,"dist")
    },
    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:"vue-loader"
            },
            {
                test:/\.css$/,
                use:["style-loader","css-loader"]
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin()
      ]
}
  1. 编辑 package.json, scripts属性增加build,如下:
 ...
 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config  webpack.config.js"
  },
  ...
  1. 测试构建
npm run build

二、配置css、image等

  1. css文件处理
    step1、新建 src/assert目录,新建src/assert/stylus/app.css。内容如下
body{
    color: green;
}

step 2、index.js文件中引入app.css

import Vue from 'vue'
import App from './App.vue'

import "./assert/stylus/app.css"

const root = document.createElement("div");
···

step3、安装style-loader css-loader。(第一章节已安装)
在这里插入图片描述

step4、配置webpack.config.js(第一章节已配置)
在这里插入图片描述
2. 图片处理
step1、新建 src/image目录,导入图片 leaf001.jpeg(图片名称)
step2、修改 src/stylus/app.css。修改后内容如下

body{
    color: green;
    background-image: url(../image/leaf001.jpeg)
}

step3、安装url-loader file-loader

npm i url-loader file-loader

step4、配置webpac.config.js

···
rules:[
            {
                test:/\.vue$/,
                loader:"vue-loader"
            },
          ···
            {
                test:/\.jpeg$/,
                use:[
                    {
                        loader:"url-loader",
                        options:{
                            limit:1024,
                            //[name]:文件名   [ext]:文件扩展名
                            name:"prefix_[name].[ext]"
                        }
                    }
                ]
            }
        ]
        ···
  1. stylus文件处理
    step1、新建src/stylus/app.styl。内容如下:
body
  font-size 40px

step2、index.js引入app.styl

import Vue from 'vue'
import App from './App.vue'

import "./assert/stylus/test.css"
import "./assert/image/leaf001.jpeg"
import "./assert/stylus/test.styl"

const root = document.createElement("div");
document.body.appendChild(root)
 new Vue({
    render:(h)=>h(App)
}).$mount(root)

step3、安装stylus stylus-loader

npm i stylus stylus-loader

step4、修改webpack.config.js,配置stylus-loader

···
rules:[
            ···
            {
                test:/\.styl$/,
                use:["style-loader","css-loader","stylus-loader"]
            }
        ]
···        

三、配置weback-dev-server

  1. 安装webpack-dev-server cross-env
npm i webpack-dev-server cross-env
  1. 配置package.json。增加dev
···
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config  webpack.config.js",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config  webpack.config.js"
  },
···
  1. 配置webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HTMLPlugin = require("html-webpack-plugin")
const webpack = require("webpack")


const isDev = process.env.NODE_ENV === "development"

const config = {
    target:"web",
    entry:path.join(__dirname,"src/index.js"),
    output:{
        filename:"bundle.js",
        path:path.join(__dirname,"dist")
    },
    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:"vue-loader"
            },
            ···
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new webpack.DefinePlugin({
            "process.env":{
                NODE_ENV:isDev?'"development"':'"production"'
        }
        }),
        new HTMLPlugin()
      ]
}

if(isDev){

    config.devtool = "#cheap-module-eval-source-map"
    config.plugins.push(
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin()
    )
    config.devServer={
        host:"0.0.0.0",
        port:9080,
        overlay:{
            error:true
        },
        hot:true
    }
}

module.exports = config
  1. 启动webpack-dev-server
npm run dev

四、业务开发

  1. 删除无用代码
    删除app.vue中个标签中的内容
    删除index.js 中引入的全局样式

  2. 安装插件

npm i postcss-loader autoprefixer babel-loader babel-core 
npm i babel-preset-env babel-plugin-transform-vue-jsx
  1. 新建 .babelrc。内容如下:
{
    "presets": [
        "env"
    ],
    "plugins": [
        "transform-vue-jsx"
    ]
}
  1. 新建postcss.config.js。内容如下:

const autoprefixer = require("autoprefixer")

module.exports={
    plugins:[
        autoprefixer()
    ]
}
  1. 配置 webpack.config.js。内容如下
···
{
    test:/\.jsx$/,
    loader:"babel-loader"
},
{
    test:/\.styl$/,
    use:[
        "style-loader",
        "css-loader",
        {
            loader:"postcss-loader",
            options:{
                sourceMap:true
            }
        }
    ]
}
···

  1. 界面
    新建 src/ToDo文件夹。ToDo目录下新建

header.vue

<template>
    <header class="main-header">
        <h1>Todo</h1>
    </header>
</template>

<script>
export default {
    
}
</script>

<style lang="stylus" scoped>
.main-header
    text-align center
    h1
        font-size 100px
        color rgba(175,47,47,0.4)
        font-weight 400
        margin 20px
</style>

footer.jsx

import "../assert/stylus/footer.styl"

export default {
    data(){
        return {
            author:"XB"
        }
    },
    render(){
        return (
            <div id="footer">
                <span>Write by {this.author}</span>
            </div>
        )
    }
}

todo.vue


<template>
<section class="real-app">

    <input 
        type="text"
        class="add-input"
        placeholder="接下去要做什么"
        autofocus="autofocus"
        @keyup.enter="addTodo"
    >
    <Item :todo="todo"> </Item>
    <Tabs :filter="filter"></Tabs>
</section>
    
</template>

<script>

import Item from "./item.vue"
import Tabs from "./tabs.vue"

export default {
    data(){
        return{
            todo: {
                id:1,
                content:"学习",
                completed:false
            },
            filter:"all"
        }
       
    },
    components:{
        Item,
        Tabs
    },
    methods:{
        addTodo(){

        }
    }
}
</script>

<style lang="stylus" scoped>
.real-app
    width 600px
    margin 0 auto
    box-shadow 0 0 5px #666
.add-input
    position relative
    margin 0
    width 100%
    font-size 24px
    font-family inherit
    font-weight inherit 
    line-height 1.4em
    border none
    outline none 
    color inherit 
    box-sizing border-box
    font-smoothing antialiased
    padding 16px 16px 16px 36px
    border none
    box-shadow inset 0 -2px 1px rgba(0, 0, 0, 0.03)
</style>

item.vue


<template>

<div :class="['todo-item', todo.completed?'completed':'']">

    <input 
        type="checkbox"
        class="toggle"
        v-model="todo.completed"
    >
    <label >{{todo.content}}</label>
    <button class="destory" @click="deleteTodo"></button>
</div>
    
</template>

<script>
export default {
    props:{
        todo:{
            type:Object,
            required:true
        }
    },
    methods:{
        deleteTodo(){

        }
    }
    
}
</script>


<style lang="stylus" scoped>

.todo-item
        position relative
        background-color #fff
        font-size 24px
        border-bottom 1px solid rgba(0,0,0,0.06)
        &:hover
            .destory:after
                content 'x'            
        label
            white-space pre-line
            word-break break-all
            padding 15px 60px 15px 15px
            margin-left 45px
            display block
            line-height 1.2
            transition color 0.4s
        &.completed
            label
                color #d9d9d9
                text-decoration line-through
    .toggle
        text-align center
        width 50px
        height 30px
        position absolute
        top 0
        bottom 0
        margin auto 0
        border none
        appearance none
        outline none
        &:after
            content url('../assert/image/unChecked.svg')
        &:checked:after
            content url('../assert/image/checked.svg')
    .destory
        position absolute
        top 0
        right 10px
        bottom 0
        width 40px
        height 40px
        margin auto 0
        font-size 30px
        color #cc9a9a
        margin-bottom 11px
        transition color 0.2s ease-out
        background-color transparent
        appearance none
        border-width 0
        cursor pointer
        outline none

</style>

tabs.vue


<template>

<div class="helper">
    <span class="left">2 items left</span>
    <span class="tabs">
        <span 
            v-for="state in states" 
            :key="state"
            :class="['state',filter===state?'actived':'']"
            @click="toggleFilter(state)"
            >
            {{state}}
        </span>
    </span>
    <span class="clear" @click="clearAllCompleted">Clear Completed</span>
</div>
    
</template>

<script>
export default {
    props:{
        filter:{
            type:String,
            required:true
        }
    },
    data(){
        return {
            states:["all","active","completed"]
        }
    },
    methods:{
        clearAllCompleted(){},
        toggleFilter(){}
    }
}
</script>

<style lang="stylus" scoped>
.helper
    font-weight 100
    display flex
    justify-content space-between
    padding 5px 0
    line-height 30px
    background-color #ffffff
    font-size 14px
    font-smoothing antialiased
.left, .clear, .tabs
    padding 0 10px
.left .clear
    width 150px
.left
    text-align center
.clear
    text-align right
    cursor pointer
.tabs
    width 200px
    display flex
    justify-content space-between
    *
        display inline-block
        padding 0 10px
        cursor pointer
        border 1px solid rgba(175,47,47,0)
        &.actived
            border-color rgba(175,47,47,0.4)
            border-radius 5px
</style>
  1. 业务

五、遇到的问题

  1. npm 安装警告
···
npm WARN vue-loader@15.7.1 requires a peer of css-loader@* but none is installed. You must install peer dependencies yourself.
···

问题分析:vue-loader依赖css-loader,需要手动安装css-loader
解决方案:

npm i css-loader
  1. npm run build 提示如下:
One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
 - webpack-cli (https://github.com/webpack/webpack-cli)
   The original webpack full-featured CLI.
We will use "npm" to install the CLI via "npm install -D".
Do you want to install 'webpack-cli' (yes/no):

输入:yes

  1. 解析.vue文件报 Module parse failed: Unexpected character ‘#’
ERROR in ./src/App.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
 @ ./src/index.js 2:0-27 8:20-23

ERROR in ./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css& 16:0
Module parse failed: Unexpected character '#' (16:0)

问题分析:vue-loader 解析css样式失败
解决方案 :安装并配置style-loader css-loader,并配置webpack.config.js
step、安装loader

npm i style-loader css-loader 

setp2、修改webpack.config.js

const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
···
    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:"vue-loader"
            },
            {
                test:/\.css$/,
                use:["style-loader","css-loader"]
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin()
      ]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值