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 <[email protected]> '回車確認' ? 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:\untitled\vueapp01>npm run dev '(啟動前端服務)'' Your application is running here: http://localhost:8080' 停止專案:Ctrl + C 4.在當前專案下安裝bootstrap C:\untitled\vueapp01>npm install [email protected] -D 或者 npm install [email protected] --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=https://www.cnblogs.com/mylu/archive/2020/10/15/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>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/172646.html
標籤:其他
上一篇:bootstrap輸入框組
下一篇:攻防世界RE 2.666
