zoukankan      html  css  js  c++  java
  • npm(nodejs package manager)、webpack、Vue组件、Vue脚手架开发工具、Vue Router的使用、Vuex的使用、使用Django前后端交互

    13.8 npm(nodejs package manager)

    使用命令行安装包:
    1. cd切换到项目目录下,执行初始化操作 npm init/npm init -y
    2. 安装其他依赖包
    npm install jquery
    npm install jquery@1.11.13
    npm install jquery -g       全局安装
    npm install bootstrap@3 -D  开发环境下
    marked包安装和使用    npm install marked -D   
    npm install vuex -D
    3. 卸载包     npm uninstall 包名
    4. 更新npm    npm install npm@latest 
    5. npm安装包慢的解决办法:
        1.安装cnpm包 :https://npm.taobao.org/
        npm install -g cnpm --registry=https://registry.npm.taobao.org
        2. 配置npm源为阿里源
        npm config set registry https://registry.npm.taobao.org/

    在当前项目下生成文件:node_moduels(包含用npm导入的jQuery包等)、package.json、pack-lock.json(包含导入包的信息)

    index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <script src="./node_modules/jquery/dist/jquery.min.js"></script>
        <script>
            $.each([11,22,33], function(k,v){
                console.log(k,v)
            })
        </script>
    </body>
    </html>

    13.9 webpack

    为什么要有webpack?
    1. JS中不存在模块化的概念
    2. 安装和使用
    npm install webpack -g          --> 全局安装
    npm install webpack-cli -g
    3. webpack进阶:https://webpack.js.org/

    在当前项目下生成文件:dist(包含main.js,将项目下的依赖关系文件打包保存在main.js文件中)、node_moduels(包含用npm导入的jQuery包等)、package.json、pack-lock.json(包含导入包的信息)

    x.js:

    var alex = 'sb';
    var login = true;
    module.exports = {alex}

    y.js:

    var obj = require('./x')
    var jquery = require('jquery')
    console.log(obj);   //sb
    jquery.each([11,22,33,44], function(k,v){
        console.log(k,v)
    })

    main.html:

    <body>
    <script src="./dist/main.js"></script>
    </body>

    13.10Vue组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div id="app">
            <button-counter></button-counter>
            <button-counter></button-counter>
            <button-counter></button-counter>
            <component-a></component-a>
            <ComponentB             //父组件向子组件通信
                v-for="a in aList"
                v-bind:url="a.url"
                v-bind:title="a.title"
            ></ComponentB>
           <p> 被选了{{num}}次!</p>     <!--子组件向父组件通信-->
            <ComponentC
                v-for="name in nameList"
                v-bind:name="name"
                v-on:do="foo"
            ></ComponentC>  
            <table>                 //组件的is属性
            <!-- <ComponentB></ComponentB> 此时组件中template中的tr会显示在table外-->  
            <tr is="ComponentB"></tr>  //此时组件中template中的tr会显示在table中的tbody中
            </table>
        </div>
        <script src="./node_modules/vue/dist/vue.js"></script>  <!--通过npm导入vue.js-->
        <script>
            //全局注册组件:定义一个名为button-counter的新组件
            Vue.component('button-counter', {
            /* data: {
                count: 0
                } */
            data: function (){      //data 必须是一个函数,不能直接是对象,组件复用时会影响到其他实例
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">你点了我 {{ count }} 次。</button>'
            })
            //局部注册组件:局部注册的组件在其子组件中不可用,如果你希望ComponentB在ComponentA中可用,需声明
            const ComponentA = {
                 components: {
                    ComponentB
                },
                template: `<a href='https://www.sogo.com'>点我</a>`,
                data: function(){
                    return {  
                    }
                }
            }
            //父组件向子组件通信
            const ComponentB  = {
                //template: `<a> <slot></slot></a>`,通过插槽slot分发内容
                //template: ` <tr><slot></slot></tr>`,组件的is属性
                template: `<p><a v-bind:href='url'>{{title}}</a></p>`,
                props: {            //在子组件中使用props声明将url、title传入组件template并显示
                    url: String,     //对传值进行校验
                    title: {
                        type: String,
                        required: true
                    }
                },
                data: function(){
                    return {
                    
                    }
                }
            }
             //子组件向父组件通信
            const ComponentC = {
                //子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件
                template: `<button v-on:click='$emit("do")'>{{ name }}</button>`,
                props: {        //使用props声明将name传入组件template并显示
                    name
                },
                methods: {
                    do(){
    ​
                    }
                }
            }
            var vm = new Vue({
                el: '#app',
                components:{        //局部注册组件需要在components中声明
                    'component-a': ComponentA,
                    ComponentB,
                    ComponentC
                },
                 data: {
                    num:0,
                    nameList: ["技师A", '技师B', '技师C'],
                    aList: [
                        {
                            url: 'https://www.sogo.com',
                            title: 'sogo'
                        },
                        {
                            url: 'https://www.luffycity.com',
                            title: 'luffycity'
                        },
                        {
                            url: 'http://www.oldboyedu.com/',
                            title: 'oldboy edu'
                        },
                    ]
                },
                methods: {
                    foo(){
                        this.num += 1;
                    }
                } 
            })
        </script>
    </body>
    </html>

    13.11Vue脚手架开发工具

    1. 安装
    npm install -g vue-cli
    2. 使用
    查看安装的vue-cli版本:vue -V
    查看帮助:vue --help
    查看支持的模板:vue list
    3.创建Vue项目
    webpack简单模板:vue init webpack-simple app01
    webpack模板:(使用Bootstrap时候要用这个):vue init webpack vueapp01
        ? Project name vueapp01                     '回车确认'
        ? Project description A Vue.js project        '回车确认'
        ? Author Lmy <1592187014@qq.com>             '回车确认'
        ? Vue build (Use arrow keys)                
        ? Vue build (standalone)
            > Runtime + Compiler: recommended for most users    '回车确认'
            Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are              ONLY allowed in .vue files - render functions are required elsewhere
        ? Install vue-router? 'Yes'
        ? Use ESLint to lint your code? 'No'
        ? Set up unit tests No '(设置单元测试)'
        ? Setup e2e tests with Nightwatch?  'No'   '(用夜视器设置e2e测试?)'
        ? Should we run `npm install` for you after the project has been created? (recommended) (Use arrow keys)    '(npm)'
            > Yes, use NPM    '回车确认'
            Yes, use Yarn
            No, I will handle that myself
        。。。。( vue-cli · Generated "vueapp01".)。。。。(Installing project dependencies ...)。。。。 Project initialization finished!。。。。。。
    '''To get started:
      cd vueapp01
      npm run dev'''
    C:untitled>cd vueapp01
    C:untitledvueapp01>npm run dev '(启动前端服务)'' Your application is running here: http://localhost:8080'
    停止项目:Ctrl + C 
    4.在当前项目下安装bootstrap
    C:untitledvueapp01>npm install bootstrap@3.3.7 -D  或者  npm install bootstrap@3.3.7 --save-d
    '安装开发环境下的bootstrap,并将依赖关系写入package.json中'

    13.12Vue Router的使用

    两个组件(Vue Router内置组件):

    <router-link to="/foo">Go to Foo</router-link> #默认渲染成a标签
    <router-view></router-view>                  #路由视图,组件显示位置

    制作组件路由:

    components/Home.vue

    <template>
        <div>
            <h1>这是home页面</h1>   //vue文件中,组件template一定要用div包裹所有标签
        </div>
    </template><script>
    export default {
        name:'Home',
    }
    </script><style></style>

    components/Note.vue

    <template>
        <div>
            <h1>这是note页面</h1>
        </div>
    </template><script>
    export default {
        name:'Note',
    }
    </script><style>
    </style>

    router/index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import Home from '@/components/Home.vue'  //从组件导入,@代表src
    import Note from '@/components/Note.vue' 
    ​
    Vue.use(Router)
    ​
    export default new Router({
      mode:'history',                       //去掉URL中的'#'
      routes: [                             //设置组件路由对应关系
        {
          path: '/home',
          name: '我的home页面',     
          component: Home
        },
        {
          path: '/note',
          name: '我的note页面',
          component: Note
        }
      ]
    })

    Apple.vue:

    <li><router-link to="/home">link home版</router-link></li>
    <li><router-link to="/note">link note版</router-link></li>
    <router-view></router-view>

    <router-link
              to="/home" 
              tag="li"               #指定生成li标签
              active-class="active"   #指定标签被点击时的样式
            >
              <a href="">link home版</a>
            </router-link>
     <router-link
              to="/note" 
              tag="li"               
              active-class="active"   
            >
              <a href="">link note版</a>
            </router-link>
    <router-view></router-view>

    <router-link
        v-for="(item,index) in allRouters"
        v-bind:to="item.path"
        tag="li"
        active-class="active"    
        v-bind:key=index
            >
        <a href="">{{ item.name }}</a>
    </router-link>
    <router-view></router-view><script>
    import 'bootstrap/dist/css/bootstrap.min.css'
    export default {
      name: 'App',
      // 计算属性
      computed:{
        allRouters(){   // 当前Vue实例注册的所有路由
          return this.$router.options.routes
        }
      }
    }
    </script>

    main.js:

    import Vue from 'vue'
    import App from './App'
    import router from './router'  //导入路由对象
    ​
    Vue.config.productionTip = false/* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,           //注册路由对象
      components: { App },
      template: '<App/>'
    })

    13.13Vuex的使用

    store.js:

    import Vue from 'vue'
    import Vuex from 'vuex'
    ​
    Vue.use(Vuex)
    // 开一家商店
    export default new Vuex.Store({
        state: {
          count:0
        },
        mutations:{             //提交 mutation来更改 Vuex 的 store 中的状态
          increment(state){
            state.count+=1
          }
        }
      })

    main.js:

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from './store'
    ​
    Vue.config.productionTip = false/* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,   //注册路由对象
      store,    //向vue实例注册我的商店
      components: { App },
      template: '<App/>'
    })

    NoteItem.vue:

    <template>
      <div
      class="list-group-item"
      v-on:click="foo"
      >
      {{n}}
      </div>
    </template><script>
    export default{
        name:'NoteItem',
        props:{
          n:String
        },
        methods:{                   //v-on监听事件使用method
          foo(){                  //子组件被点击时向父组件传值 ,使用$emit()传递事件,告知父组件子组件被点击
           // this.$emit('plus')   //使用子组件向父组件传值时使用$emit,使用vuex时注释此项
           //this.$store.state.count+=1      //使用vuex,在被点击时修改store中的count
           this.$store.commit('increment')  //使用vuex,在被点击时提交事件increme
        }
        }
      }
    </script><style>
    </style>

    NoteList.vue:

    <template>
        <div>
        <div class="list-group">
          <!-- #父组件向子组件传值,将循环数据使用v-bind传给子组件,子使用props接收并使用,后替换NoteItem -->
                <NoteItem
                v-for="(note,index) in noteList"
                v-bind:n='note'
                v-bind:key='index'
                v-on:plus='p'>  <!-- #子组件向父组件传值,使用v-on监听$emit传递的事件 -->
                </NoteItem>
                <p>计数器:{{count}}</p>
            </div>
         </div>
    </template><script>
      import NoteItem from '@/components/NoteItem'
      export default {
        name:'NoteList',
        components:{
           NoteItem
         },
         data:function() {
           return {
             noteList: [
               '第一项','第二项','第三项'
             ],
             //count:0          //使用子组件向父组件传值时使用data,使用vuex时注释此项
           }
         },
         methods:{     //v-on监听事件使用method
           p(){
             //console.log(this.count);
             this.count+=1
         }
         },
         computed:{         //使用vuex时使用此项,要用return返回
           count:function() {
             return this.$store.state.count
           }
         }
    ​
    }
    </script>
    <style>
    </style>

    Vue组件之间的通信:

       父组件->子组件:子组件中要使用:props声明我接收的变量

       子组件 -> 父组件:1.子组件 通过this.$emit('事件名') 向父组件抛出事件

               2.父组件 通过v-on:事件名='方法名' 监听子组件的事件从而触发一个修改数据的方法

    13.14使用Django前后端交互

    1.django做后端,(先导入pip3 install django-cors-headers)在Django的settings文件中配置:

    #允许跨域请求的IP(因为vue默认8080端口,Django默认8000端口)
    #授权白名单
    CORS_ORIGIN_WHITELIST=(
        'http://localhost:8080',
        'http://127.0.0.1:8080'
    )

    views.py:

    from app01 import models
    from django.http import JsonResponse
    ​
    def note_list(request):
        ret = {"code": 0}
        data = list(models.Note.objects.all().values("id", "title", "content", "markedcontent"))
        ret["data"] = data
        return JsonResponse(ret) #返回json字符串

    2.vue作前端,使用axios发送请求并接受后端的数据(安装:npm install axios)

    App.vue:

    <script>
      import 'bootstrap/dist/css/bootstrap.min.css'
      export default {
        name: 'App',
        data: function () {
          return {}
        },
        // 计算属性
        computed: {
          // 当前Vue实例注册的所有路由
          allRouters() {
            return this.$router.options.routes
          }
        },
        beforeMount(){     //在挂载前执行store.js中的playNote函数接受后端数据
         this.$store.commit('playNote')
        },
      }
    </script>

    store.js:将接收到的数据放进商店

    import Vue from 'vue'
    import Vuex from 'vuex'
    import axios from 'axios'  //导入axios
    Vue.use(Vuex)
    ​
    export default new Vuex.Store({
        state: {
          count:0,
          notelist:[]
        },
        mutations:{
        
          addnote_store(state,data){   //捕获NoteEdit传到store的数据用data接收
            state.notelist.push(data)
          },
          playNote(state,data){
            //在挂载DOM之前向后端获取数据
            axios.get('http://127.0.0.1:8000/api/notes/')  //访问note_list视图函数的路由
                   .then(function (response) {          //response接收包含json字符串(ret)在内的数据
                       //console.log(response.data.data);
                       state.notelist=response.data.data  //后端返回到response中的数据(ret)以data命名
            })
                   .catch(function (error) {              //获取后端数据失败打印错误信息
                      console.log(error);
            });
          }
        },
        actions:{
            
        //方法一:直接将新添加的数据使用 addnote_store添加到 notelist:[]
          addnode_post(context,data){    //异步操作store
         // 发送 POST 请求
           var data=qs.stringify(data) //发送json类型
           axios({
             method: 'post',
             url: 'http://127.0.0.1:8000/api/add/',
             data: data,
             })
             .then(function (response) {
               console.log('插入数据');
                 console.log(response);
                 context.commit('addnote_store',response.data.data)  // {id: 3, title: "第三条笔记", content: "", markdownContent: ""}
                  //此处只让后端在数据库中添加数据,不添加到notelist:[]
               })
             .catch(function (error) {
                 console.log(error);
               })
               },
        }
        })

    NoteList.vue:取出商店里的数据,交给template进行渲染

    <template>
            <div class="list-group">
                <NoteItem
                v-for="(note,index) in noteList"
                v-bind:n='note'
                v-bind:key='index'
                </NoteItem>
            </div>
    </template><script>
      import NoteItem from '@/components/NoteItem'
      export default {
        name:'NoteList',
        components:{
           NoteItem
         },
         data:function() {
           }
         },
         computed:{         //使用vuex时使用此项
           count:function() {
             return this.$store.state.count
           },
           noteList:function(){    //使用vuex获得store的数据
             return this.$store.state.notelist
           }
         }
    }
    </script>

    NoteItem.vue:

    <template>
      <div
      class="list-group-item"
      v-on:click="foo"
      >
      {{n.title}}{{n.content}}
      </div>
    </template><script>
    export default{
        name:'NoteItem',
        props:{      //props指定接收父组件传递的数据
          n:Object
        },
        methods:{                 //v-on监听事件使用method
          foo(){                  //子组件被点击时向父组件传值 ,使用$emit()传递事件,告知父组件子组件被点击
           // this.$emit('plus')   //使用子组件向父组件传值时使用$emit,使用vuex时注释此项
           //this.$store.state.count+=1      //使用vuex,在被点击时修改store中的count
           this.$store.commit('increment')   //使用vuex,在被点击时提交事件increme
        }
        }
      }
    </script>

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    《SQL Server 2008从入门到精通》--20180628
    2019国赛
    [蓝桥杯2020] 湖北省省赛
    2019第十届蓝桥杯B组决赛题解第五题
    试题 算法提高 分解质因数
    大数相加减
    试题 算法提高 汉诺塔
    试题 算法提高 欧拉函数
    试题 算法提高 天天向上-dp
    算法训练 猴子吃包子-构造
  • 原文地址:https://www.cnblogs.com/mylu/p/13821238.html
Copyright © 2011-2022 走看看