项目八遇到的知识点
一、cli3.0引入Mint UI
1、安装
- 官网地址:
- npm i mint-ui -S
2、使用当中遇到的问题
- 公司要做一个手机端页面当时想到vux,项目中用到cli3.0,当我引入vux的时候报了错
npm install @types/vux` if it exists or add a new declaration (.d.ts) file containing `declare module 'vux';
- 搞了好久都没解决,最后用了mint-ui,还是报类似vux的错,最后终于解决了。。。
main.ts中写
import Mint from "mint-ui";
Vue.use(Mint);
import 'mint-ui/lib/style.css'
- 这样写就会报错,解决方法如下
- 在项目src下建.d.ts文件
- shims-mint名字随便起
shims-mint.d.ts
declare module "mint-ui" {
const Mint: any;
export const Toast: any;
export const MessageBox: any;
export default Mint;
}
- 这样就可以在页面中引用ui组件,toast和messageBox需要重新引用
import { Toast, MessageBox } from "mint-ui";
3、Popup + Picker结合使用实现弹窗功能
页面
<template>
<div class="base-info">
<div class="info-item space-between">
<p class="f15">其他出行方式</p>
<div class="info-right">
<div
@click="handleTripMode"
class="info-box"
>
<input
type="text"
class="f15"
v-model="tripMode"
disabled
placeholder="请选择"
>
</div>
<img
src="../../assets/right.svg"
@click="handleTripMode"
>
<mt-popup
style="width: 100%;height: 5.84rem;"
popup-transition="popup-fade"
closeOnClickModal="true"
v-model="popupVisible"
position="bottom"
class="mint-popup"
>
<mt-picker
:slots="dataList"
:visible-item-count="5"
:show-toolbar="true"
defaultIndex
ref="VisitType"
value-key="Name"
>
<mt-button
@click="handleCancel"
class="sure"
>取消</mt-button>
<mt-button
@click="handleConfirm"
class="sure"
>确认</mt-button>
</mt-picker>
</mt-popup>
</div>
</div>
</div>
</template>
js
<script lang="ts">
import { Component, Vue, Emit } from "vue-property-decorator";
@Component({})
export default class TripMode extends Vue {
$refs: {
VisitType: any;
};
popupVisible = false;
// 其他出行方式
dataList = [];
tripMode = "";
created() {
this.InitLoad();
}
InitLoad() {
this.dataList = [
{
values: ["其他", "打车", "步行"]
}
];
}
handleTripMode() {
this.popupVisible = true;
}
handleCancel() {
this.popupVisible = false;
}
handleConfirm() {
this.tripMode = this.$refs.VisitType.getValues()[0];
this.popupVisible = false;
}
}
</script>
如果Picker选择的是对象
InitLoad() {
let list = [
{
id: 1,
Name: "其他"
},
{
id: 2,
Name: "打车"
},
{
id: 3,
Name: "步行"
}
];
this.dataList = [
{
values: list
}
];
}
handleConfirm() {
this.tripMode = this.$refs.VisitType.getValues()[0].Name;
this.popupVisible = false;
}
- 知识点
1.getValues():获取所有 slot 目前被选中的值
2.value-key 属性来指定显示的字段名
4、点击增加/删除列表
<template>
<div class="add-info">
<div
v-for="(base,index) in objList"
:key="index"
>
<div class="add-item space-between">
<p class="f15">姓名</p>
<input
type="text"
v-model="base.name"
placeholder="请输入姓名"
>
</div>
<div class="add-item space-between">
<p class="f15">性别</p>
<input
type="text"
v-model="base.sex"
placeholder="请输入性别"
>
</div>
<div class="add-item space-between">
<p class="f15">年龄</p>
<input
type="text"
v-model="base.age"
placeholder="请输入年龄"
>
</div>
</div>
<div class="add-flex">
<div @click="add">
<img src="../../assets/add.svg">
<p>增加</p>
</div>
<div @click="detele">
<img src="../../assets/de.svg">
<p>删除</p>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Emit } from "vue-property-decorator";
@Component({})
export default class TripMode extends Vue {
objList = [
{
name: "", // 姓名
sex: "", // 性别
age: "" // 年龄
}
];
add() {
let newObj = {
name: "",
sex: "",
age: ""
};
this.objList.push(newObj);
console.log(this.objList);
}
detele() {
let tmpLength = this.objList.length;
if (tmpLength !== 1) {
this.objList.splice(tmpLength - 1, 1);
}
}
}
</script>
<style lang="less">
.add-info {
.add-item {
height: 45px;
line-height: 45px;
padding: 0 20px;
border-bottom: 1px solid #d9d9d9;
}
.add-flex {
display: flex;
div {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
img {
width: 24px;
}
p {
display: inline-block;
margin-left: 20px;
font-size: 14px;
}
}
}
}
</style>
5、获取地址栏参数
方法1
-
在地址栏获取code的参数
UrlSearch(name) { let [returnVal, index, queryArr] = [ "", window.location.hash.indexOf("?"), [] ]; if (index >= 0) { queryArr = window.location.hash.substring(index).split("&"); for (let i = 0; i < queryArr.length; i++) { const element = queryArr[i]; if (element.indexOf("=") >= 0) { returnVal = element.split("=")[1]; break; } } return returnVal; } } // 调用 this.UrlSearch("code")
方法2
each(array, fn) {
for (var i in array) {
fn(i, array[i]);
}
}
// 获取地址栏参数
getHrefData() {
var href = window.location.href;
var paramStr = href.substring(href.indexOf("?") + 1);
var paramArray = paramStr.split("&");
var reVal = {};
this.each(paramArray, function(index, item) {
var tmp = paramArray[index].split("=");
reVal[tmp[0]] = decodeURI(tmp[1]);
});
return reVal;
}
// 调用
const data = this.getHrefData();
const code = data.code; // 获取code
6、钉钉免登
-
获取微应用免登授权码
dd.ready(function() { dd.runtime.permission.requestAuthCode({ corpId: _config.corpId, // 企业id onSuccess: function (info) { const code = info.code // 通过该免登授权码可以获取用户身份 }}); });
-
在哪里调用就写在哪里,可以封装到方法中
-
获取code 一般后端会有个接口,通过code登录
7、钉钉扫码登录
通过免登授权码换取用户身份
- 我项目中用到的是第三方企业应用免登服务端接口文档
正在在项目的使用
(1)、创建扫码登录应用授权
- 进入【钉钉开发者平台-应用开发-移动接入应用-登录-创建扫码登录应用授权】,创建扫码登录应用授权
- 完成之后我们就可以拿到appId和appSecret了
(2)、构造扫码登录页面
1.第一种方式是直接使用钉钉提供的扫码登录页面
https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI
2.第二种方式是支持网站将钉钉登录二维码内嵌到自己的页面中
步骤1:在页面中先引入如下js文件
步骤2: 在需要使用钉钉登录的地方使用以下js对象
/*
* 解释一下goto参数,参考以下例子:
* var url = encodeURIComponent('http://localhost.me/index.php?test=1&aa=2');
* var goto = encodeURIComponent('https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=appid&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+url)
*/
var obj = DDLogin({
id:"login_container",//这里需要你在自己的页面定义一个HTML标签并设置id,例如<div id="login_container"></div>或<span id="login_container"></span>
goto: "", //请参考注释里的方式
style: "border:none;background-color:#FFFFFF;",
width : "365",
height: "400"
});
-
这段代码的意思就是在你id定义的DOM中生成二维码,扫码成功之后会给你当前页面(/login)返回一个临时授权码,通过如下代码接收临时授权码,然后构造需要跳转的地址(/home)带上临时授权码。
var hanndleMessage = function(event) { var origin = event.origin; console.log("origin", event.origin); if (origin == "https://login.dingtalk.com") { //判断是否来自ddLogin扫码事件。 var loginTmpCode = event.data; //拿到loginTmpCode后就可以在这里构造跳转链接进行跳转了 window.location.href = "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=你的&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=http://localhost:8080/home&loginTmpCode=" + loginTmpCode; } }; if (typeof window.addEventListener != "undefined") { window.addEventListener("message", hanndleMessage, false); } else if (typeof window.attachEvent != "undefined") { window.attachEvent("onmessage", hanndleMessage); }
3.实例
最外层的index.html
<script src="http://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
DingTalk.vue
<template>
<div class="ding-talk tac">
<p class="title">钉钉登录</p>
<div id="login_container"></div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Emit, Prop, Model } from "vue-property-decorator";
@Component
export default class DingTalk extends Vue {
created() {
document.title = "钉钉扫码登录";
this.InitLoad();
}
getDDLogin(){
let url = encodeURIComponent("http://localhost:8080/#/DingTalk");
let goto = encodeURIComponent("https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" + 你的appId+"&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" + url);
let obj = DDLogin({
id: "login_container",
goto: goto,
style: "border:none;background-color:#FFFFFF;",
width: "365",
height: "400"
});
let hanndleMessage = function(event) {
let origin = event.origin;
if (origin == "https://login.dingtalk.com") {
//判断是否来自ddLogin扫码事件。
let loginTmpCode = event.data; //拿到loginTmpCode后就可以在这里构造跳转链接进行跳转了
let url2 = "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=" + 你的appId + "&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" +url +"&loginTmpCode=" + loginTmpCode;
// 跳转成功后url参数中追加临时授权码code及state两个参数。
window.location.href = url2;
}
};
if (typeof window.addEventListener != "undefined") {
window.addEventListener("message", hanndleMessage, false);
} else if (typeof window.attachEvent != "undefined") {
window.attachEvent("onmessage", hanndleMessage);
}
}
InitLoad(){
const data = this.getHrefData();
const code = data.code; // code 是地址栏中
if(code){
// 如果有code表示扫码成功
// 接口数据
}
}
each(array, fn) {
for (var i in array) {
fn(i, array[i]);
}
}
// 获取地址栏参数
getHrefData() {
var href = window.location.href;
var paramStr = href.substring(href.indexOf("?") + 1);
var paramArray = paramStr.split("&");
var reVal = {};
this.each(paramArray, function(index, item) {
var tmp = paramArray[index].split("=");
reVal[tmp[0]] = decodeURI(tmp[1]);
});
return reVal;
}
}
</script>
<style lang="less">
.ding-talk {
width: 100%;
height: 100%;
background-color: rgb(51, 51, 51);
padding: 50px;
.title {
font-size: 20px;
color: #fff;
margin-bottom: 10px;
}
}
</style>
8、微信公众号授权登录
<script lang="ts">
import { Component, Vue, Emit } from "vue-property-decorator";
@Component
export default class WechatList extends Vue {
created() {
this.initData();
}
initData() {
const data = this.getHrefData();
const code = data.code; // 获取到的地址栏中的code
// 判断是否登录
if( code ){
// 获取code
}else {
let weixinUrl = "";
let jumpUrl = encodeURIComponent('跳转的地址');
weixinUrl ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + 公众号的appid + "&redirect_uri=" + jumpUrl +"&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
window.location.href = weixinUrl;
}
}
each(array, fn) {
for (var i in array) {
fn(i, array[i]);
}
}
// 获取地址栏参数
getHrefData() {
var href = window.location.href;
var paramStr = href.substring(href.indexOf("?") + 1);
var paramArray = paramStr.split("&");
var reVal = {};
this.each(paramArray, function(index, item) {
var tmp = paramArray[index].split("=");
reVal[tmp[0]] = decodeURI(tmp[1]);
});
return reVal;
}
}
</script>