澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

cli的一些准备工作,vue个人笔记

一、跨域

python 之CORS,VUE rest_framework示例,corsrest_framework

一、跨域

    浏览器的同源策略

                ----对ajax请求进行阻拦

                ----对href属性读不阻拦

       xhr=new XMLHttpRequest

       xhr.open...

       xhr.send(...)

   解决方案:

       ---JSONP

                 点击按钮: 

                        动态添加一个

<script src='http://www.bonzeragro.com/uploads/allimg/190707/1I2012B5-0.jpg'></script>
                        <script>
                            function func(arg){
                                alert(arg)
                            }
                        </script

删除

<script src='http://www.bonzeragro.com/uploads/allimg/190707/1I2012B5-0.jpg'></script>

二、CORS

客户端浏览器:

        --$.ajax()

a. 简单请求(非常好)

A网站:
<input type="button" value="获取用户数据" onclick="getUsers()">

<script src="jquery-1.12.4.min.js"></script>
<script>
function getUsers() {
$.ajax({
url: '',
type:'GET',
success:function (ret) {
console.log(ret)
}
})
}
</script>

服务商:
class UsersView(views.APIView):
def get(self,request,*args,**kwargs):

ret = {
'code':1000,
'data':'老男孩'
}
response = JsonResponse(ret)
response['Access-Control-Allow-Origin'] = "*"
return response

b. 复杂请求(性能上的损耗,options预检,真实的请求)
A网站:
<input type="button" value="获取用户数据" onclick="getUsers()">

<script src="jquery-1.12.4.min.js"></script>
<script>
function getUsers() {
$.ajax({
url: '',
type:'POST',
data: {'k1':'v1'},
headers:{
'h1':'asdfasdfasdf'
},
success:function (ret) {
console.log(ret)
}
})
}
</script>

服务商:

class UsersView(views.APIView):
def get(self,request,*args,**kwargs):

ret = {
'code':1000,
'data':'老男孩'
}
response = JsonResponse(ret)
response['Access-Control-Allow-Origin'] = "*"
return response

def post(self,request,*args,**kwargs):
print(request.POST)
ret = {
'code':1000,
'data':'老男孩'
}
response = JsonResponse(ret)
response['Access-Control-Allow-Origin'] = "*"
return response

def options(self, request, *args, **kwargs):
# self.set_header('Access-Control-Allow-Origin', "")
# self.set_header('Access-Control-Allow-Headers', "k1,k2")
# self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
# self.set_header('Access-Control-Max-Age', 10)

response = HttpResponse()
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Headers'] = 'h1'
# response['Access-Control-Allow-Methods'] = 'PUT'
return response

  1. Vue rest示例

前端:vue
修改源:
npm config set registry

创建脚手架:
vue init webpack Vue项目名称
# Install vue-router? Yes

插件:
axios,发送Ajax请求
vuex,保存所有组件共用的变量
vue-cookies,操作cookie

流程:

  1. 创建脚手架

  2. # 用于点击查看组件
    <router-link to="/index">首页</router-link>

# 组件显示的位置
<router-view/>

  1. 写路由
    import Vue from 'vue'
    import Router from 'vue-router'
    import Index from '@/components/Index'
    import Login from '@/components/Login'
    import Course from '@/components/Course'
    import Micro from '@/components/Micro'
    import News from '@/components/News'
    import CourseDetail from '@/components/CourseDetail'
    import NotFound from '@/components/NotFound'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'index',
component: Index
},
{
path: '/index',
name: 'index',
component: Index
},
{
path: '/course',
name: 'course',
component: Course
},
{
path: '/course-detail/:id/',
name: 'courseDetail',
component: CourseDetail
},
{
path: '/micro',
name: 'micro',
component: Micro
},
{
path: '/news',
name: 'news',
component: News
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '*',
component: NotFound
}
],
mode: 'history'
})

  1. 写组件
    <template>

<div>
<h1>登录页面</h1>
<div>
<input type="text" v-model="username" placeholder="用户名">
<input type="text" v-model="password" placeholder="密码">
<a @click="doLogin">提交</a>
</div>
</div>
</template>

<script>

export default {
# 定义局部字段
data () {
return {
username: '',
password: ''
}
},
# 加载时执行
mounted:function(){
},
# 定义局部方法
methods:{
doLogin() {
var that = this
this.$axios.request({
url: '',
method: 'POST',
data: {
username: this.username,
password: this.password
},
responseType: 'json'
}).then(function (response) {
console.log(response.data)
// 找到全局变量,把用户名和token赋值到其中。
that.$store.commit('saveToken',response.data)
// 重定向到index
that.$router.push('/index')
})
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

  1. ajax请求:axios
    npm install axios

main.js
import Vue from 'vue'
import App from './App'
import router from './router'

import axios from 'axios'

Vue.prototype.$axios = axios

Vue.config.productionTip = false
...

组件使用:
this.$axios.request({
url: '',
method: 'POST',
data: {
username: this.username,
password: this.password
},
responseType: 'json'
}).then(function (response) {
console.log(response.data)

that.$router.push('/index')
})

PS:重定向 that.$router.push('/index')

  1. vuex
    npm install vuex

main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'

import store from './store/store' # vuex

Vue.prototype.$axios = axios

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
el: '#app',
store, # vuex
router,
components: { App },
template: '<App/>'
})

src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies'

Vue.use(Vuex)

export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
username: Cookie.get('username'),
token: Cookie.get('token')
},
mutations: {
// 组件中通过 this.$store.commit(参数) 调用
saveToken: function (state, data) {
state.username = data.username
cli的一些准备工作,vue个人笔记。state.token = data.token
Cookie.set('username', data.username, '20min')
Cookie.set('token', data.token, '20min')

},
clearToken: function (state) {
state.username = null
state.token = null
Cookie.remove('username')
Cookie.remove('token')
}
}
})

  1. vue-cookies
    npm install vue-cookies

Cookie.get('username')

Cookie.set('username', data.username, '20min')
Cookie.remove('username')

src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies' # vue-cookies

Vue.use(Vuex)

export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
username: Cookie.get('username'), # vue-cookies
token: Cookie.get('token') # vue-cookies
},
mutations: {
// 组件中通过 this.$store.commit(参数) 调用
saveToken: function (state, data) {
state.username = data.username
state.token = data.token
Cookie.set('username', data.username, '20min') # vue-cookies
Cookie.set('token', data.token, '20min')

},
clearToken: function (state) {
state.username = null
state.token = null
Cookie.remove('username') # vue-cookies
Cookie.remove('token')
}
}
})

  1. 路由
    # 定义路由
    {
    path: '/course-detail/:id/',
    name: 'courseDetail',
    component: CourseDetail
    },
    {
    path: '/login',
    name: 'login',
    component: Login
    },
    {
    path: '*',
    component: NotFound
    }

# router-link参数
<router-link :to="{'path':'/course-detail/' item.id }">{{item.name}}</router-link>
<router-link to="/index">首页</router-link>

# 获取传过来的参数
this.$route.params.id
# 重定向
this.$router.push('/index')

 

之CORS,VUE rest_framework示例,corsrest_framework 一、跨域 浏览器的同源策略 ----对ajax请求进行阻拦 ----对href属性读不阻拦 xhr=new XMLHttpReques...

vue-cli

个人技术学习笔记,如有雷同,纯属正常,请勿喷,谢谢合作。

https://ke.qq.com/course/186871 具体教学视频地址
创建Vue项目(具体看VueTest) eslint等测试的一律选N 其他可以写
先建文件夹 cd到目录下vue init webpack my-project 大型应用
或者 vue init webpack-simple my-project 创建简单模版
然后 cd my-project 用cnpm install安装依赖项
vue启动 cd到指定的目录下 输入npm run dev 启动 8080端口

项目musicWebApp

变量赋值用等号,标签内的属性赋值用等号,标签外的属性赋值用冒号。函数用冒号
官网:http://cn.vuejs.org/ 手册: http://cn.vuejs.org/api/ 适合: 移动端项目,小巧
v-model 一般表单元素(input) 双向数据绑定
循环: v-for="(k,v) in json" v-for="name in json"{{$index}} {{$key}}
事件: @click="" v-on:click="函数"
v-on:click/mouseout/mouseover/dblclick/mousedown.....
显示隐藏: v-show=“true/false”
事件对象: @click="show($event)"
阻止冒泡:a). ev.cancelBubble=true; b). @click.stop=" " 推荐b
阻止默认行为:a). ev.preventDefault() b). @contextmenu.prevent 推荐b
键盘: @keydown $event ev.keyCode键码
常用键: 回车 @keyup.13 @keyup.enter
上@keyup/keydown.left、下、左、右@keyup/keydown.right
属性: :src="" 推荐
class和style: :class="" :style=""
模板:{{msg}} 数据更新模板变化 {{msg}} 数据只绑定一次 {{{msg}}} HTML转意输出
过滤器:-> 过滤模板数据 {{msg| filterA | filterB}}
{{{msg}}} -> v-html
计算属性的使用:
computed:{
b:function(){ //默认调用get
return 值
}
}
对于任何复杂逻辑,你都应当使用计算属性。
computed里面可以放置一些业务逻辑代码,一定记得return
vue实例简单方法:
vm.$el -> 就是元素
vm.$data -> 就是data
vm.$mount -> 手动挂在vue程序
vm.$options -> 获取自定义属性
vm.$destroy -> 销毁对象
vm.$log(); -> 查看现在数据的状态
双向过滤器:

Vue.filter('filterHtml',{
read:function(input){ //model-view
return input.replace(/<[^<] >/g,'');
},
write:function(val){ //view -> model
return val;
}
});
自定义指令:
属性:
Vue.directive(指令名称,function(参数){
this.el -> 原生DOM元素
});
<div v-red="参数"></div>
指令名称: v-red -> red

  • 注意: 必须以 v-开头
    自定义键盘信息:
    Vue.directive('on').keyCodes.ctrl=17;
    Vue.directive('on').keyCodes.myenter=13;
    监听数据变化:
    vm.$watch(name,fnCb); //浅度
    vm.$watch(name,fnCb,{deep:true}); //深度监视
    bower-> (前端)包管理器
    npm install bower -g
    验证: bower --version
    bower install <包名>
    bower uninstall <包名>
    bower info <包名> 查看包版本信息
    定义组件(在src/component创建vue文件)
    .vue文件:放置的是vue组件代码 分为三部分:
    <template>此处放html模版</template>
    <script> (平时代码、ES6) babel-loader
    export default {
    name:"Vmain",
    data(){
    return{ 此处放数据 一定要返回值
    }
    },
    props:{ 此处用于接收父组件传下来的数据 json格式需要指明类型 也可以用数组
    cli的一些准备工作,vue个人笔记。},
    methods:{ 此处调用父组件的自定义事件
    },
    computed:{ 计算属性,处理复杂逻辑
    }
    }
    </script>
    <style></style> 此处放css样式

父级获取子级数据
*子组件把自己的数据,发送到父级
vm.$emit(事件名,数据);

ES6: 模块化开发
导出模块:
export default {}
引入模块:
import 模块名 from 地址
*组件里面放数据:
data必须是函数的形式,函数必须返回一个对象(json)
组件数据传递:

  1. 子组件想获取父组件data
    在调用子组件:
    <bbb :m="数据"></bbb> 绑定
    子组件之内:
    props:['m','myMsg'] 数组形式接收
    props:{ json格式接收
    'm':String,
    'myMsg':Number
    }

broserify 模块加载,只能加载js
webpack 模块加载器, 一切东西都是模块, 最后打包到一块了
修改端口:
package.json
"scripts":{
"dev":"webpack-dev-server --inline --hot --port 8082"
}
下载模块: npm install <package-name> --save-dev
EADDRINUSE 端口被占用

路由:vue-router
下载vue-router模块 cnpm install vue-router
import VueRouter from 'vue-router'
Vue.use(VueRouter);

vue-cli——vue脚手架 帮你提供好基本项目结构
本身集成很多项目模板:webpack 可以使用(大型项目)
Eslint 检查代码规范,单元测试
webpack-simple 个人推荐使用, 没有代码检查 √

基本使用流程:

  1. npm install vue-cli -g 安装 vue命令环境
    验证安装ok? vue --version
  2. 生成项目模板
    vue init <模板名> 本地文件夹名称
  3. 进入到生成目录里面
    cd xxx cnpm install
  4. npm run dev 启动

Vue2.0 必须有根元素,包裹住所有的代码
生命周期:
beforeCreate 组件实例刚刚被创建,属性都没有
created 实例已经创建完成,属性已经绑定
beforeMount 模板编译之前
mounted 模板编译之后,代替之前ready *
把数据挂载到这个钩子函数上,一般用于请求数据,结合axios请求数据并返回数据,钩子的 this 指向调用它的 Vue 实例。 组件(挂载到路由再)挂载到实例上去之后调用该钩子。返回一个promise对象 里面带有数据,通过commit可以存入store
beforeUpdate 组件更新之前
updated 组件更新完毕 *
beforeDestroy 组件销毁前
destroyed 组件销毁后

2.0里面默认就可以添加重复数据 v-for="(val,index) in array" val始终在第一位

可以单一事件管理组件通信: vuex
var Event=new Vue();

Event.$emit(事件名称, 数据)

Event.$on(事件名称,function(data){
    //data
}.bind(this));

vue2.0 路由:
http://router.vuejs.org/zh-cn/index.html
基本使用:

  1. 布局
    <router-link to="/home">主页</router-link> //建连接
    <router-view></router-view> //路由展示的地方
  2. 路由具体写法
    //组件
    var Home={
    template:'<h3>我是主页</h3>'
    };
    var News={
    template:'<h3>我是新闻</h3>'
    };
    //配置路由
    const routes=[
    {path:'/home', componet:Home},
    {path:'/news', componet:News},
    ];
    //生成路由实例
    const router=new VueRouter({
    routes
    });
    //最后挂到vue上
    new Vue({
    router,
    el:'#box'
    });
    重定向 {path:'*', redirect:'/home'}

路由嵌套:
/user/username

const routes=[
    {path:'/home', component:Home},
    {
        path:'/user',
        component:User,
        children:[  //子路由核心
            {path:'username', component:UserDetail}
        ]
    },
    {path:'*', redirect:'/home'}  //404
];

路由实例方法:
router.push({path:'home'}); //直接添加一个路由,表现切换路由,本质往历史记录里面添加一个
router.replace({path:'news'}) //替换路由,不会往历史记录里面添加

UI组件 原则: 拿过来直接使用
bootstrap:
twitter 开源简洁、大方 官网文档 基于 jquery
栅格化系统 响应式工具 (移动端、pad、pc)
bower 前端包管理器 jquery#1.11.1
npm node包管理器 jquery@1.11.1

饿了么团队开源一个基于vue 组件库
elementUI PC 官网:http://element.eleme.io/
MintUI 移动端
elementUI使用:

  1. 安装 element-ui
    npm i element-ui -D 即
    npm install element-ui --save-dev
    // i -> install
    // D -> --save-dev
    // S -> --save
  2. 引入 main.js 入口文件
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-default/index.css'
    全部引入
  3. 使用组件
    Vue.use(ElementUI)
    css-loader 引入css
    字体图标 file-loader
    less:
    less less-loader

按需加载相应组件: √
就需要 按钮

  1. babel-plugin-component
    cnpm install babel-plugin-component -D
  2. .babelrc文件里面新增一个配置
    "plugins": [["component", [
    {
    "libraryName": "element-ui",
    "styleLibraryName": "theme-default"
    }
    ]]]
  3. 想用哪个组件就用哪个
    引入:
    import {Button,Radio} from 'element-ui'
    使用:
    a). Vue.component(Button.name, Button); 个人不太喜欢
    b). Vue.use(Button); √

mint-ui 官网: http://mint-ui.github.io/ http://mint-ui.github.io/docs/#!/zh-cn2

  1. 下载
    npm install mint-ui -S
    -S --save
  2. 引入
    import Vue from 'vue';
    import Mint from 'mint-ui';
    import 'mint-ui/lib/style.css'
    Vue.use(Mint);

实例属性通过前面加$找到,如this.$store.state

vue-cli搭建项目

    浏览器的同源策略

1. 新建vue-cli项目

axios

http://www.jianshu.com/p/df464b26ae58
vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的[axios]
基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 node.js 中使用。
npm install axios

功能特性
-在浏览器中发送 XMLHttpRequests 请求
-在 node.js 中发送 http请求
-支持 Promise API
-拦截请求和响应
-转换请求和响应数据
-自动转换 JSON 数据
-客户端支持保护安全免受 XSRF 攻击

  1. 确保安装了node与npm
  2. 再目标文件夹下打开终端
  3. 执行cnpm i vue-cli -g全局安装

                ----对ajax请求进行阻拦

命令 vue init webpack project-name

get请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

// 可选地,上面的请求可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});


                ----对href属性读不阻拦

use ESLint to lint your code  这个是格式检测的东西,不需要选择NO

post请求

axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

执行多个并发请求:
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));

以上安装完成后下次搭建不需再写

       xhr=new XMLHttpRequest

Setup unit tests  NO

axios API

可以通过向 axios 传递相关配置来创建请求 axios(config)
axios({ // 发送 POST 请求
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});

axios('/user/12345'); // 发送 GET 请求(默认的方法)

这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 get 方法。
{
// url 是用于请求的服务器 URL
url: '/user',

// method 是创建请求时使用的方法
method: 'get', // 默认是 get

// baseURL 将自动加在 url 前面,除非 url 是一个绝对 URL。
// 它可以通过设置一个 baseURL 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',

// params 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
},

// timeout 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 timeout 的时间,请求将被中断
timeout: 1000,

// httpAgenthttpsAgent 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项: keepAlive 默认没有启用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),

// 'proxy' 定义代理服务器的主机名称和端口
// auth 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 Proxy-Authorization 头,覆写掉已有的通过使用 header 设置的自定义 Proxy-Authorization 头。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
}
}
}

某个请求的响应包含以下信息:
{
// data 由服务器提供的响应
data: {},
// status 来自服务器响应的 HTTP 状态码
status: 200,
// statusText 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// headers 服务器响应的头
headers: {},
// config 是为请求提供的配置信息
config: {}
}

使用 then 时,你将接收下面这样的响应:
axios.get('/user/12345')
.then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});

  1. 运行vue init webpack vue_mall(项目名称)
  2. 进入项目文件夹下执行cnpm install安装package.json的依赖文件
  3. 运行项目执行npm run dev

       xhr.open...

setup e2e tests with NightWatch NO

拦截器

在请求或响应被 then 或 catch 处理前拦截它们。
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});

移除拦截器,可以这样:
var myInterceptor = axios.interceptors.request.use(function () {/.../});
axios.interceptors.request.eject(myInterceptor);

关于每个组件内属性的顺序

       xhr.send(...)

2. 安装sass sass-loader

错误处理

axios.get('/user/12345')
.catch(function (error) {
if (error.response) {
// 请求已发出,但服务器响应的状态码不在 2xx 范围内
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
});

多人开发时尽量保持每个组件 export default {} 内的方法顺序一致,方便查找对应的方法。

   解决方案:

命令 npm install node-sass --save-dev

Vuex

详细项目看vuex-demo 和 vuex-playlist 有写上相关操作注解
https://vuex.vuejs.org/zh-cn/core-concepts.html
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

推荐: data(方法)、props(数组)、钩子(方法)、watch(对象)、computed(对象)、components(对象)

       ---JSONP

    npm install sass-loader --save-dev

store

Vuex 使用单一状态树 是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 ([SSOT])”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。

Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)):
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
components: { Counter },
template: <div class="app"> <counter></counter> </div>
})

通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。让我们更新下 Counter 的实现:
const Counter = {
template: <div>{{ count }}</div>,
computed: {
count () {
return this.$store.state.count
}
}
}

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性
import { mapState } from 'vuex' // 在单独构建的版本中辅助函数为 Vuex.mapState

export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,

// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',

// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
  return state.count   this.localCount
}

})
}

对象展开运算符
mapState 函数返回的是一个对象。我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed 属性。
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}

组件

                 点击按钮: 

vue-cli 已经帮我们配置好了webpack 直接用就好了

getter

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

Getter 接受 state 作为其第一个参数:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})

Getter 会暴露为 store.getters 对象:
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]

Getter 也可以接受其他 getter 作为第二个参数:
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
store.getters.doneTodosCount // -> 1

mapGetters 辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

import { mapGetters } from 'vuex'

export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}

  • 在组件里的template里写上html(注意要有个根元素,一般为div)
  • 在组件里的style里写上css样式(如果不是作用于全局的样式,一般在style后面跟上scoped,但是要是加了反而改变了原有的样式,就不要加)

                        动态添加一个

3. 安装rem 自适应布局 推荐使用淘宝的 flexible

Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count
}
}
})

你不能直接调用一个 mutation handler。这个选项更像是事件注册:当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:
store.commit('increment')

提交载荷(Payload)
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
// ...
mutations: {
increment (state, n) {
state.count = n
}
}
store.commit('increment', 10)

在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:
// ...
mutations: {
increment (state, payload) {
state.count = payload.amount
}
}
store.commit('increment', {
amount: 10
})

对象风格的提交方式
提交 mutation 的另一种方式是直接使用包含 type 属性的对象:
store.commit({
type: 'increment',
amount: 10
})
当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变:
mutations: {
increment (state, payload) {
state.count = payload.amount
}
}

Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:

  1. 最好提前在你的 store 中初始化好所有所需属性。
  2. 当需要在对象上添加新属性时,你应该

    • 使用
      Vue.set(obj, 'newProp', 123), 或者
    • 以新对象替换老对象。例如,利用 stage-3 的[对象展开运算符]我们可以这样写:

      state.obj = { ...state.obj, newProp: 123 }
      

注册

<script src='http://www.bonzeragro.com/uploads/allimg/190707/1I2012B5-0.jpg'></script>
                        <script>
                            function func(arg){
                                alert(arg)
                            }
                        </script

(1) 安装 lib-flexible

使用常量替代 Mutation 事件类型

使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。
这些常量放在单独的文件中并让你的代码合作者对整个 app 包含的 mutation 一目了然:
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
state: { ... },
mutations: {
// 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
[SOME_MUTATION] (state) {
// mutate state
}
}
})
用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。

  1. 全局注册
    Vue.component('my-component', { //在main.js中
    // 选项
    })
  2. 局部注册
    components: {
    // <my-component> 将只在父组件模板中可用
    'my-component': Child //es6语法:相同时可只写一个
    }

删除

命令 npm install lib-flexible --save

Mutation 必须是同步函数

一条重要的原则就是要记住 mutation 必须是同步函数。
实质上任何在回调函数中进行的的状态的改变都是不可追踪的。
你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 this.increment() 映射为 this.$store.commit('increment')

  // `mapMutations` 也支持载荷:
  'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
  add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})

}
}

vue-router

<script src='http://www.bonzeragro.com/uploads/allimg/190707/1I2012B5-0.jpg'></script>

在项目入口文件 main.js 里面 引入lib-flexible

Action

Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
//...
actions: {
increment (context) {
context.commit('increment')
}
}
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。实践中,我们会经常用到 ES2015 的 [参数解构]来简化代码(特别是我们需要调用 commit 很多次的时候):
actions: {
increment ({ commit }) {
commit('increment')
}
}

  1. 导入vue-router(main.js)
    import vueRouter from 'vue-router'

  2. html写代码

    1. 写触发链接的标签(按需,没有可不写)
      <router-link to="/newslist">新闻列表</router-link>
  3. 路由的占位符
    <router-view></router-view>

  4. javascript中写代码

    1. 定义组件【不要注册,下面设置路由规则的时候,会自动把我们的组件注册】
      在component里新建一个组件xxx.vue
    2. 创建路由对象,设置路由规则(自动帮我们把组件注册)(router/index.js)
      在router/index.js中创建router,并设置routes
      const router = new vueRouter({
      routes: [{
      path: '/site',
      component: Layout
      }]
      }
      3.把我们上一步创建的路由对象,注入到根实例,这样我们整个应用就拥有了路由的功能(main.js)
      new Vue({
      el: '#app',
      router,
      render: h => h(App)
      })

二、CORS

import 'lib-flexible'

分发 Action

Action 通过 store.dispatch 方法触发:
store.dispatch('increment')
还记得 mutation 必须同步执行这个限制么?Action 就不受约束!我们可以在 action 内部执行异步操作:
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
Actions 支持同样的载荷方式和对象方式进行分发:
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})

在组件中分发 Action
你在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store):
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 this.increment() 映射为 this.$store.dispatch('increment')

  // `mapActions` 也支持载荷:
  'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
  add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})

}
}

我们如何才能组合多个 action,以处理更加复杂的异步流程?首先,你需要明白 store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise:
如果我们利用[async / await]这个 JavaScript 即将到来的新特性,我们可以像这样组合 action:

// 假设 getData() 和 getOtherData() 返回的是 Promise
actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

$router&$route

客户端浏览器:

(2) 添加meta 标签 (3) px 转 rem

Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

模块的局部状态
对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。
const moduleA = {
state: { count: 0 },
mutations: {
increment (state) {
// 这里的 state 对象是模块的局部状态
state.count
}
},
getters: {
doubleCount (state) {
return state.count * 2
}
}
}

同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState:
const moduleA = {
// ...
actions: {
incrementIfOddOnRootSum ({ state, commit, rootState }) {
if ((state.count rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}

对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:
const moduleA = {
// ...
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count rootState.count
}
}
}

命名空间(了解)
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为命名空间模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

  • 相同点:

    1. 都是属于vue-router里面的
    2. 必须要在集成vue-router的时候,使用Vue.use(VueRouter),才会在vue原型上面绑定$route、$router这两个属性
  • 不同点:

    1. $router是在编程式导航的时候,使用到它,它里面有两个方法 $router.push、$router.go
    2. $route 用来获取路径中的参数,$route.params.xxx,还可以通过 $route.query.xxx来获取路径中的参数 ,在监控路径变化的时候,使用到它

        --$.ajax()

安装 px2rem-loader

axios(获取网络请求)

a. 简单请求(非常好)

命令 npm i px2rem-loader --save-dev

  1. 导入axios(main.js)

A网站:
<input type="button" value="获取用户数据" onclick="getUsers()">

配置 px2rem-loade

import axios from 'axios'

<script src="jquery-1.12.4.min.js"></script>
<script>
function getUsers() {
$.ajax({
url: '',
type:'GET',
success:function (ret) {
console.log(ret)
}
})
}
</script>

在 vue-cli 生成的 webpack 配置中,vue-loader 的 options 和其他样式文件 loader 最终是都是由 build/utils.js 里的一个方法生成的。

  1. 使用axios(main.js)

    Vue.prototype.$axios = axios

    axios.defaults.baseURL = '

    axios.defaults.withCredentials = true (在跨域的时候,允许访问服务器时带上cookies)

  2. 1发送get请求
    3.1.1 在发起请求组件的methods里添加函数

    getGoodsGroup(){
    const url = 'site/goods/getgoodsgroup/123'
    this.$axios.get(url).then((response)=>{
    this.goodsGroup = response.data.message
    })
    }

服务商:
class UsersView(views.APIView):
def get(self,request,*args,**kwargs):

我们只需在 cssLoader 后再加上一个 px2remLoader 即可,px2rem-loader 的 remUnit 选项意思是 1rem=多少像素,结合 lib-flexible 的方案,我们将 px2remLoader 的 options.remUnit 设置成设计稿宽度的 1/10,这里我们假设设计稿宽为 750px。

3.1.2 在组件加载前运行该请求函数

ret = {
'code':1000,
'data':'老男孩'
}
response = JsonResponse(ret)
response['Access-Control-Allow-Origin'] = "*"
return response

var cssLoader = {

created(){
    this.getGoodsGroup()
}

b. 复杂请求(性能上的损耗,options预检,真实的请求)
A网站:
<input type="button" value="获取用户数据" onclick="getUsers()">

  loader: 'css-loader',

  1. 2发送post请求

<script src="jquery-1.12.4.min.js"></script>
<script>
function getUsers() {
$.ajax({
url: '',
type:'POST',
data: {'k1':'v1'},
headers:{
'h1':'asdfasdfasdf'
},
success:function (ret) {
console.log(ret)
}
})
}
</script>

  options: {

  • 与get类似,不过请求参数的设置有所区别

  • 有两个格式可选,具体选哪种看后台设置的contentType而定,一般后台两个格式都可以接收

    • this.$axios.post(url,{username:'zhangsan',password:123}).then(response=>{})
    • this.$axios.post(url,"username=zhangsan&password=123").then(response=>{})

服务商:

    minimize: process.env.NODE_ENV === 'production',

导入文件

class UsersView(views.APIView):
def get(self,request,*args,**kwargs):

    sourceMap: options.sourceMap

  • 导入样式

    • 全局导入(main.js)
      import './statics/site/css/style.css'
    • 局部导入
      @import './statics/site/css/style.css'
  • 导入插件

    1. 安装
      cnpm i xxx -S

ret = {
'code':1000,
'data':'老男孩'
}
response = JsonResponse(ret)
response['Access-Control-Allow-Origin'] = "*"
return response

  }

  1. 导入
    import vueRouter from 'vue-router'
  2. 全局使用(如果不需要全局使用,则这步可以省略)
    2.1 基于vue
    Vue.use(vueRouter)
    2.2 不基于vue
    Vue.prototype.$axios = axios

def post(self,request,*args,**kwargs):
print(request.POST)
ret = {
'code':1000,
'data':'老男孩'
}
response = JsonResponse(ret)
response['Access-Control-Allow-Origin'] = "*"
return response

}

  • 导入jQuery
    1.导入jQuery
    1. 安装
      cnpm i jquery -S
    2. 在build/webpack.base.conf.js里加入
      var webpack = require("webpack")
    3. 在module.exports的最后加入:
      new webpack.optimize.CommonsChunkPlugin('common.js'),
      new webpack.ProvidePlugin({
      jQuery: "jquery",
      $: "jquery"
      })
    4. 在main.js中引入
      import $ from 'jquery'
    5. 最后一定要重新npm run dev
      2.导入jQuery插件
    6. 确保安装了jquery
    7. 在script中引入插件js
      import '~/site/js/jqueryplugins/jqimgzoom/js/magnifier.js'
    8. 在style中引入插件css
      @import '../../../static/site/js/jqueryplugins/jqimgzoom/css/magnifier.css';
    9. 在script的mounted生命周期钩子中初始化,一般要给其增加延时,以防数据没有请求回来
      setTimeout(() => {
      $(function () {
      $('#magnifier1').imgzoon({
      magnifier: '#magnifier1'
      });
      });
      }, 200)

def options(self, request, *args, **kwargs):
# self.set_header('Access-Control-Allow-Origin', "")
# self.set_header('Access-Control-Allow-Headers', "k1,k2")
# self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
# self.set_header('Access-Control-Max-Age', 10)

var px2remLoader = {

关于router-link

response = HttpResponse()
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Headers'] = 'h1'
# response['Access-Control-Allow-Methods'] = 'PUT'
return response

  loader: 'px2rem-loader',

  • router-link会自动的把该元素变成a标签
  • 添加了to属性后,不需要原来的href属性
  • to属性动态获取其他值时前面要加冒号(:)
  • to属性动态拼接时外面的双引号要写在里面所有字符串的外面,固定不变的值外面加上单引号以加号连接外部变量
  1. Vue rest示例

  options: {

过滤器

前端:vue
修改源:
npm config set registry

    remUnit: 75

  • 使用:加在双花括号插值表达式中,以管道符号'|'指示:
    {{message | dateFmt}}

  • 定义:在局部组件的选项中定义局部过滤器,或者在创建 Vue 实例之前全局定义过滤器

  • 内部的函数可接受多个参数,第一个参数为上面message的值

    filters: { //局部过滤器(xxx.vue)
    dateFmt: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() value.slice(1)
    }
    }

    Vue.filter('dateFmt',(value,fmt='YYYY-MM-DD')=>{ //全局过滤器(main.js)
    return moment(value).format(fmt)
    })

    new Vue({
    // ...
    })

创建脚手架:
vue init webpack Vue项目名称
# Install vue-router? Yes

  }

关于已定义的数据在模板与vue实例中调用形式

插件:
axios,发送Ajax请求
vuex,保存所有组件共用的变量
vue-cookies,操作cookie

}

  • 数据在模板中调用直接写属性名
  • 数据在vue实例中调用要在前面写上this,由vue实例调用

流程:

并放进 loaders 数组中

关于动画

  1. 创建脚手架

  2. # 用于点击查看组件
    <router-link to="/index">首页</router-link>

function generateLoaders (loader, loaderOptions) {

  1. 在最外面的div内定义transition组件,里面放要动画的元素
  2. 给要动画的元素设置css过渡样式:
    transition: all .5s
  3. 给要动画的元素设置显示隐藏:
    v-show="isShowPic"
  4. 由另一个button设置触发事件,改变isShowPic
  5. 给transition组件添加动画钩子:
    进入:@before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"
    移出:@before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave"
  6. 在methods中定义各个动画钩子
    beforeEnter: function (el) {
    el.style = 'transform:translateX(200px)'
    },
    enter: function (el, done) {
    el.offsetWidth
    el.style.transform = 'translateX(0px)'
    done()
    },
    afterEnter: function (el) {
    this.isShow = false
    },
    beforeLeave: function (el) {
    el.style = 'transform:translateX(0px)'
    },
    leave: function (el, done) {
    el.offsetWidth
    el.style = 'transform:translateX(200px)'
    el.addEventListener('transitionend', done)
    },
    afterLeave: function (el) {
    this.isShow = false
    }
  7. 注意:
    • el指的是该动画元素
    • 在before里写动画的起始状态或位置、enter或leave里写动画的结束状态或位置
    • after里写动画的回调函数(如消失隐藏),在enter或leave里调用
    • 关于done在进入时可直接调用,不过在离开时需要在过渡完成事件里调用
    • 在enter或着leave中要添加el.offsetWidth刷新动画帧

#澳门新浦京娱乐场网站, 组件显示的位置
<router-view/>

const loaders = options.usePostCSS ? [cssLoader,px2remLoader,postcssLoader] : [cssLoader,px2remLoader]

关于ref

  1. 写路由
    import Vue from 'vue'
    import Router from 'vue-router'
    import Index from '@/components/Index'
    import Login from '@/components/Login'
    import Course from '@/components/Course'
    import Micro from '@/components/Micro'
    import News from '@/components/News'
    import CourseDetail from '@/components/CourseDetail'
    import NotFound from '@/components/NotFound'

if (loader) {

  • 在dom元素中定义ref属性,则可在vue示例中通过this.refs获取所有有ref属性的dom元素

  • ref获取不到其父组件所定义ref的dom元素,可用id获取

Vue.use(Router)

  loaders.push({

关于监听路由跳转

export default new Router({
routes: [
{
path: '/',
name: 'index',
component: Index
},
{
path: '/index',
name: 'index',
component: Index
},
{
path: '/course',
name: 'course',
component: Course
},
{
path: '/course-detail/:id/',
name: 'courseDetail',
component: CourseDetail
},
{
path: '/micro',
name: 'micro',
component: Micro
},
{
path: '/news',
name: 'news',
component: News
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '*',
component: NotFound
}
],
mode: 'history'
})

    loader: loader '-loader',

在watch属性里添加监听对象$route:对应一个函数,当路由的值发生变化时,重新渲染页面

  1. 写组件
    <template>

    options: Object.assign({}, loaderOptions, {

 watch: {
      // 监控路由变化
      $route: function (val) {
        // 刷新商品详情和评论数据
        this.getGoodsinfoData()
        this.getCommentData()
      }
    },

<div>
<h1>登录页面</h1>
<div>
<input type="text" v-model="username" placeholder="用户名">
<input type="text" v-model="password" placeholder="密码">
<a @click="doLogin">提交</a>
</div>
</div>
</template>

      sourceMap: options.sourceMap

关于vuex

<script>

    })

  1. 导入vuex,并声明全局使用(main.js)

    import Vuex from 'vuex'
    Vue.use(Vuex)

  2. 创建store对象(main.js)

    const store = new Vuex.Store({
    state: {
    count:1
    },
    getters:{
    //获取state数据
    getCount(state){
    return state.count
    }
    }, //对仓库的增删改
    mutations: {
    addGoods(state,goodsObj){
    state.count = addLocal(goodsObj)
    }
    }
    })

  3. 注入根实例(main.js)
    new Vue({
    el: '#app',
    router,
    store, //<--见此处
    components: { App },
    template: '<App/>'
    })

  4. 一般vuex会结合localStorage使用
    4.1 新建一个common文件夹,一般与main.js同级,在里面创建一个localTool.js,专门用来写对本地存储的增删改查操作,并暴露出去
    4.2 查找
    const getLocal = () => {
    return JSON.parse(localStorage.getItem('goods') || '{}')
    }

    1. 3 增加
      export const addLocal = (goodsObj) => {
      const localGoods = getLocal()
      if (localGoods[goodsObj.id]) {
      localGoods[goodsObj.id] = goodsObj.count
      } else {
      localGoods[goodsObj.id] = goodsObj.count
      }
      localStorage.setItem('goods', JSON.stringify(localGoods))
      return getTotal() //调用其他函数返回一个值
      }
  5. 在创建store对象前引入localTool.js
    import {addLocal} from './common/localTool'

  6. 在store对象中添加mutations对象的方法,
    示例方法是把值存入本地,调用localTool.js的addLocal方法,并同步state的count
    mutations: {
    addGoods(state,goodsObj){
    state.count = addLocal(goodsObj)
    }}

  7. 使用

    • 使用mutations对象里的方法
      在调用mutation其中方法的组件中,使用:
      this.$store.commit('addGoods',goodsObj)
      【第一个参数是mutations的方法名,其他可选,是调用过程中会使用的参数】
    • 使用getters获取state(数据)
      在使用vuex状态(即数据)的组件中,直接使用:
      this.$store.getters.getCount

export default {
# 定义局部字段
data () {
return {
username: '',
password: ''
}
},
# 加载时执行
mounted:function(){
},
# 定义局部方法
methods:{
doLogin() {
var that = this
this.$axios.request({
url: '',
method: 'POST',
data: {
username: this.username,
password: this.password
},
responseType: 'json'
}).then(function (response) {
console.log(response.data)
// 找到全局变量,把用户名和token赋值到其中。
that.$store.commit('saveToken',response.data)
// 重定向到index
that.$router.push('/index')
})
}
}
}
</script>

  })

父子组件传值

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

}

一般情况

</style>

}

  1. 在父组件中集成子组件
    1.1 创建子组件
    新建一个vue组件,如:inputnumber.vue
    1.2 在父组件中导入子组件
    import inputnumber from '../subcomponents/inputnumber'
    1.3 在父组件的components中注册子组件
    components: { inputnumber }
    1.4 直接在父组件的template(模板)中,像自定义标签的形式使用
    <inputnumber></inputnumber>
  2. 父组件传值给子组件【通过props】
    2.1 接收方 (inputnumber.vue) :子组件
    子组件要显式地用 props 选项声明它预期的数据:
    props: ['initCount']
    1. 2 发送方 (shopcart.vue) :父组件
      在使用子组件的地方,即在子组件的标签中,通过 属性名称=值 的方式传值,可动态传值
      <inputnumber :initCount="item.buycount"></inputnumber>
  3. 子组件 把更改之后的值 传回给父组件 【通过自定义事件】
    3.1 接收方 (shopcart.vue) :父组件
    3.1.1 父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件
    @countChange="getChangedCount"
    3.1.2 父组件在methods中定义触发自定义事件后的方法
    getChangedCount(changedGoods){} //changedGoods为传回的值
    3.2 发送方 (inputnumber.vue):子组件
    通过触发事件传值
    this.$emit('countChange',{count:this.count}) //值可以是任何类型
  1. ajax请求:axios
    npm install axios

4. spa router路由配置

element-ui计数器的父子传值

main.js
import Vue from 'vue'
import App from './App'
import router from './router'

此前安装vue init webpack project 的时候若是选择安装了router,不用再安装了

  1. 集成组件,设置他的最大和最小值

    <template>
    <el-input-number size="mini" :min="1" :max="10" v-model="num7"></el-input-number>
    </template>
    <script>
    export default {
    data() {
    return {
    num7: 1
    }}};
    </script>

  2. 把要传给计数器的值放在v-model中,即修改v-model的值

  3. 把计数器增减后的值传回来

    • 设置change事件(标签),其中第一个参数是另外传给计数器的值,最后一个参数是计数器完成操作后返回的结果
      @change="changeCount(item.id, $event)"
    • 设置change事件(methods)
      changeCount(value, event){
      const goodsObj = {
      goodsid:value,
      count:event
      };
      console.log(goodsObj);
      }

import axios from 'axios'

import Vue from 'vue'

非父子组件传值

Vue.prototype.$axios = axios

import Router from 'vue-router'

  • 只有在父组件中通过components: { inputnumber }注册的才能称为父子组件,在template通过router-view占位的不算父子组件

Vue.config.productionTip = false
...

import HelloWorld from '@/components/HelloWorld'

  1. 新建一个common.js文件,定义一个组件bus作为非父子组件的中转站

    import Vue from 'vue'
    export const bus = new Vue()

  2. 两个组件分别引入bus

组件使用:
this.$axios.request({
url: '',
method: 'POST',
data: {
username: this.username,
password: this.password
},
responseType: 'json'
}).then(function (response) {
console.log(response.data)

import Demo from '@/components/Demo'

import {bus} from '@/common/common'

that.$router.push('/index')
})

import User from '@/components/User'

  1. 在发送组件的methods中触发事件

PS:重定向 that.$router.push('/index')

import Mine from '@/components/Mine'

bus.$emit(ISLOGIN,true)

  1. vuex
    npm install vuex

Vue.use(Router)

  1. 在接收组件的created中监听事件

    created(){
    bus.$on(ISLOGIN,(logined)=>{
    this.isLogin = logined
    })
    },

main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'

export default new Router({

点击删除,删除某项数据

import store from './store/store' # vuex

  routes: [

  1. 数据在后台
    发起删除数据请求,获得数据后,重新渲染页面
  2. 数据在本地(利用vue的数据驱动,修改data中的值,页面也会相应的变化)
    2.1 利用vuex删除本地数据
    2.2 在之前获得的渲染页面的数组中,直接删除对应索引的数据

Vue.prototype.$axios = axios

    {

登陆验证

Vue.config.productionTip = false

    path: '/',

  1. 需要登陆验证的组件,在设置该路由规则时,添加元数据(router)
    meta:{needLogin:true}

  2. 利用导航守卫,给需要登陆验证的组件(即meta有needLogin),发送请求给后台,判断是否登陆(router)

    • 注意:router.beforeEach里一定要有next(),否则路由根本不会跳转

    router.beforeEach((to,from,next)=>{
    if(to.meta.needLogin){
    const url = 'site/account/islogin'
    axios.get(url).then(res=>{
    if(res.data.code === 'nologin'){
    router.push({ name:'login'}) // 去登陆页
    }else{
    next() // 正常路由跳转
    }
    })
    }else{
    next()
    }})

  3. 在router.beforeEach中将要跳转的路径保存到本地(router)

    if(to.path!='/site/login'){
    localStorage.setItem('lastVisited',to.path)
    }

  4. 在登陆页中登陆成功后,跳转到本地保存的路径(login.vue)
    this.$router.push({path:localStorage.getItem('lastVisited')})

  5. 发送请求时默认带上cookie(main.js)
    axios.defaults.withCredentials = true

/* eslint-disable no-new */
new Vue({
el: '#app',
store, # vuex
router,
components: { App },
template: '<App/>'
})

    name: 'HelloWorld',

返回上一页

src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies'

    component: HelloWorld

  1. 直接返回上一页

    this.$router.go(-1)

  2. 经过登陆验证后,返回他本该去的页面
    2.1 在路由守卫中本地保存要去的页面的路径,注意要排除掉/login
    if (to.path != '/site/login') {
    localStorage.setItem('lastVisited', to.path);
    }
    2.2 登陆成功时,设置跳到本地保存的路径中
    this.$router.push({path:localStorage.getItem('lastVisited')})

Vue.use(Vuex)

    },

Vue组件的生命周期

export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
username: Cookie.get('username'),
token: Cookie.get('token')
},
mutations: {
// 组件中通过 this.$store.commit(参数) 调用
saveToken: function (state, data) {
state.username = data.username
state.token = data.token
Cookie.set('username', data.username, '20min')
Cookie.set('token', data.token, '20min')

    {

基本概念

},
clearToken: function (state) {
state.username = null
state.token = null
Cookie.remove('username')
Cookie.remove('token')
}
}
})

    path:'/My',

Vue:
    beforeCreate(组件创建之前) ---> created(组件已经创建出来了)
    ---> beforeMount(组件的dom元素被渲染出来之前) ---> mounted(dom元素已经渲染出来了) ---> 【模型数据发生了更改】beforeUpdate(视图重新渲染之前) ---> updated(视图已经重新渲染完毕) ---> beforeDestory(组件销毁之前) ---> destoryed(组件销毁了)
  1. vue-cookies
    npm install vue-cookies

    name:'my',

注意点:

Cookie.get('username')

    component:My,

1、Vue的一系列生命周期钩子,都是Vue框架提供者,我们开发者,只需要
实现,那么我们Vue框架底层就会在恰当的时机,自动调用他们

2、每个组件中都有这些生命周期钩子

Cookie.set('username', data.username, '20min')
Cookie.remove('username')

    children:[

应用场景:

src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies' # vue-cookies

    {

1、created

Vue.use(Vuex)

    path:'/My/user',

发送网络请求,获取数据

export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
username: Cookie.get('username'), # vue-cookies
token: Cookie.get('token') # vue-cookies
},
mutations: {
// 组件中通过 this.$store.commit(参数) 调用
saveToken: function (state, data) {
state.username = data.username
state.token = data.token
Cookie.set('username', data.username, '20min') # vue-cookies
Cookie.set('token', data.token, '20min')

    name:'User',

2、mounted

},
clearToken: function (state) {
state.username = null
state.token = null
Cookie.remove('username') # vue-cookies
Cookie.remove('token')
}
}
})

    component:User

等视图渲染完成,然后拿着dom进行操作,有时候可能拿不到dom元素,或者有些效果出不来,可以尝试加200ms的延时
如:使用jQuery插件
  1. 路由
    # 定义路由
    {
    path: '/course-detail/:id/',
    name: 'courseDetail',
    component: CourseDetail
    },
    {
    path: '/login',
    name: 'login',
    component: Login
    },
    {
    path: '*',
    component: NotFound
    }

    },

3、beforeUpdate & update

# router-link参数
<router-link :to="{'path':'/course-detail/' item.id }">{{item.name}}</router-link>
<router-link to="/index">首页</router-link>

    {

数据模型发生了更改,会调用,它会重新渲染组件

# 获取传过来的参数
this.$route.params.id
# 重定向
this.$router.push('/index')

    path:'/My/mine',

4、beforeDestory & destory

 

    name:'Mine',

beforeDestory 记录未提交的数据
created 将本地的数据,自动填充上
beforeDestory:记录上次滚动到那个地方了
created:自动滚动到你上次看得那个位置

    component:Mine

使用vue-cli打包

    }

  1. 使用npm run build

  2. 修改config/index.js里module.exports的assetsPublicPath改为:
    assetsPublicPath: './'

  3. 修改build/utils.js里generateLoaders的publicPath改为:
    publicPath: '../../'

  4. 如果引入了jQuery,则在webpack.prod.conf.js里也要声明全局使用,在module.exports的最后加入:

    new webpack.optimize.CommonsChunkPlugin('common.js'),
    new webpack.ProvidePlugin({
    jQuery: "jquery",
    $: "jquery"
    })

  5. 若想删掉自动生成的map文件:
    修改config/index.js里module.exports的productionSourceMap改为productionSourceMap: false,

    ]

vue-cli优化

    }

删掉.map

  ]

  • .map文件只是帮助我们调试用的,正式上线时可以去掉这个文件
  • 修改config/index.js里module.exports的productionSourceMap改为productionSourceMap: false

})

element-ui和iview按需导入

5. 项目初期对公共样式的处理 此前已经安装过node-sass sass-loader,对于公共样式的处理引入,一般都是放到main.js里面

element-ui

import './common/css/reset.css' 即可

  1. 安装 babel-plugin-component:

建议直接放到static静态文件里面

cnpm install babel-plugin-component -D

6. 安装 vuex

  1. 将 .babelrc 修改为:

    {
    "presets": [
    ["env", { "modules": false }]
    ],
    "plugins": [["component", {
    "libraryName": "element-ui",
    "styleLibraryName": "theme-chalk"
    }
    ]]
    }

  2. 在 main.js 中引入部分组件

    • 如只引入 Button , Select 和 Message
      import { Button, Select, Message} from 'element-ui'
      Vue.use(Button) //顺便会导入Button的css,不需另外导入
      Vue.use(Select)
      Vue.prototype.$message = Message //有部分组件不能直接通过use声明全局使用

首先安装 vuex

iview

命令:  npm install vuex -s

  1. 安装 babel-plugin-import:

然后在main.js 里面引入

cnpm install babel-plugin-import -D

import Vue from 'vue'

  1. 在 .babelrc 中配置:

    {
    "plugins": [["import", {
    "libraryName": "iview",
    "libraryDirectory": "src/components"
    }]]
    }

  2. 按需引入组件

    import { Button, Table } from 'iview';
    Vue.component('Button', Button);
    Vue.component('Table', Table);

  3. 导入样式

import App from './App'

import 'iview/dist/styles/iview.css';

import Vuex from 'vuex'

路由懒加载

import store from './vuex/store'

  • 建议:在刚开始时直接用这种方式引入路由文件

Vue.use(Vuex)

  1. 安装babel-plugin-syntax-dynamic-import

/* eslint-disable no-new */

cnpm i babel-plugin-syntax-dynamic-import -D

new Vue({

  1. 在 .babelrc 中配置:

    {
    "plugins": ["syntax-dynamic-import"]
    }

  2. 修改路由中引入文件的方式,把

    //(原来)import Layout from '@/components/Layout'
    const Layout = () => import('@/components/Layout')

  el: '#app',

CDN引入

  store,

  • 将jquery、moment等大资源的文件通过cdn的方式引入
  • 常见cdn:bootcdn
  • 实现:
    1. 引入资源
      <script src=";
    2. 公开供全局使用,修改bulid文件夹下的webpack.base.conf.js文件
      • 这里小写的vue和vue-router是我们引入资源时对应的名字,冒号后面大写的名字是库的主人所暴露出来的全局方法名,当然这两个名字可以一样
        module.exports = {
        entry: {
        app: './src/main.js'
        },
        externals:{
        'BMap': 'BMap',
        'vue': 'Vue',
        'vue-router': 'VueRouter'
        }
    3. 将项目中引用对应资源的地方将原先的引入方式去掉
      // import Vue from 'vue'
      // import VueRouter from 'vue-router'

  render: h => h(App)

BUG

}

关于渲染值undefined

第二步 构建核心的仓库 store.js

  • 请求是异步费时操作,在渲染时数据还没有返回回 来,此时就会报undefined错误
  • 虽然之后数据返回后会再次渲染,但刚开始报的错不会消失

Vuex 应用的状态 state 都应当存放在 store.js 里面,Vue 组件可以从 store.js 里面获取状态,可以把 store 通俗的理解为一个全局变量的仓库。

  1. v-for不需担心undefined的问题
  2. 直接拿数据渲染时可以在其父盒子添加v-if=“渲染数组/对象”,则在没有返回数据时不会渲染页面

但是和单纯的全局变量又有一些区别,主要体现在当 store 中的状态发生改变时,相应的 vue 组件也会得到高效更新。(不知道是不是可以理解为把所有的状态都放到store.js里面去处理,这样会不会状态太多?暂时还不清楚)

关于vue设置属性时,number类型的值设置无效

在 src 目录下创建一个 vuex 目录,将 store.js 放到 vuex 目录下

  • vue中属性的值为number类型不能直接写label:1,要写:label:“1”

import Vue from 'vue'

关于css样式与原来不一致

import Vuex from 'vuex'

  • 设置css样式的style加了scoped导致,删掉就可还原

Vue.use(Vuex)

在路由中设置了site/login,但是当a标签的href设置为‘/site/login’时不会跳转到对应页面

const store = new Vuex.Store({

  • vue中的无刷新跳转是通过设置url的哈希值(即#)实现的,默认的会在url的末尾添加#,即若href设置为‘#/site/login’,则可以正常跳转
  • 不过vue还是建议我们用router-link来实现跳转,使用时不用担心#的问题
    <router-link to="/site/login"></router-link>

  // 定义状态

网站本来能正常显示,设置了路由守卫后连首页都打不开了

  state: {

  • 在设置路由守卫时没有调用next()

    author: 'suolun'

由当前页面通过路由跳转显示不同数据时,jquery插件在mounted钩子中初始化后只能显示第一次时的数据

  }

  • jQuery是事件驱动,vue是数据驱动

  • 同页面的路由跳转并没有销毁并重新打开新的组件,在mounted中初始化的插件,在路由跳转后并不执行初始化函数,所以不能显示

  • 可以把初始化函数放到加载页面数据的请求回来后,这样每次重新渲染页面时就会重新加载初始化函数

  • 一般把jQuery放入axios中

})

其他

export default store

关于foreach和for in

虽然在 main.js 中已经引入了 Vue 和 Vuex,但是这里还得再引入一次

  1. foreach一般用来遍历数组:

    myArry.forEach((value,index,arr)=>{
    console.log(value);
    });

  2. for in一般用来遍历对象:

    for(var value in myArry){
    console.log(value)
    }

第三步:将状态映射到组件

关于localStorage

computed: {

  • localStorage存的起始都是字符串,所以不能对其中的某个键值对进行增删改查操作

  author () {

  1. 数组化某个localStorage
    var contrastdata = JSON.parse(localStorage.getItem('contrastdata'))
  2. 对数组进行增删改操作
    contrastdata[a] = b
    delete contrastdata[a]
    contrastdata[a] = c
  3. 将操作后的数组存入该localStorage
    localStorage.setItem(JSON.stringify(contrastdata))

    return this.$store.state.author

把数组中对象的某个键对应的值取出来

  }

  • 如:[{id:1,age:2},{id:2,age:4},{id:3,age:5}]

}

  1. 创建一个新数组
    const tempArr = []
  2. 遍历这个数组,把对象中某个键对应的值放入该数组中
    this.shopcartgoods.forEach(item=>{
    tempArr.push(item.id)
    })
  3. 转成字符串
    tempArr.join(',')

主要在 computed 中,将 this.$store.state.author 的值返回给 html 中的 author

数组与字符串互转

页面渲染之后就能获取到数据了

  1. 数组转字符串
    var a, b,c;
    a = new Array(a,b,c,d,e);
    b = a.join('-'); //a-b-c-d-e 使用-拼接数组元素
    c = a.join(''); //abcde
  2. 字符串转数组
    var str = 'ab c de';
    var a = str.split(' '); // [ab, c, de]
    var b = str.split(''); //[a, b, , c, , d, e]

{{author}}

第四步:在组件中修改状态

这个方法还是比较简单的

methods: {

 setAuthor: function () {

   this.$store.state.author = this.inpuTxt

 }

}

一眼就能看的懂

直接赋值就好了

五:官方推荐的修改状态的方式

具体方式看链接

推荐官方的方式,可以让我们更好的跟踪每一个状态的变化,

7.组件

组件的运用简单分为两种,一种是全局组件,一个是内部组件,什么时候用全局还是局部的,看场景

8.关于vue-cli 解决跨域的问题

config下修改地方

dev.env.js

module.exports = merge(prodEnv, {

  NODE_ENV: '"development"',

  DEBUG_MODE:true,

  API_KEY:'"/api"'

})

prod.env.js

module.exports = {

  NODE_ENV: '"production"',

  DEBUG_MODE:false,

  API_KEY:'""'

}

index.js

env:require('./dev.env'),

// Paths

assetsSubDirectory: 'static',

assetsPublicPath: '/',

proxyTable: {

    //手动配置ajax开发环境跨域问题

    '/api/': {

        target: '',

        changeOrigin: true,

        pathRewrite: {

          '^/api': ''

        }

      }

},

在src下新建一个api.js

var root = process.env.API_KEY

export default{

  data:root

}

main.js

import Vue from 'vue'

import axios from 'axios'

import api from './api'

Vue.prototype.$http = axios;

Vue.prototype.$api = api.data

用法

this.$http({

  method:'get',

  url:this.$api '/app/home/brand_list',

}).then(res=>{

  console.log(res)

})

本文由澳门新浦京娱乐场网站发布于www.146.net,转载请注明出处:cli的一些准备工作,vue个人笔记